Skip to content

Commit c524c81

Browse files
committed
Update descriptions
1 parent 1beb831 commit c524c81

5 files changed

Lines changed: 102 additions & 78 deletions

File tree

src/dp/creational/AbstractFactory.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
// cppcheck-suppress-file [functionStatic]
22

3-
// Abstract Factory is a creational design pattern that lets you produce
4-
// families of related objects without specifying their concrete classes.
3+
// Abstract Factory — create families of related products without concrete types.
4+
//
5+
// Flow in this file:
6+
// 1. Define product interfaces -> IGdbProduct, ICMakeProduct
7+
// 2. Implement concrete products per OS -> Linux / Windows / MacOs variants
8+
// 3. Define an abstract factory -> IProductAbstractFactory
9+
// 4. Implement concrete factories -> one factory = one matching family
10+
// 5. Client uses one factory for all products -> products stay consistent (same OS)
511

612
#include <memory>
713
#include <string>

src/dp/creational/Builder.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
// cppcheck-suppress-file [functionStatic]
22

3+
// Flow in this file:
4+
// 1. Define the product being built -> Product (parts list)
5+
// 2. Define a builder interface -> IBuilder (produce_part_N / build)
6+
// 3. Share common builder state -> AbstractBuilder (reset / product_)
7+
// 4. Implement concrete builders -> SimpleBuilder / ComplexBuilder
8+
// 5. Client chains steps, then build() -> same steps, different representations
9+
310
#include <memory>
411
#include <ostream>
512
#include <sstream>

src/dp/creational/FactoryMethod.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
// cppcheck-suppress-file [functionStatic]
22

3+
// Flow in this file:
4+
// 1. Define a product interface -> IGdbProduct
5+
// 2. Implement concrete products -> Linux / Windows / MacOs Gdb
6+
// 3. Define a creator interface -> IGdbFactory (+ AbstractGdbFactory)
7+
// 4. Implement concrete creators -> Linux / Windows / MacOs factories
8+
// 5. Client picks a factory, then uses it -> never constructs products directly
9+
310
#include <memory>
411
#include <string>
512
#include "ExampleRegistry.h"

src/dp/creational/Prototype.cpp

Lines changed: 72 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,131 @@
11
// cppcheck-suppress-file [functionStatic]
22

