From ed401eda98f6d17b3d2f2892974f2d1d45d39c43 Mon Sep 17 00:00:00 2001 From: XMuli Date: Sat, 24 Dec 2022 01:17:47 +0800 Subject: [PATCH] feat: add Observer Pattern --- Studio/DesignPatterns/DesignPatterns.cpp | 9 ++ Studio/DesignPatterns/DesignPatterns.vcxproj | 153 ++++++++++++++++++ .../DesignPatterns.vcxproj.filters | 36 +++++ Studio/DesignPatterns/Observer.cpp | 1 + Studio/DesignPatterns/Observer.h | 106 ++++++++++++ Studio/DesignPatterns/Singleton.cpp | 1 + Studio/DesignPatterns/Singleton.h | 24 +++ Studio/Studio.sln | 10 ++ Studio/Studio/BinarySearch.cpp | 1 + Studio/Studio/BinarySearch.h | 88 ++++++++++ Studio/Studio/SpecialMembers.h | 32 ++-- Studio/Studio/Studio.vcxproj | 2 + Studio/Studio/Studio.vcxproj.filters | 6 + 13 files changed, 453 insertions(+), 16 deletions(-) create mode 100644 Studio/DesignPatterns/DesignPatterns.cpp create mode 100644 Studio/DesignPatterns/DesignPatterns.vcxproj create mode 100644 Studio/DesignPatterns/DesignPatterns.vcxproj.filters create mode 100644 Studio/DesignPatterns/Observer.cpp create mode 100644 Studio/DesignPatterns/Observer.h create mode 100644 Studio/DesignPatterns/Singleton.cpp create mode 100644 Studio/DesignPatterns/Singleton.h create mode 100644 Studio/Studio/BinarySearch.cpp create mode 100644 Studio/Studio/BinarySearch.h diff --git a/Studio/DesignPatterns/DesignPatterns.cpp b/Studio/DesignPatterns/DesignPatterns.cpp new file mode 100644 index 0000000..a79b40b --- /dev/null +++ b/Studio/DesignPatterns/DesignPatterns.cpp @@ -0,0 +1,9 @@ +// DesignPatterns.cpp : This file contains the 'main' function. Program execution begins and ends there. +// + +#include + +//int main() +//{ +// std::cout << "Hello World!\n"; +//} diff --git a/Studio/DesignPatterns/DesignPatterns.vcxproj b/Studio/DesignPatterns/DesignPatterns.vcxproj new file mode 100644 index 0000000..e4812f6 --- /dev/null +++ b/Studio/DesignPatterns/DesignPatterns.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {57f3c035-9c90-4e9f-934a-032804827444} + DesignPatterns + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Studio/DesignPatterns/DesignPatterns.vcxproj.filters b/Studio/DesignPatterns/DesignPatterns.vcxproj.filters new file mode 100644 index 0000000..a0a15c0 --- /dev/null +++ b/Studio/DesignPatterns/DesignPatterns.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/Studio/DesignPatterns/Observer.cpp b/Studio/DesignPatterns/Observer.cpp new file mode 100644 index 0000000..3231ac2 --- /dev/null +++ b/Studio/DesignPatterns/Observer.cpp @@ -0,0 +1 @@ +#include "Observer.h" diff --git a/Studio/DesignPatterns/Observer.h b/Studio/DesignPatterns/Observer.h new file mode 100644 index 0000000..2c58a6b --- /dev/null +++ b/Studio/DesignPatterns/Observer.h @@ -0,0 +1,106 @@ +/******************************************************************* + * Copyright (c) 2022~2023 XMuli All rights reserved. + * GitHub: https://github.com/XMuli + * Description: 观察者模式 Observer Pattern + * Reference: 情景 → Subject 发送一个消息,然后所有的 Observer A、B、C + * 都有收到,并且对相同的消息,做出各自不同的操作响应 + * See: https://www.cnblogs.com/suzhou/p/dp16obsvr.html + ******************************************************************/ + +#pragma once +#include +#include +#include +using namespace std; + +class Observer { // 观察者 +public: + virtual void update(string msg) = 0; + virtual void doSomeThing() = 0; + +protected: + string m_msg; +}; + +class Subject { +public: + Subject() = default; + virtual ~Subject() = default; + virtual void addObsvr(Observer* obj) = 0; + virtual void removeObsvr(Observer* obj) = 0; + virtual void notify(string msg) = 0; +}; + +//--------------------------------------------------------- +class ConcreteSubject: public Subject { +public: + ConcreteSubject() {}; + virtual ~ConcreteSubject() { m_obsvrs.clear(); } + virtual void addObsvr(Observer* obj) override { + m_obsvrs.push_back(obj); + } + virtual void removeObsvr(Observer* obj) override { + m_obsvrs.remove(obj); + } + virtual void notify(string msg) override { + for (const auto& it : m_obsvrs) + it->update(msg); + + for (const auto& it : m_obsvrs) + it->doSomeThing(); + + cout << endl; + } + +private: + list m_obsvrs; +}; + +class AObserver : public Observer { +public: + void update(string msg) override { m_msg = msg; } + virtual void doSomeThing() override { cout << "AObserver: 对 " << m_msg << " 进行 A 的操作" << endl; } +}; + +class BObserver : public Observer { +public: + void update(string msg) override { m_msg = msg; } + virtual void doSomeThing() override { cout << "BObserver: 对 " << m_msg << " 进行 B 的操作" << endl; } +}; + +class CObserver : public Observer { +public: + void update(string msg) override { m_msg = msg; } + virtual void doSomeThing() override { cout << "CObserver: 对 " << m_msg << " 进行 C 的操作" << endl; } +}; + +int main() +{ + AObserver* a = new AObserver(); + BObserver* b = new BObserver(); + CObserver* c = new CObserver(); + ConcreteSubject* concreSubject = new ConcreteSubject(); + + concreSubject->addObsvr(a); + concreSubject->addObsvr(b); + concreSubject->addObsvr(c); + concreSubject->notify("messagebox 1"); + + concreSubject->removeObsvr(c); + concreSubject->notify("messagebox 2"); + + //a->doSomeThing(); + //b->doSomeThing(); + //c->doSomeThing(); + return 0; +} + + +/*****************************打印结果******************************* +AObserver: 对 messagebox 1 进行 A 的操作 +BObserver: 对 messagebox 1 进行 B 的操作 +CObserver: 对 messagebox 1 进行 C 的操作 + +AObserver: 对 messagebox 2 进行 A 的操作 +BObserver: 对 messagebox 2 进行 B 的操作 + ******************************************************************/ diff --git a/Studio/DesignPatterns/Singleton.cpp b/Studio/DesignPatterns/Singleton.cpp new file mode 100644 index 0000000..69acca0 --- /dev/null +++ b/Studio/DesignPatterns/Singleton.cpp @@ -0,0 +1 @@ +#include "Singleton.h" diff --git a/Studio/DesignPatterns/Singleton.h b/Studio/DesignPatterns/Singleton.h new file mode 100644 index 0000000..11faed8 --- /dev/null +++ b/Studio/DesignPatterns/Singleton.h @@ -0,0 +1,24 @@ +/******************************************************************* + * Copyright (c) 2022~2023 XMuli All rights reserved. + * GitHub: https://github.com/XMuli + * Description: 单例模式 Singleton Pattern 的最优雅实现 + * Reference: https://zhuanlan.zhihu.com/p/37469260 单例介绍及好一篇 + ******************************************************************/ +#pragma once + +// 《Effective C++》提出了一种更优雅的单例模式实现,称为 Meyers' Singleton +class Singleton +{ +public: + static Singleton& instance() { + static Singleton instan; + return instan; + } + +private: + Singleton() {}; + ~Singleton() {}; + Singleton(const Singleton& obj) = delete; + Singleton& operator=(const Singleton& obj) = delete; +}; + diff --git a/Studio/Studio.sln b/Studio/Studio.sln index d72b602..cbd932b 100644 --- a/Studio/Studio.sln +++ b/Studio/Studio.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.32802.440 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Studio", "Studio\Studio.vcxproj", "{11117C51-BEAF-4F63-B386-CDB0760BCDE8}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DesignPatterns", "DesignPatterns\DesignPatterns.vcxproj", "{57F3C035-9C90-4E9F-934A-032804827444}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -21,6 +23,14 @@ Global {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Release|x64.Build.0 = Release|x64 {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Release|x86.ActiveCfg = Release|Win32 {11117C51-BEAF-4F63-B386-CDB0760BCDE8}.Release|x86.Build.0 = Release|Win32 + {57F3C035-9C90-4E9F-934A-032804827444}.Debug|x64.ActiveCfg = Debug|x64 + {57F3C035-9C90-4E9F-934A-032804827444}.Debug|x64.Build.0 = Debug|x64 + {57F3C035-9C90-4E9F-934A-032804827444}.Debug|x86.ActiveCfg = Debug|Win32 + {57F3C035-9C90-4E9F-934A-032804827444}.Debug|x86.Build.0 = Debug|Win32 + {57F3C035-9C90-4E9F-934A-032804827444}.Release|x64.ActiveCfg = Release|x64 + {57F3C035-9C90-4E9F-934A-032804827444}.Release|x64.Build.0 = Release|x64 + {57F3C035-9C90-4E9F-934A-032804827444}.Release|x86.ActiveCfg = Release|Win32 + {57F3C035-9C90-4E9F-934A-032804827444}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Studio/Studio/BinarySearch.cpp b/Studio/Studio/BinarySearch.cpp new file mode 100644 index 0000000..7b1c4ae --- /dev/null +++ b/Studio/Studio/BinarySearch.cpp @@ -0,0 +1 @@ +#include "BinarySearch.h" diff --git a/Studio/Studio/BinarySearch.h b/Studio/Studio/BinarySearch.h new file mode 100644 index 0000000..8b7b2e2 --- /dev/null +++ b/Studio/Studio/BinarySearch.h @@ -0,0 +1,88 @@ +#pragma once +#include +#include +using namespace std; + +int binarySearch(vector vec, int target) +{ + int left = 0; + int right = vec.size() - 1; + + while (left <= right) { + int mid = left + (right - left) / 2; + + if (target < vec[mid]) { + right = mid - 1; + } else if (target > vec[mid]) { + left = mid + 1; + } else { + return mid; + } + } + + return -1; +} + +int binarySearch2(vector vec, int target) +{ + int left = 0; + int right = vec.size(); + + while (left < right) { + int mid = left + (right - left) / 2; + + if (target < vec[mid]) { + right = mid; + } else if (target > vec[mid]) { + left = mid + 1; + } else { + return mid; + } + } + + return -1; +} + + +int binarySearch3(vector& vec, int left, int right, int target) +{ + if (left > right) // target 在数组左右两侧时的场景 + return -1; + + int mid = left + (right - left) / 2; + if (target < vec[mid]) { + return binarySearch3(vec, left, mid -1, target); + } else if (target > vec[mid]) { + return binarySearch3(vec, mid + 1, right, target); + } else { + return mid; + } +} + +// 毒药版-错误百出版本 +//int binarySearch4(vector vec, int target) +//{ +// int mid = vec.size() / 2; +// +// if (target < vec[mid]) { +// vector t(vec.begin(), vec.begin() + mid); +// return binarySearch4(t, target); +// } else if (target > vec[mid]) { +// vector t(vec.begin() + mid + 1, vec.end()); +// return binarySearch4(t, target); +// } else { +// return mid; +// } +// return -1; +//} + +int main() +{ + vector v = { 0, 3, 5, 6, 7 }; + int target = 8; + cout << "binarySearch:" << binarySearch(v, target) << endl + << "binarySearch2:" << binarySearch2(v, target) << endl + << "binarySearch3:" << binarySearch3(v, 0, v.size() - 1, target) << endl; + + return 0; +} \ No newline at end of file diff --git a/Studio/Studio/SpecialMembers.h b/Studio/Studio/SpecialMembers.h index 6bf8a2b..a726751 100644 --- a/Studio/Studio/SpecialMembers.h +++ b/Studio/Studio/SpecialMembers.h @@ -89,22 +89,22 @@ A fn() { return t; } -int main() -{ - A a1("a1"); // default constructor - A a2(a1); // copy constructor - A a3 = a1; // copy constructor - a1 = a3; // copy assignment constructor - std::cout << "----------------------------\n\n"; - - //fn(); // function returning a A object - A a5 = std::move(a1); // move constructor - A a6; // default constructor - a6 = std::move(a1); // move assignment constructor - std::cout << "Hello World!\n"; - - return 0; -} +//int main() +//{ +// A a1("a1"); // default constructor +// A a2(a1); // copy constructor +// A a3 = a1; // copy constructor +// a1 = a3; // copy assignment constructor +// std::cout << "----------------------------\n\n"; +// +// //fn(); // function returning a A object +// A a5 = std::move(a1); // move constructor +// A a6; // default constructor +// a6 = std::move(a1); // move assignment constructor +// std::cout << "Hello World!\n"; +// +// return 0; +//} /*************************** 运行结果 ******************************* * no-default-val constructor diff --git a/Studio/Studio/Studio.vcxproj b/Studio/Studio/Studio.vcxproj index a566a5e..22e43e1 100644 --- a/Studio/Studio/Studio.vcxproj +++ b/Studio/Studio/Studio.vcxproj @@ -139,12 +139,14 @@ + + diff --git a/Studio/Studio/Studio.vcxproj.filters b/Studio/Studio/Studio.vcxproj.filters index 5a978e3..6dd8b21 100644 --- a/Studio/Studio/Studio.vcxproj.filters +++ b/Studio/Studio/Studio.vcxproj.filters @@ -27,6 +27,9 @@ Source Files + + Source Files + @@ -41,5 +44,8 @@ Header Files + + Header Files + \ No newline at end of file