Skip to content

Commit 827ca14

Browse files
committed
Refactor design principles
1 parent d2a09fb commit 827ca14

3 files changed

Lines changed: 165 additions & 54 deletions

File tree

DesignPrinciple/CMakeLists.txt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,14 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
77

88
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
99

10-
add_executable(composition_over_inheritance "composition_over_inheritance.cpp")
11-
add_executable(interface_segregation "interface_segregation.cpp")
10+
add_executable(code_to_interface
11+
code_to_interface_logger.cpp
12+
)
13+
14+
add_executable(composition_over_inheritance
15+
composition_over_inheritance.cpp
16+
)
17+
18+
add_executable(interface_segregation
19+
interface_segregation.cpp
20+
)
Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,102 @@
1+
#include <chrono>
2+
#include <iomanip>
13
#include <iostream>
24
#include <memory>
5+
#include <sstream>
36
#include <string>
7+
#include <vector>
48

5-
class ILogger {
9+
inline std::string current_time_string() {
10+
// using namespace std::chrono;
11+
12+
const std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
13+
14+
const std::time_t time = std::chrono::system_clock::to_time_t(now);
15+
16+
std::ostringstream oss;
17+
oss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S");
18+
return oss.str();
19+
}
20+
21+
enum class log_level_t { info, warning, error };
22+
23+
inline std::string to_string(log_level_t level) {
24+
switch (level) {
25+
case log_level_t::info:
26+
return "INFO";
27+
case log_level_t::warning:
28+
return "WARNING";
29+
case log_level_t::error:
30+
return "ERROR";
31+
}
32+
return "UNKNOWN";
33+
}
34+
35+
class logger_t {
636
public:
7-
virtual ~ILogger() = default;
8-
virtual void log(const std::string& msg) const = 0;
37+
virtual ~logger_t() = default;
38+
39+
virtual void log(const std::string& msg, log_level_t level = log_level_t::info) const = 0;
940
};
1041

11-
class FileLogger : public ILogger {
42+
class console_logger_t : public logger_t {
1243
public:
13-
void log(const std::string& msg) const override { std::cout << "[File] " << msg << '\n'; }
44+
void log(const std::string& msg, log_level_t level = log_level_t::info) const override {
45+
std::cout << "[" << current_time_string() << "] " << "[" << to_string(level) << "] " << "[console] " << msg << '\n';
46+
}
1447
};
1548

16-
class ConsoleLogger : public ILogger {
49+
class file_logger_t : public logger_t {
1750
public:
18-
void log(const std::string& msg) const override { std::cout << "[Console] " << msg << '\n'; }
51+
void log(const std::string& msg, log_level_t level = log_level_t::info) const override {
52+
std::cout << "[" << current_time_string() << "] " << "[" << to_string(level) << "] " << "[file] " << msg << '\n';
53+
}
1954
};
2055

21-
class Application {
56+
class multi_logger_t : public logger_t {
2257
public:
23-
explicit Application(std::unique_ptr<ILogger> logger_in)
58+
void add_logger(std::unique_ptr<logger_t> logger) { loggers.push_back(std::move(logger)); }
59+
60+
void log(const std::string& msg, log_level_t level = log_level_t::info) const override {
61+
for (const auto& logger : loggers) {
62+
logger->log(msg, level);
63+
}
64+
}
65+
66+
private:
67+
std::vector<std::unique_ptr<logger_t>> loggers;
68+
};
69+
70+
class application_t {
71+
public:
72+
explicit application_t(std::unique_ptr<logger_t> logger_in)
2473
: logger(std::move(logger_in)) {}
2574

26-
void run() const { logger->log("App is running"); }
75+
void run() const {
76+
logger->log("application starting");
77+
perform_task();
78+
logger->log("application finished", log_level_t::info);
79+
}
2780

2881
private:
29-
std::unique_ptr<ILogger> logger;
82+
void perform_task() const {
83+
logger->log("processing data...");
84+
logger->log("minor issue detected", log_level_t::warning);
85+
logger->log("critical failure avoided", log_level_t::error);
86+
}
87+
88+
private:
89+
std::unique_ptr<logger_t> logger;
3090
};
3191

3292
int main() {
33-
std::unique_ptr<ILogger> logger = std::unique_ptr<ILogger>(new ConsoleLogger());
93+
auto root_logger = std::make_unique<multi_logger_t>();
3494

35-
Application app(std::move(logger));
95+
root_logger->add_logger(std::make_unique<console_logger_t>());
96+
root_logger->add_logger(std::make_unique<file_logger_t>());
97+
98+
application_t app(std::move(root_logger));
3699
app.run();
100+
37101
return 0;
38102
}

DesignPrinciple/composition_over_inheritance.cpp

Lines changed: 77 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,127 @@
11
/**
22
* @file composition_over_inheritance.cpp
3-
* @author Xuhua Huang
4-
* @brief Inheritance establishes an IS-A relaHonship
5-
* Composition/aggregation establish a HAS-A relaHonship – this can often be preferable
6-
*
7-
* Aggregation
8-
* An object comprised of other objects uses those objects
9-
* Those objects exist outside of the object
10-
* When the object is destroyed, the objects that comprise it remain
11-
*
12-
* @version 0.1
13-
* @date 2026-04-09
14-
*
15-
* @copyright Copyright (c) 2026
3+
* @brief Demonstration of composition over inheritance using runtime strategies
164
*
5+
* Key ideas:
6+
* - Prefer HAS-A over IS-A
7+
* - Compose behavior dynamically
8+
* - Keep components orthogonal and swappable
179
*/
1810

1911
#include <iostream>
2012
#include <memory>
21-
// #include <string>
13+
#include <vector>
14+
15+
namespace experimental {
16+
template <typename MovementPolicy, typename PowerPolicy>
17+
class vehicle_t;
18+
}
2219

23-
class IMovement {
20+
class movement_t {
2421
public:
25-
virtual ~IMovement() = default;
26-
virtual void move() const = 0;
22+
virtual ~movement_t() = default;
23+
virtual void move() const = 0;
24+
virtual const char* describe() const = 0;
2725
};
2826

29-
class IPowerSource {
27+
class power_source_t {
3028
public:
31-
virtual ~IPowerSource() = default;
32-
virtual void supply_power() const = 0;
29+
virtual ~power_source_t() = default;
30+
virtual void supply_power() const = 0;
31+
virtual const char* describe() const = 0;
3332
};
3433

35-
class WheelMovement : public IMovement {
34+
class wheel_movement_t : public movement_t {
3635
public:
3736
void move() const override { std::cout << "Moving on wheels\n"; }
37+
38+
const char* describe() const override { return "Wheel-based movement"; }
3839
};
3940

40-
class FlyingMovement : public IMovement {
41+
class flying_movement_t : public movement_t {
4142
public:
4243
void move() const override { std::cout << "Flying in the air\n"; }
44+
45+
const char* describe() const override { return "Aerial movement"; }
4346
};
4447

45-
class GasEngine : public IPowerSource {
48+
class gas_engine_t : public power_source_t {
4649
public:
4750
void supply_power() const override { std::cout << "Supplying power from gas engine\n"; }
51+
52+
const char* describe() const override { return "Gas engine"; }
4853
};
4954

50-
class ElectricBattery : public IPowerSource {
55+
class electric_battery_t : public power_source_t {
5156
public:
5257
void supply_power() const override { std::cout << "Supplying power from battery\n"; }
58+
59+
const char* describe() const override { return "Electric battery"; }
60+
};
61+
62+
class solar_panel_t : public power_source_t {
63+
public:
64+
void supply_power() const override { std::cout << "Supplying power from solar energy\n"; }
65+
66+
const char* describe() const override { return "Solar panel"; }
67+
};
68+
69+
// Composite power source (aggregation of multiple sources)
70+
class hybrid_power_t : public power_source_t {
71+
public:
72+
void add_source(std::unique_ptr<power_source_t> source) { sources.push_back(std::move(source)); }
73+
74+
void supply_power() const override {
75+
std::cout << "Hybrid power system engaged:\n";
76+
for (const auto& src : sources) {
77+
src->supply_power();
78+
}
79+
}
80+
81+
const char* describe() const override { return "Hybrid power system"; }
82+
83+
private:
84+
std::vector<std::unique_ptr<power_source_t>> sources;
5385
};
5486

55-
class Vehicle {
87+
class vehicle_t {
5688
public:
57-
Vehicle(std::unique_ptr<IMovement> movement, std::unique_ptr<IPowerSource> power_source)
89+
vehicle_t(std::unique_ptr<movement_t> movement, std::unique_ptr<power_source_t> power_source)
5890
: movement(std::move(movement))
5991
, power_source(std::move(power_source)) {}
6092

6193
void operate() const {
94+
std::cout << "[Vehicle Start]\n";
95+
std::cout << "Movement: " << movement->describe() << "\n";
96+
std::cout << "Power: " << power_source->describe() << "\n";
97+
6298
power_source->supply_power();
6399
movement->move();
100+
101+
std::cout << "[Vehicle End]\n\n";
64102
}
65103

66104
private:
67-
std::unique_ptr<IMovement> movement;
68-
std::unique_ptr<IPowerSource> power_source;
105+
std::unique_ptr<movement_t> movement;
106+
std::unique_ptr<power_source_t> power_source;
69107
};
70108

71109
int main() {
72-
// Traditional car
73-
Vehicle car(std::make_unique<WheelMovement>(), std::make_unique<GasEngine>());
110+
vehicle_t car(std::make_unique<wheel_movement_t>(), std::make_unique<gas_engine_t>());
111+
112+
vehicle_t ev(std::make_unique<wheel_movement_t>(), std::make_unique<electric_battery_t>());
74113

75-
// Electric car
76-
Vehicle ev(std::make_unique<WheelMovement>(), std::make_unique<ElectricBattery>());
114+
vehicle_t drone(std::make_unique<flying_movement_t>(), std::make_unique<electric_battery_t>());
77115

78-
// Futuristic flying electric vehicle
79-
Vehicle drone(std::make_unique<FlyingMovement>(), std::make_unique<ElectricBattery>());
116+
// Hybrid example: battery + solar
117+
auto hybrid_power = std::make_unique<hybrid_power_t>();
118+
hybrid_power->add_source(std::make_unique<electric_battery_t>());
119+
hybrid_power->add_source(std::make_unique<solar_panel_t>());
120+
121+
vehicle_t futuristic_vehicle(std::make_unique<flying_movement_t>(), std::move(hybrid_power));
80122

81123
car.operate();
82124
ev.operate();
83125
drone.operate();
126+
futuristic_vehicle.operate();
84127
}
85-
86-
class SolarPanel : public IPowerSource {
87-
public:
88-
void supply_power() const override { std::cout << "Supplying power from solar energy\n"; }
89-
};

0 commit comments

Comments
 (0)