3-
// Prototype is a creational design pattern that lets you "copy existing objects" without making your code "dependent on their classes".
4-
// Appicability:
5-
// (*) when your code shouldn’t depend on the concrete classes of objects that you need to copy.
6-
// (**) when you want to reduce the number of subclasses that only differ in the way they initialize their respective objects.
7-
8-
// UML: docs/uml/patterns_behavioral_prototype.drawio.svg
9-
3+
// Prototype = create new objects by cloning existing ones.
4+
//
5+
// Flow in this file:
6+
// 1. Define a cloneable interface -> IExtensionPrototype
7+
// 2. Implement concrete prototypes -> Logger / Analytics
8+
// 3. (Optional) Store named presets -> ExtensionPrototypeRegistry
9+
// 4. Client asks registry to clone by id -> never mentions concrete types
10+
11+
#include <memory>
12+
#include <string>
13+
#include <string_view>
1014
#include <unordered_map>
1115
#include <utility>
16+
17+
#include "ExampleRegistry.h"
1218
#include "Logger.h"
19+
1320
namespace {
1421
namespace prototy {
1522

16-
constexpr std::string_view kLoggerEtxId = "logger";
23+
constexpr std::string_view kLoggerExtId = "logger";
1724
constexpr std::string_view kAnalyzeId = "analyze";
1825

19-
/*
20-
* Prototype interface declares the cloning methods.
21-
* In most cases, it’s a single `clone` method.
22-
*/
26+
/// @class Prototype interface: "I know how to copy myself."
27+
/// @brief client code only depends on this class
2328
class IExtensionPrototype {
2429
public:
2530
virtual ~IExtensionPrototype() = default;
26-
virtual IExtensionPrototype* clone() = 0;
31+
32+
/// return a new object
33+
virtual std::unique_ptr<IExtensionPrototype> clone() const = 0;
34+
2735
virtual void execute() const = 0;
2836
};
2937

30-
/*
31-
* Concrete Prototype implement an operation for cloning itself
32-
* In addition to copying the original object’s data to the clone,
33-
* this method may also handle some edge cases of the cloning process related to cloning linked objects,
34-
* untangling recursive dependencies, etc.
35-
*/
38+
/// @class Concrete Prototype
39+
/// @brief each class copies itself
3640
class LoggerExtension : public IExtensionPrototype {
37-
private:
38-
std::string log_level_;
39-
4041
public:
4142
explicit LoggerExtension(std::string level = "DEBUG")
4243
: log_level_{std::move(level)} {}
4344

44-
IExtensionPrototype* clone() override { return new LoggerExtension(*this); }
45+
std::unique_ptr<IExtensionPrototype> clone() const override {
46+
return std::make_unique<LoggerExtension>(*this);
47+
}
4548

4649
void execute() const override { LOG("log level: " + log_level_); }
47-
};
4850

49-
class AnalyticsExtension : public IExtensionPrototype {
5051
private:
51-
int sRate_;
52+
std::string log_level_;
53+
};
5254

55+
class AnalyticsExtension : public IExtensionPrototype {
5356
public:
54-
explicit AnalyticsExtension(int level = 1) : sRate_{level} {}
57+
explicit AnalyticsExtension(int sampling_rate = 1)
58+
: sampling_rate_{sampling_rate} {}
5559

56-
IExtensionPrototype* clone() override {
57-
return new AnalyticsExtension(*this);
60+
std::unique_ptr<IExtensionPrototype> clone() const override {
61+
return std::make_unique<AnalyticsExtension>(*this);
5862
}
5963

60-
void execute() const override { LOG_S("sampling rate: " << sRate_); }
61-
};
64+
void execute() const override { LOG_S("sampling rate: " << sampling_rate_); }
6265

63-
/**
64-
* Prototype Registry provides an easy way to access frequently-used prototypes.
65-
* It stores a set of pre-built objects that are ready to be copied.
66-
* The simplest prototype registry is a name ^ prototype hash map.
67-
* However, if you need better search criteria than a simple name, you can build a much more robust version of the registry.
68-
*/
69-
class ExtensionPrototypeRegistry {
7066
private:
71-
std::unordered_map<std::string, IExtensionPrototype*> prototypes_;
67+
int sampling_rate_;
68+
};
7269

70+
/// @class Prototype Registry
71+
/// @brief a map of named presets ready to be cloned.
72+
class ExtensionPrototypeRegistry {
7373
public:
74-
~ExtensionPrototypeRegistry() {
75-
for (auto it = prototypes_.begin(); it != prototypes_.end();) {
76-
delete it->second; // free the pointer
77-
it = prototypes_.erase(it); // erase and move to next
78-
}
79-
}
80-
void register_extension(const std::string_view& id,
81-
IExtensionPrototype* proto) {
74+
void register_extension(std::string_view id,
75+
std::unique_ptr<IExtensionPrototype> proto) {
8276
LOG(id);
83-
prototypes_[std::string(id)] = proto;
77+
prototypes_[std::string(id)] = std::move(proto);
8478
}
8579

86-
IExtensionPrototype* create(const std::string_view& id) const {
80+
/// clone the preset for `id`. Returns nullptr if the id is unknown.
81+
std::unique_ptr<IExtensionPrototype> create(std::string_view id) const {
8782
auto it = prototypes_.find(std::string(id));
88-
if (it != prototypes_.end()) {
89-
return it->second->clone();
83+
if (it == prototypes_.end()) {
84+
return nullptr;
9085
}
91-
return nullptr;
86+
return it->second->clone(); // copy the template, leave the original intact
9287
}
88+
89+
private:
90+
std::unordered_map<std::string, std::unique_ptr<IExtensionPrototype>>
91+
prototypes_;
9392
};
9493

9594
void run() {
96-
// Client creates a new object by asking a prototype to clone itself
97-
auto client_code = [](const ExtensionPrototypeRegistry* const registry) {
98-
IExtensionPrototype* logger_etx = registry->create(prototy::kLoggerEtxId);
99-
logger_etx->execute();
100-
IExtensionPrototype* analyx_etx = registry->create(prototy::kAnalyzeId);
101-
analyx_etx->execute();
102-
103-
delete logger_etx;
104-
delete analyx_etx;
95+
// build presets once, register by name
96+
ExtensionPrototypeRegistry registry;
97+
registry.register_extension(kLoggerExtId,
98+
std::make_unique<LoggerExtension>("DEBUG"));
99+
registry.register_extension(kAnalyzeId,
100+
std::make_unique<AnalyticsExtension>(1200));
101+
102+
// create-by-clone
103+
auto client_code = [](const ExtensionPrototypeRegistry& reg) {
104+
auto logger_ext = reg.create(kLoggerExtId);
105+
auto analytics_ext = reg.create(kAnalyzeId);
106+
107+
if (logger_ext) {
108+
logger_ext->execute();
109+
}
110+
if (analytics_ext) {
111+
analytics_ext->execute();
112+
}
105113
};
106114

107-
// Create a registry
108-
auto* registry = new ExtensionPrototypeRegistry();
109-
110-
// Register extensions
111-
registry->register_extension(prototy::kLoggerEtxId,
112-
new LoggerExtension("DEBUG"));
113-
registry->register_extension(prototy::kAnalyzeId,
114-
new AnalyticsExtension(1200));
115-
116115
client_code(registry);
117-
118-
delete registry;
119116
}
117+
120118
} // namespace prototy
121119
} // namespace
122120

123-
#include "ExampleRegistry.h"
124-
125121
class PrototypeExample : public IExample {
126122
public:
127123
std::string group() const override { return "dp/creational"; }
128124
std::string name() const override { return "Prototype"; }
129125
std::string description() const override {
130-
return "Prototype Pattern Example";
126+
return "Clone configured objects via a prototype interface + registry";
131127
}
132128
void execute() override { prototy::run(); }
133129
};
134130

135-
REGISTER_EXAMPLE(PrototypeExample);
131+
REGISTER_EXAMPLE(PrototypeExample);

src/dp/creational/Singleton.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
// cppcheck-suppress-file [functionStatic]
22

3+
// Singleton — ensure a class has only one instance, accessed globally.
4+
//
5+
// Flow in this file:
6+
// 1. Hide the constructor -> private SingletonConfig()
7+
// 2. Ban copy / assign -> deleted special members
8+
// 3. Expose a single access point -> get_instance() (Meyers' singleton)
9+
// 4. Client always uses get_instance() -> same object everywhere
10+
311
#include <string>
412
#include "ExampleRegistry.h"
513
#include "Logger.h"

0 commit comments

Comments
 (0)