C++ features by examples
patterns.cpp
Go to the documentation of this file.
1#include <bits/stdc++.h>
2
3using namespace std;
4
66template <typename ValueType>
69 virtual void set(ValueType i) = 0;
70 virtual ~Setter_interface() = default;
71};
72
73template <typename ValueType>
76 virtual ValueType get() const = 0;
77 virtual ~Getter_interface() = default;
78};
79
80template <typename ValueType>
83 virtual void change(ValueType c) = 0;
84 virtual ~Change_interface() = default;
85};
86
87template <typename ValueType>
94 : public Setter_interface<ValueType>, public Getter_interface<ValueType>, public Change_interface<ValueType>
95{
96 void set(ValueType i) override {
97 scoped_lock writer_lock(mtx);
98 value = i;
99 }
100
101 ValueType get() const override {
102 shared_lock reader_lock(mtx);
103 return value;
104 }
105
106 void change(ValueType c) override {
107 scoped_lock writer_lock(mtx);
108 value += c;
109 }
110
111 mutable shared_mutex mtx;
112 ValueType value;
113};
114
121{
122 auto client = [] (Setter_interface<int>& s, Getter_interface<int>& g) {
123 s.set(1);
124 assert(g.get() == 1);
125 };
129 client(s, g);
130
131 auto client2 = [] (Setter_interface<string>& s, Getter_interface<string>& g) {
132 s.set("abc");
133 assert(g.get() == "abc");
134 };
139 client2(s2, g2);
140 c2.change("de");
141 assert(g2.get() == "abcde");
142}
143
145
167{
168 virtual int method() = 0;
169 virtual ~Interface() = default;
170};
171
186#define SINGLETON(Singleton) \
187public: \
188 /* Meyers Singleton realization */ \
189 static Singleton& instance() { \
190 static Singleton me; \
191 return me; \
192 } \
193 Singleton(const Singleton&) = delete; \
194 Singleton& operator=(const Singleton&) = delete; \
195 Singleton(Singleton&&) = delete; \
196 Singleton& operator=(Singleton&&) = delete; \
197private: \
198 Singleton()
199
201{
203};
204
206{
207 virtual unique_ptr<Interface> factory_method() = 0;
208
209 int client() {
210 auto p(factory_method());
211 return p->method();
212 };
213};
214
216 : Interface
217{
218 int data;
219 int method() override { return data; }
220 Sample_product(int d = 0) : data(d) {}
221};
222
225{
226 unique_ptr<Interface> factory_method() override {
227 return make_unique<Sample_product>(123);
228 }
229};
230
232{
233 virtual unique_ptr<Interface> create() = 0;
234};
235
238{
239 virtual unique_ptr<Interface> create() {
240 return make_unique<Sample_product>();
241 }
242};
243
247{
248
249 int method() override { return 1; }
250 unique_ptr<Interface> create() override {
251 auto clone = new Prototype(*this);
252 return unique_ptr<Interface>(clone);
253 }
254};
255
257{
258 int data = 0;
259 Builder& add(int i) {
260 data += i;
261 return *this;
262 }
263
264 Builder& operator <<(int i) { return add(i); }
265
267 {
268 return *new Sample_product(data);
269 }
270};
271
273{
274 Singleton_demo& singe = Singleton_demo::instance();
275
276 unique_ptr<Abstract_factory> factory(new Sample_factory());
277
278 auto product = factory->create();
279
280 Prototype p1;
281 auto p2 = p1.create();
282
284 assert(C.client() == 123);
285
286 Interface& p = (Builder().add(1).add(2) << 3 << 4).create();
287 assert(p.method() == 10);
288 // strstream looks like string builder
289 delete &p;
290}
291
293
308{
309 float standalone_method() const {
310 return 1.01;
311 }
312};
313
314struct Bridge
316 : public Interface
317{
318 Bridge(Standalone& s): standalone(s) {
319// trace(typeid(*this).name());
320 }
321 int method() override {
322 return this->standalone.standalone_method();
323 }
324private:
325 Standalone& standalone;
326};
327
328struct Proxy
330 : public Interface
331{
332 Proxy(Interface& o): subject(o) {}
333 int method() override {
334 return this->subject.method();
335 }
336private:
337 Interface& subject;
338};
339
342 : public Interface
343{
345 int method() override {
346 return 100 + this->subject.method();
347 }
348 Interface& subject; // decorated object is public
349};
350
352 : public Interface
353{
354 int method() override {
355 //trace();
356 for (Interface& i : children) i.method();
357 return 0;
358 }
359 forward_list<reference_wrapper<Interface>> children;
360};
361
363{
364 Standalone sa;
365 Bridge br(sa);
366 br.method();
367 Proxy p(br);
368 Decorator dec(br);
369 dec.method();
370 dec.subject.method();
371 p.method();
372 Composite comp;
373 comp.children.push_front(p);
374 comp.method();
375}
376
378
392struct Subject;
393
396{
398 virtual void notify() {};
400 virtual void update(Subject& subject) {};
401 virtual ~Observer() = default;
402};
403
406{
408 for (Observer& o : observers) {
409 o.notify();
410 o.update(*this);
411 }
412 }
413 forward_list<reference_wrapper<Observer>> observers;
414};
415
423{
424 virtual int execute() { return -1; };
425};
426
427
436struct Visitor;
437
440{
441 virtual string component_accept(Visitor&) const = 0;
442 virtual ~Component() = default;
443};
444
445struct Sample_component;
448{
450 virtual string visit(const Sample_component&) const = 0;
451 virtual ~Visitor() = default;
452};
453
455 : public Component
459{
460 string component_accept(Visitor& visitor) const override {
461 return string(__func__) + " > " + visitor.visit(*this);
462 }
464 string component_method() const {
465 return __func__;
466 }
467};
468
469string client_visit(const forward_list<unique_ptr<Component>>& components,
470 const forward_list<unique_ptr<Visitor>>& visitors)
472{
473 string res;
474 for (auto&& comp : components)
475 for (auto&& vis : visitors) {
476 res += string(__func__) + " > " + comp->component_accept(*vis.get());
477 }
478 return res;
479}
480
492{
495 struct Sample_visitor
496 : public Visitor {
498 string visit(const Sample_component& c) const override {
499 return string(__func__) + " > " + c.component_method();
500 }
501 };
502
503 forward_list<unique_ptr<Component>> components;
504 components.emplace_front(new Sample_component);
505 Sample_visitor v;
506 forward_list<unique_ptr<Visitor>> visitors;
507 visitors.emplace_front(new Sample_visitor);
508 assert(client_visit(components, visitors) ==
509 "client_visit > component_accept > visit > component_method");
510}
511
513
516{
518 virtual int handle(Command& cmnd) { return cmnd.execute(); };
519 virtual ~Handler() = default;
520};
521
523 : Handler
531{
532 void register_handler(Handler&& h, bool front = false) {
533 if (front)
534 handlers.push_front(h);
535 else
536 handlers.push_back(h);
537 }
538 int handle(Command& cmnd) override {
539 int rc = -1;
540 for (Handler& h : handlers)
541 if ((rc = h.handle(cmnd)) >= 0)
542 return rc;
543 return rc;
544 }
545private:
546 list<reference_wrapper<Handler>> handlers;
547};
548
549struct Message { };
550
557struct Mediator;
558
559struct Member
560{
562 void send(Message& );
563 void receive(Message& ) { }
564};
565
567{
569 m.mediator = this;
570 members.push_front(m);
571 }
572 void receive(Message& msg) {
573 for (Member& m : members)
574 m.receive(msg);
575 }
576 forward_list<reference_wrapper<Member>> members;
577};
578
580{
581 mediator->receive(m);
582}
583
585{
586 Member m1, m2;
587 Mediator md;
588 md.register_member(m1);
589 md.register_member(m2);
590 Message msg;
591 m1.send(msg);
592}
593
595{
597 chain.register_handler(Handler());
598
599 Command cmnd;
600 chain.handle(cmnd);
601
602 Observer o;
603 Subject s;
604 s.observers.push_front(o);
605
606 visitor_demo();
607
609}
610
612
622struct Model
623 : Subject
625{
627 observers.push_front(o);
628 }
629
630 int command(Command& cmnd) {
631 int rc = cmnd.execute();
633 return rc;
634 }
635
636 int command(Command&& cmnd) {
637 int rc = cmnd.execute();
639 return rc;
640 }
641};
642
643struct View
645 : public Observer
646{
647 View(Model& m) : model(m) {};
648
649 void notify() override {
650 // check model
651 (void)model;
652 }
653
655};
656
661{
662 Model& mod; // can be many models
663 Controller(Model& s) : mod(s) { };
664
665 int command(Command& cmnd) {
666 return mod.command(cmnd);
667 }
668
669 int command(Command&& cmnd) {
670 return mod.command(cmnd);
671 }
672};
673
682{
683 void message(Message& m) {
684 };
685};
686
688{
689 map<string, forward_list<reference_wrapper<Subscriber>>> topic_subscribers;
690
691 void publish(const string& topic, Message& m) {
692 for (Subscriber& s : topic_subscribers[topic])
693 s.message(m);
694 }
695};
697
699{
700 Model mod;
701 View view(mod);
702 mod.register_observer(view);
703 mod.notify_observers();
704 Controller ctrl(mod);
705 ctrl.command(Command());
706 Command cmnd;
707 ctrl.command(cmnd);
708
709 Subscriber sub;
710 Publisher pub;
711 pub.topic_subscribers["sample_topic"].push_front(sub);
712 Message m;
713 pub.publish("sample_topic", m);
714}
715
717
725template <typename T, class Container = std::queue<T>>
727 : Container
728{
729 mutex mtx;
730public:
731 condition_variable cv;
732 bool stop = false;
733 void push(T&& v) {
734 scoped_lock<mutex>{mtx}, Container::push(v);
735 cv.notify_one();
736 };
737
738 optional<reference_wrapper<T>> pull() {
739 unique_lock<mutex> lk(mtx);
740 cv.wait(lk, [&] { return !this->empty() || stop; });
741 optional<reference_wrapper<T>> ret;
742 if (stop) {
743 ret = nullopt;
744 } else {
745 ret = make_optional(ref(Container::front()));
746 this->pop();
747 }
748 return ret;
749 };
750};
751
758 : Interface
759{
760 typedef function<void()> Command;
763 : subject(s)
764 {
765 th = thread([this] {
766 while (true) {
767 auto cmd = cmd_q.pull();
768 if (!cmd.has_value())
769 break;
770 cmd.value()();
771 }
772 });
773 }
775 cmd_q.stop = true;
776 cmd_q.cv.notify_one();
777 th.join();
778 }
779
780 int method() override {
781 promise<int> p;
782 future f = p.get_future();
783 cmd_q.push([&p, this] { p.set_value(subject.method());});
784 return f.get();
785 }
786
787protected:
789 thread th;
790};
791
793{
794 Sample_product sp(3);
795 Active_object ao(sp);
796 assert(ao.method() == 3);
797}
798
800
801
802int main()
803{
804 oop_demo();
810}
811
813
encapsulating class with only public accessor and mutator intrfaces
Definition: patterns.cpp:95
optional< reference_wrapper< T > > pull()
Definition: patterns.cpp:738
void push(T &&v)
Definition: patterns.cpp:733
condition_variable cv
Definition: patterns.cpp:731
void architectural_patterns_demo()
Definition: patterns.cpp:698
void send(Message &)
Definition: patterns.cpp:579
void mediator_demo()
Definition: patterns.cpp:584
void behavioral_patterns_demo()
Definition: patterns.cpp:594
void concurrency_patterns_demo()
Definition: patterns.cpp:792
void creational_patterns_demo()
Definition: patterns.cpp:272
int main()
Definition: patterns.cpp:802
void oop_demo()
Definition: patterns.cpp:115
void structural_patterns_demo()
Definition: patterns.cpp:362
void visitor_demo()
Definition: patterns.cpp:491
string client_visit(const forward_list< unique_ptr< Component > > &components, const forward_list< unique_ptr< Visitor > > &visitors)
knows only virtual visitor and component
Definition: patterns.cpp:469
virtual unique_ptr< Interface > create()=0
Active object
Definition: patterns.cpp:759
function< void()> Command
Definition: patterns.cpp:760
Interface & subject
Definition: patterns.cpp:761
Active_object(Interface &s)
Definition: patterns.cpp:762
int method() override
Definition: patterns.cpp:780
Synchronized_queue< Command > cmd_q
Definition: patterns.cpp:788
is a wrapper using different from Standalone interface. AKA Adapter
Definition: patterns.cpp:317
int method() override
Definition: patterns.cpp:321
Bridge(Standalone &s)
Definition: patterns.cpp:318
Builder & add(int i)
Definition: patterns.cpp:259
Builder & operator<<(int i)
Definition: patterns.cpp:264
Interface & create()
Definition: patterns.cpp:266
int data
Definition: patterns.cpp:258
list based implementation without recursion
Definition: patterns.cpp:531
int handle(Command &cmnd) override
Specific handler can process a command and return non-negative.
Definition: patterns.cpp:538
void register_handler(Handler &&h, bool front=false)
Definition: patterns.cpp:532
virtual ~Change_interface()=default
virtual void change(ValueType c)=0
is a sample of getter abstract interface for Synchronised_encapsulated_value
encapsulates arguments. AKA Intent, operation.
Definition: patterns.cpp:423
virtual int execute()
Definition: patterns.cpp:424
accepts a pure virtual Visitor
Definition: patterns.cpp:440
virtual string component_accept(Visitor &) const =0
virtual ~Component()=default
int method() override
Definition: patterns.cpp:354
forward_list< reference_wrapper< Interface > > children
Definition: patterns.cpp:359
is part of MVC with Model and View
Definition: patterns.cpp:661
Controller(Model &s)
Definition: patterns.cpp:663
Model & mod
Definition: patterns.cpp:662
int command(Command &&cmnd)
Definition: patterns.cpp:669
int command(Command &cmnd)
Definition: patterns.cpp:665
is a partial wrapper of an object with same as wrapped object Interface
Definition: patterns.cpp:343
Interface & subject
Definition: patterns.cpp:348
int method() override
Definition: patterns.cpp:345
Decorator(Interface &o)
Definition: patterns.cpp:344
virtual unique_ptr< Interface > factory_method()=0
virtual ValueType get() const =0
is a sample of getter abstract interface for Synchronised_encapsulated_value
virtual ~Getter_interface()=default
is a virtual command handler of Chain_of_responsibility
Definition: patterns.cpp:516
virtual int handle(Command &cmnd)
Specific handler can process a command and return non-negative.
Definition: patterns.cpp:518
virtual ~Handler()=default
is a common pure virtual interface
Definition: patterns.cpp:167
virtual int method()=0
virtual ~Interface()=default
forward_list< reference_wrapper< Member > > members
Definition: patterns.cpp:576
void register_member(Member &m)
Definition: patterns.cpp:568
void receive(Message &msg)
Definition: patterns.cpp:572
void receive(Message &)
Definition: patterns.cpp:563
Mediator * mediator
Definition: patterns.cpp:561
is part of MVC with View and Controller
Definition: patterns.cpp:625
void register_observer(Observer &o)
Definition: patterns.cpp:626
int command(Command &cmnd)
Definition: patterns.cpp:630
int command(Command &&cmnd)
Definition: patterns.cpp:636
is virtual observer of a Subject
Definition: patterns.cpp:396
virtual ~Observer()=default
virtual void notify()
without arguments
Definition: patterns.cpp:398
virtual void update(Subject &subject)
with the only Subject argument
Definition: patterns.cpp:400
is the factory of himself
Definition: patterns.cpp:247
int method() override
Definition: patterns.cpp:249
unique_ptr< Interface > create() override
Definition: patterns.cpp:250
is a opaque wrapper with same as wrapped object Interface
Definition: patterns.cpp:331
int method() override
Definition: patterns.cpp:333
Proxy(Interface &o)
Definition: patterns.cpp:332
map< string, forward_list< reference_wrapper< Subscriber > > > topic_subscribers
Definition: patterns.cpp:689
void publish(const string &topic, Message &m)
Definition: patterns.cpp:691
one of many components is independed from Sample_visitor and implemenation of function visit.
Definition: patterns.cpp:459
string component_accept(Visitor &visitor) const override
Definition: patterns.cpp:460
string component_method() const
is not virtual
Definition: patterns.cpp:464
unique_ptr< Interface > factory_method() override
Definition: patterns.cpp:226
virtual unique_ptr< Interface > create()
Definition: patterns.cpp:239
int method() override
Definition: patterns.cpp:219
Sample_product(int d=0)
Definition: patterns.cpp:220
virtual ~Setter_interface()=default
virtual void set(ValueType i)=0
is a sample of setter abstract interface for Synchronised_encapsulated_value
SINGLETON(Singleton_demo)
Definition: patterns.cpp:202
is wrapped by Bridge. AKA adaptee of Adapter
Definition: patterns.cpp:308
float standalone_method() const
Definition: patterns.cpp:309
of Observer
Definition: patterns.cpp:406
void notify_observers()
Definition: patterns.cpp:407
forward_list< reference_wrapper< Observer > > observers
Definition: patterns.cpp:413
void message(Message &m)
Definition: patterns.cpp:683
is concrete Observer
Definition: patterns.cpp:646
View(Model &m)
Definition: patterns.cpp:647
Model & model
Definition: patterns.cpp:654
void notify() override
without arguments
Definition: patterns.cpp:649
is a pure virtual visitor of Sample_component and other specific components
Definition: patterns.cpp:448
virtual ~Visitor()=default
virtual string visit(const Sample_component &) const =0
overloaded function for each component