├── .gitignore ├── Draft.py ├── LICENSE ├── README.md ├── StartPython.py ├── Test.py ├── advanced_pattern ├── Callback.py ├── Filter.py ├── MVC.py └── ObjectPool.py ├── advanced_programming ├── Decorator.py ├── MagicMethod.py ├── Metaclass.py └── __init__.py ├── application ├── GameCommand.py ├── ImageProcessing.py ├── TerminalMonitor.py ├── WhiteBoard.py └── __init__.py ├── docs ├── DesignPattern.eap └── EverybodyKnowsDesgnPatterns.jpg ├── pattern ├── Adapter.py ├── Bridge.py ├── Builder.py ├── Clone.py ├── Command.py ├── ComputerComposite.py ├── Decorator.py ├── Facade.py ├── Flyweight.py ├── Interpreter.py ├── Iterator.py ├── Mediator.py ├── Memento.py ├── Observer.py ├── Proxy.py ├── Responsibility.py ├── SimpleFactory.py ├── Singleton.py ├── State.py ├── Strategy.py ├── Template.py └── Visitor.py └── principle ├── DIP.py ├── DRY.py ├── ISP.py ├── LSP.py ├── LoD.py ├── OCP.py ├── Principle.py ├── Refactor.py └── SRP.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # user custome 29 | .idea/ 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | 52 | # Translations 53 | *.mo 54 | *.pot 55 | 56 | # Django stuff: 57 | *.log 58 | local_settings.py 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | docs/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # pyenv 77 | .python-version 78 | 79 | # celery beat schedule file 80 | celerybeat-schedule 81 | 82 | # SageMath parsed files 83 | *.sage.py 84 | 85 | # dotenv 86 | .env 87 | 88 | # virtualenv 89 | .venv 90 | venv/ 91 | ENV/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /Draft.py: -------------------------------------------------------------------------------- 1 | # class A(object): # -> don't forget the object specified as base 2 | # 3 | # def __new__(cls): 4 | # print("A.__new__ called") 5 | # return super(A, cls).__new__(cls) 6 | # # return 20 7 | # 8 | # def __init__(self): 9 | # print("A.__init__ called") 10 | # return 22 11 | # 12 | # print(A()) 13 | # 14 | # class B: 15 | # __instance = None 16 | # 17 | # def __new__(cls, name): 18 | # if cls.__instance is None: 19 | # cls.__instance = super().__new__(cls) 20 | # cls.name = name 21 | # return cls.__instance; 22 | # 23 | # def __init__(self, name): 24 | # self.name = name 25 | # 26 | # 27 | # # def get 28 | # 29 | # @classmethod 30 | # def getInstance(cls, name): 31 | # if B.__instance is None: 32 | # B.__instance = B(name) 33 | # return B.__instance 34 | # 35 | # # b1 = B("B1") 36 | # # print("id:", id(b1), " name:", b1.name) 37 | # # b2 = B("B2") 38 | # # print("id:", id(b2), " name:", b2.name) 39 | # 40 | # # b = B("B") 41 | 42 | 43 | 44 | class Foobar(object): 45 | # pass 46 | def __init__(self, name): 47 | self.name = name 48 | 49 | print( type(Foobar) ) 50 | print(Foobar) 51 | foo = Foobar("Test") 52 | print( type(foo) ) 53 | print(foo.name) 54 | foo2 = type(foo)("Text2") 55 | print(foo2.name) 56 | # print("Hello") 57 | print(isinstance(foo, Foobar)) 58 | print(isinstance(Foobar, type)) 59 | print(isinstance(Foobar, object)) 60 | 61 | 62 | 63 | MyClass = type('MyClass', (), {}) 64 | print(MyClass) 65 | 66 | # T = type 67 | print(type("Test", (), {})) 68 | 69 | 70 | # class MetaAAA(type): 71 | # pass 72 | # # def __prepare__(metacls, name, bases): 73 | # # pass 74 | # 75 | # 76 | # print(MetaAAA) 77 | # 78 | # 79 | # class MyClassA(metaclass=MetaAAA): 80 | # pass 81 | # 82 | # def test(self): 83 | # b = 5 84 | # b = True 85 | # 86 | # print(type(MyClassA)) 87 | # 88 | # 89 | # 90 | # print("=====================") 91 | # class B: 92 | # pass 93 | # 94 | # class C(B): 95 | # pass 96 | # 97 | # c = C() 98 | # print(C.__bases__) 99 | # 100 | # 101 | # print("Base===============") 102 | # print(object.__bases__) 103 | # print(type.__bases__) 104 | # print(type(object)) 105 | # print(object.__class__) 106 | # print(type(C)) 107 | # print(C.__class__) 108 | # 109 | # print("Callable:") 110 | # print(callable(type)) 111 | # print(callable(object)) 112 | # print(type(object)) 113 | # 114 | # 115 | # print("DD====================") 116 | # class DD: 117 | # 118 | # def __call__(self, *args, **kwargs): 119 | # print("DD.__call__") 120 | # # print(args) 121 | # return self.__class__ 122 | # 123 | # def __init__(self, name): 124 | # self.name = name 125 | # # 126 | # # d = DD() 127 | # # d("This is test") 128 | # # DD("This is test") 129 | # # id(d) 130 | # 131 | # # DD = DD() 132 | # # DD("This is test") 133 | # d = DD("Test") 134 | # print(d) 135 | # print(d.name) 136 | # print(callable(DD)) 137 | # print(callable(d)) 138 | callable() 139 | 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Description of PyDesignPattern 2 | 3 | ## English 4 | This is the source ocde of [ *Everybody Know Design Patterns : How to comprehend Design Patterns from daily life* ](https://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3). 5 | 6 | ## 中文 7 | 这是《人人都懂设计模式:从生活中领悟设计模式(Python实现)》一书的源码。可通过线上课程[如何从生活中领悟设计模式(Python)](https://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3) 进行试读。 8 | 9 | 设计模式(Design pattern)是一套被反复使用、多数人知晓的、无数工程师实践的代码设计经验的总结,它是面向对象思想的高度提炼和模板化。使用设计模式将会使你的代码具有更高的可重用性,更好的灵活性和可拓展性,更易被人阅读和理解。 10 | 11 | 程序不应只是冷冰冰的代码,更应赋予它生活的乐趣和特殊的意义。本课程将会从生活的角度,在生活的每一个细节和故事中解读一个个设计模式。 **力求用最通俗的语言阐述最难懂的概念;用最简单的语法实现最复杂的逻辑;用最短小的代码写出最强悍的程序!** 希望能给您带来一种全新的阅读体验和思考方式。 12 | 13 | 此升级版的系列分三部分内容:(1). 基础篇,19种常用设计模式单独章节讲解 + 剩余4种模式合集(会有1到2篇的篇幅);(2). 进阶篇,是基础设计模式的衍生,也是各大编程语言中非常重要而常见的种编程机制;(3). 经验篇,将会分享我对设计原则、设计模式、项目重构的经验和看法。 14 | 15 | ## 书籍 16 | [京东购买](https://item.jd.com/12580392.html)、[当当购买](http://product.dangdang.com/27848931.html) 17 | 18 | ![书籍介绍](./docs/EverybodyKnowsDesgnPatterns.jpg) 19 | 20 | ## 线上课程 21 | 22 | ### 引导篇 23 | [生活中的设计模式——启程之前,请不要错过我【试读】](http://gitbook.cn/gitchat/column/5a1c24de28554541fbc8f2e8/topic/5a1f8857211fa435d2b9ca6c) 24 | 25 | ### 基础篇 26 | 27 | [生活中的监听模式——一坑爹的热水器](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3/topic/5b2604a8c81ac568fcf64ef1) 28 | pattern/Observer.py 29 | 30 | [生活中的适配模式——身高不够鞋来凑](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3/topic/5b26052ec81ac568fcf64f20) 31 | pattern/Adapter.py 32 | 33 | [生活中的状态模式——人有少、壮、老, 水之冰、液、汽](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 34 | pattern/State.py 35 | 36 | [生活中的单例模式——你是我生命的唯一](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 37 | pattern/Singleton.py 38 | 39 | [生活中的职责模式——我的假条去哪了](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 40 | pattern/Responsibility.py 41 | 42 | [生活中的中介模式——找房子问中介](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 43 | pattern/Mediator.py 44 | 45 | [生活中的代理模式——帮我拿一下快递](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 46 | pattern/Proxy.py 47 | 48 | [生活中的装饰模式——你想怎么穿就怎么穿](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 49 | pattern/Decorator.py 50 | 51 | [生活中的工厂模式——你要拿铁还是摩卡](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 52 | pattern/SimpleFactory.py 53 | 54 | [生活中的迭代模式——下一个就是你了](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 55 | pattern/Iterator.py 56 | 57 | [生活中的组合模式——自己电脑组装,价格再降三折](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 58 | pattern/Composite.py 59 | 60 | [生活中的构建模式——你想要一辆车还是一座房](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 61 | pattern/Builder.py 62 | 63 | [生活中的克隆模式——给你一个分身术](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 64 | pattern/Clone.py 65 | 66 | [生活中的策略模式——怎么来不重要,人到就行](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 67 | pattern/Strategy.py 68 | 69 | [生活中的命令模式——大闸蟹,走起!](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 70 | pattern/Command.py 71 | 72 | [生活中的备忘模式——好记性不如烂笔头](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 73 | pattern/Memento.py 74 | 75 | [生活中的享元模式——颜料很贵必须充分利用](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 76 | pattern/Flyweight.py 77 | 78 | [生活中的外观模式——学妹别慌,学长帮你](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 79 | pattern/Facade.py 80 | 81 | [生活中的访问模式——一千个读者一千个哈姆雷特](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 82 | pattern/Visitor.py 83 | 84 | [生活中的设计模式——与经典23种设计模式的不解渊源](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 85 | 86 | [生活中的设计模式——那些未完待续的设计模式](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 87 | pattern/Template.py 88 | 89 | ### 进阶篇 90 | [深入解读过滤器模式——制作一杯鲜纯细腻的豆浆](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 91 | advanced_pattern/Filter.py 92 | 93 | [深入解读对象池技术——共享让生活更便捷](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 94 | advanced_pattern/ObjectPool.py 95 | 96 | [深入解读回调机制——把你技能亮出来](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 97 | advanced_pattern/Callback.py 98 | 99 | ### 经验篇 100 | [谈谈我对设计模式的理解](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 101 | 102 | [谈谈我对设计原则的思考](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 103 | 104 | [谈谈我对项目重构的看法](http://gitbook.cn/gitchat/column/5b26040ac81ac568fcf64ea3#catalog) 105 | -------------------------------------------------------------------------------- /StartPython.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 11/21/2017 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | def testDataType(): 8 | age = 18 # int 9 | weight = 62.51 # float 10 | isAdult = True # bool,只有True和False两个枚举值 11 | name = "Tony" # string 12 | print("age:", age, " type:", type(age)) 13 | print("weight:", weight, " type:", type(weight)) 14 | print("isAdult:", isAdult, " type:", type(isAdult)) 15 | print("name:", name, " type:", type(name)) 16 | 17 | # 变量的类型可以直接改变 18 | age = name 19 | print("age:", age) 20 | 21 | a = b = c = 5 22 | # a,b,c三个变量指向相同的内存空间,具有相同的值 23 | print("a:", a, "b:", b, "c:", c) 24 | print("id(a):", id(a), "id(b):", id(b), "id(c):", id(c)) 25 | 26 | 27 | def testList(): 28 | list1 = ['Thomson', 78, 12.58, 'Sunny', 180.2] 29 | list2 = [123, 'Tony'] 30 | print("list1:", list1) # 输出完整列表 31 | print("list1[0]:", list1[0]) # 输出列表的第一个元素 32 | print("list1[1:3]:", list1[1:3]) # 输出第二个至第三个元素 33 | print("list1[2:]:", list1[2:]) # 输出从第三个开始至列表末尾的所有元素 34 | print("list2 * 2 :", list2 * 2) # 输出列表两次 35 | print("list1 + list2 :", list1 + list2) # 打印组合的列表 36 | list1[1] = 100 37 | print("设置list[1]:", list1) # 输出完整列表 38 | list1.append("added data") 39 | print("list添加元素:", list1) # 输出增加后的列表 40 | 41 | 42 | def testTuple(): 43 | tp1 = ('Thomson', 78, 12.58, 'Sunny', 180.2) 44 | tp2 = (123, 'Tony') 45 | print("tp1:", tp1) # 输出完整元组 46 | print("tp2:", tp2) # 输出完整元组 47 | print("tp1[0]:", tp1[0]) # 输出元组的第一个元素 48 | print("tp1[1:3]:", tp1[1:3]) # 输出第二个至第三个的元素 49 | print("tp1[2:]:", tp1[2:]) # 输出从第三个开始至列表末尾的所有元素 50 | print("tp2 * 2:", tp2 * 2) # 输出元组两次 51 | print("tp1 + tp2:", tp1 + tp2) # 打印组合的元组 52 | # tp1[1] = 100 # 不能修改元组内的元素 53 | 54 | 55 | def testDictionary(): 56 | dict1 = {} 57 | dict1['one'] = "This is one" 58 | dict1[2] = "This is two" 59 | dict2 = {'name': 'Tony', 'age': 24, 'height': 177} 60 | 61 | print("dict1:", dict1) 62 | print("dict1['one']:", dict1['one']) # 输出键为'one' 的值 63 | print("dict1[2]:", dict1[2]) # 输出键为 2 的值 64 | print("dict2:", dict2) # 输出完整的字典 65 | print("dict2.keys():", dict2.keys()) # 输出所有键 66 | print("dict2.values():", dict2.values()) # 输出所有值 67 | 68 | 69 | def testSet(): 70 | friuts = {"apple", "orange", "strawberry", "banana", "apple", "strawberry"} 71 | print("friuts:", friuts) 72 | print("type of friuts:", type(friuts)) 73 | arr = [1, 2, 3, 4, 5, 1] 74 | numbers = set(arr) 75 | print("numbers:", numbers) 76 | friuts.add(1) 77 | print("numbers add 1:", numbers) 78 | 79 | class Test: 80 | "这是一个测试类" 81 | 82 | def __init__(self): 83 | self.__ivalue = 5 84 | 85 | def getvalue(self): 86 | return self.__ivalue 87 | 88 | def testClass(): 89 | t = Test() 90 | print(t.getvalue()) 91 | 92 | 93 | class Person: 94 | "人" 95 | visited = 0 96 | 97 | def __init__(self, name, age, height): 98 | self.__name = name # 私有成员,访问权限为private 99 | self._age = age # 保护成员,访问权限为protected 100 | self.height = height # 公有成员,访问权限为public 101 | 102 | def getName(self): 103 | return self.__name 104 | 105 | def getAge(self): 106 | return self._age 107 | 108 | def showInfo(self): 109 | print("name:", self.__name) 110 | print("age:", self._age) 111 | print("height:", self.height) 112 | print("visited:", self.visited) 113 | Person.visited = Person.visited +1 114 | 115 | class Teacher(Person): 116 | "老师" 117 | 118 | def __init__(self, name, age, height): 119 | super().__init__(name, age, height) 120 | self.__title = None 121 | 122 | def getTitle(self): 123 | return self.__title 124 | 125 | def setTitle(self, title): 126 | self.__title = title 127 | 128 | def showInfo(self): 129 | print("title:", self.__title) 130 | super().showInfo() 131 | 132 | 133 | def testPerson(): 134 | "测试方法" 135 | tony = Person("Tony", 25, 1.77) 136 | tony.showInfo() 137 | print() 138 | 139 | jenny = Teacher("Jenny", 34, 1.68) 140 | jenny.setTitle("教授") 141 | jenny.showInfo() 142 | 143 | 144 | # testDataType() 145 | testList() 146 | # testTuple() 147 | # testDictionary() 148 | # testSet() 149 | # testClass() 150 | 151 | # testPerson() -------------------------------------------------------------------------------- /Test.py: -------------------------------------------------------------------------------- 1 | ##!/usr/bin/python 2 | 3 | #//////////////////////////////////////////////////////////////////////////// 4 | import StartPython 5 | 6 | # import pattern.Observer 7 | # import pattern.State 8 | # import pattern.Singleton 9 | # import pattern.Responsibility 10 | # import pattern.Proxy 11 | # import pattern.Mediator 12 | # import pattern.Decorator 13 | # import pattern.SimpleFactory 14 | # import pattern.Iterator 15 | # import pattern.Composite 16 | # import pattern.Clone 17 | # import pattern.Builder 18 | # import pattern.Adapter 19 | # import pattern.Strategy 20 | # import pattern.Command 21 | # import pattern.Memento 22 | # import pattern.Flyweight 23 | # import pattern.Facade 24 | # import pattern.Visitor 25 | # import pattern.Template 26 | # import pattern.Bridge 27 | # import pattern.Interpreter 28 | 29 | # import advanced_pattern.Filter 30 | # import advanced_pattern.ObjectPool 31 | # import advanced_pattern.Callback 32 | 33 | # import application.ImageProcessing 34 | # import application.GameCommand 35 | # import application.TerminalMonitor 36 | 37 | # import principle.Principle 38 | 39 | # import Draft 40 | # import advanced_programming.MagicMethod 41 | # import advanced_programming.Metaclass -------------------------------------------------------------------------------- /advanced_pattern/Callback.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 7/21/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | 8 | class Employee: 9 | """公司员工""" 10 | 11 | def __init__(self, name): 12 | self.__name = name 13 | 14 | def doPerformance(self, skill): 15 | print(self.__name + "的表演:", end="") 16 | skill() 17 | 18 | 19 | def sing(): 20 | """唱歌""" 21 | print("唱一首歌") 22 | 23 | def dling(): 24 | """拉Ukulele""" 25 | print("拉一曲Ukulele") 26 | 27 | def joke(): 28 | """说段子""" 29 | print("说一搞笑段子") 30 | 31 | def performMagicTricks(): 32 | """表演魔术""" 33 | print("神秘魔术") 34 | 35 | def skateboarding(): 36 | """玩滑板""" 37 | print("酷炫滑板") 38 | 39 | 40 | # Version 2.0 41 | #======================================================================================================================= 42 | # 代码框架1:面向过程的实现方式 43 | #============================== 44 | def callback(*args, **kwargs): 45 | """回调函数""" 46 | # todo 函数体的实现 47 | 48 | 49 | def otherFun(fun, *args, **kwargs): 50 | """高阶函数,也叫包含函数""" 51 | # todo 函数体的实现 52 | 53 | # 函数的调用方式 54 | otherFun(callable) 55 | 56 | 57 | # 代码框架2:面向对象的实现方式 58 | #============================== 59 | from abc import ABCMeta, abstractmethod 60 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 61 | 62 | class Strategy(metaclass=ABCMeta): 63 | """算法的抽象类""" 64 | 65 | @abstractmethod 66 | def algorithm(self, *args, **kwargs): 67 | """定义算法""" 68 | pass 69 | 70 | class StrategyA(Strategy): 71 | """策略A""" 72 | 73 | def algorithm(self, *args, **kwargs): 74 | print("算法A的实现...") 75 | 76 | class StrategyB(Strategy): 77 | """策略B""" 78 | 79 | def algorithm(self, *args, **kwargs): 80 | print("算法B的实现...") 81 | 82 | class Context: 83 | """上下文环境类""" 84 | 85 | def interface(self, strategy, *args, **kwargs): 86 | """交互接口""" 87 | print("回调执行前的操作") 88 | strategy.algorithm() 89 | print("回调执行后的操作") 90 | 91 | # # 调用方式 92 | # context = Context() 93 | # context.interface(StrategyA()) 94 | # context.interface(StrategyB()) 95 | 96 | 97 | # 基于框架的实现1 98 | #============================== 99 | def isEvenNumber(num): 100 | return num % 2 == 0 101 | 102 | def isGreaterThanTen(num): 103 | return num > 10 104 | 105 | def getResultNumbers(fun, elements): 106 | newList = [] 107 | for item in elements: 108 | if (fun(item)): 109 | newList.append(item) 110 | return newList 111 | 112 | 113 | # 基于框架的实现2 114 | #============================== 115 | from abc import ABCMeta, abstractmethod 116 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 117 | 118 | class Skill(metaclass=ABCMeta): 119 | """技能的抽象类""" 120 | 121 | @abstractmethod 122 | def performance(self): 123 | """技能表演""" 124 | pass 125 | 126 | class NewEmployee: 127 | """公司新员工""" 128 | 129 | def __init__(self, name): 130 | self.__name = name 131 | 132 | def doPerformance(self, skill): 133 | print(self.__name + "的表演:", end="") 134 | skill.performance() 135 | 136 | class Sing(Skill): 137 | """唱歌""" 138 | def performance(self): 139 | print("唱一首歌") 140 | 141 | class Joke(Skill): 142 | """说段子""" 143 | def performance(self): 144 | print("说一搞笑段子") 145 | 146 | class Dling(Skill): 147 | """拉Ukulele""" 148 | def performance(self): 149 | print("拉一曲Ukulele") 150 | 151 | class PerformMagicTricks(Skill): 152 | """表演魔术""" 153 | def performance(self): 154 | print("神秘魔术") 155 | 156 | class Skateboarding(Skill): 157 | """玩滑板""" 158 | def performance(self): 159 | print("酷炫滑板") 160 | 161 | 162 | # 回调在异步中的应用 163 | # ======================================================================================================================= 164 | import requests 165 | # 引入Http请求模块 166 | from threading import Thread 167 | # 引入线程模块 168 | 169 | class DownloadThread (Thread): 170 | """下载文件的线程""" 171 | 172 | # 每次写文件的缓冲大小 173 | CHUNK_SIZE = 1024 * 512 174 | 175 | def __init__(self, fileName, url, savePath, callBackProgerss, callBackFinished): 176 | super().__init__() 177 | self.__fileName = fileName 178 | self.__url = url 179 | self.__savePath = savePath 180 | self.__callbackProgress = callBackProgerss 181 | self.__callBackFionished = callBackFinished 182 | 183 | def run(self): 184 | readSize = 0 185 | r = requests.get(self.__url, stream=True) 186 | totalSize = int(r.headers.get('Content-Length')) 187 | print("[下载%s] 文件大小:%d" % (self.__fileName, totalSize)) 188 | with open(self.__savePath, "wb") as file: 189 | for chunk in r.iter_content(chunk_size = self.CHUNK_SIZE): 190 | if chunk: 191 | file.write(chunk) 192 | readSize += self.CHUNK_SIZE 193 | self.__callbackProgress(self.__fileName, readSize, totalSize) 194 | self.__callBackFionished(self.__fileName) 195 | 196 | 197 | 198 | # Test 199 | #======================================================================================================================= 200 | 201 | def testSkill(): 202 | helen = Employee("Helen") 203 | helen.doPerformance(sing) 204 | frank = Employee("Frank") 205 | frank.doPerformance(dling) 206 | jacky = Employee("Jacky") 207 | jacky.doPerformance(joke) 208 | chork = Employee("Chork") 209 | chork.doPerformance(performMagicTricks) 210 | Kerry = Employee("Kerry") 211 | Kerry.doPerformance(skateboarding) 212 | 213 | def testStrategySkill(): 214 | helen = NewEmployee("Helen") 215 | helen.doPerformance(Sing()) 216 | frank = NewEmployee("Frank") 217 | frank.doPerformance(Dling()) 218 | jacky = NewEmployee("Jacky") 219 | jacky.doPerformance(Joke()) 220 | chork = NewEmployee("Chork") 221 | chork.doPerformance(PerformMagicTricks()) 222 | Kerry = NewEmployee("Kerry") 223 | Kerry.doPerformance(Skateboarding()) 224 | 225 | 226 | def testCallback(): 227 | elements = [2, 3, 6, 9, 12, 15, 18] 228 | list1 = getResultNumbers(isEvenNumber, elements) 229 | list2 = getResultNumbers(isGreaterThanTen, elements) 230 | print("所有的偶数:", list1) 231 | print("大于10的数:", list2) 232 | 233 | def testFilter(): 234 | elements = [2, 3, 6, 9, 12, 15, 18] 235 | list1 = list(filter(lambda x: x % 2 == 0, elements)) 236 | list2 = list(filter(lambda x: x > 10, elements)) 237 | print("所有的偶数:", list1) 238 | print("大于10的数:", list2) 239 | 240 | 241 | 242 | 243 | def testDownload(): 244 | def downloadProgress(fileName, readSize, totalSize): 245 | """定义下载进度的回调函数""" 246 | percent = (readSize / totalSize) * 100 247 | print("[下载%s] 下载进度:%.2f%%" % (fileName, percent)) 248 | 249 | def downloadFinished(fileName): 250 | """定义下载完成后的回调函数""" 251 | print("[下载%s] 文件下载完成!" % fileName) 252 | 253 | print("开始下载TestForDownload1.pdf......") 254 | downloadUrl1 = "http://pe9hg91q8.bkt.clouddn.com/TestForDownload1.pdf" 255 | download1 = DownloadThread("TestForDownload1", downloadUrl1, "./download/TestForDownload1.pdf", downloadProgress, 256 | downloadFinished) 257 | download1.start() 258 | print("开始下载TestForDownload2.zip......") 259 | downloadUrl2 = "http://pe9hg91q8.bkt.clouddn.com/TestForDownload2.zip" 260 | download2 = DownloadThread("TestForDownload2", downloadUrl2, "./download/TestForDownload2.zip", downloadProgress, 261 | downloadFinished) 262 | download2.start() 263 | print("执行其它的任务......") 264 | 265 | 266 | # testSkill() 267 | # testStrategySkill() 268 | # testCallback() 269 | # testFilter() 270 | 271 | 272 | testDownload() 273 | -------------------------------------------------------------------------------- /advanced_pattern/Filter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 7/15/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | # class FilterScreen: 8 | # """过滤网""" 9 | # 10 | # def doFilter(self, rawMaterials): 11 | # for material in rawMaterials: 12 | # if (material == "豆渣"): 13 | # rawMaterials.remove(material) 14 | # return rawMaterials 15 | 16 | 17 | # Version 2.0 18 | #======================================================================================================================= 19 | # 代码框架 20 | #============================== 21 | from abc import ABCMeta, abstractmethod 22 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 23 | 24 | class Filter(metaclass=ABCMeta): 25 | """过滤器""" 26 | 27 | @abstractmethod 28 | def doFilter(self, elements): 29 | """过滤方法""" 30 | pass 31 | 32 | 33 | class FilterChain(Filter): 34 | """过滤器链""" 35 | 36 | def __init__(self): 37 | self._filters = [] 38 | 39 | def addFilter(self, filter): 40 | self._filters.append(filter) 41 | 42 | def removeFilter(self, filter): 43 | self._filters.remove(filter) 44 | 45 | def doFilter(self, elements): 46 | for filter in self._filters: 47 | elements = filter.doFilter(elements) 48 | return elements 49 | 50 | 51 | # 基于框架的实现 52 | #============================== 53 | class FilterScreen(Filter): 54 | """过滤网""" 55 | 56 | def doFilter(self, elements): 57 | for material in elements: 58 | if (material == "豆渣"): 59 | elements.remove(material) 60 | return elements 61 | 62 | 63 | import re 64 | # 引入正则表达式库 65 | 66 | class SensitiveFilter(Filter): 67 | """敏感词过滤""" 68 | 69 | def __init__(self): 70 | self.__sensitives = ["黄色", "台独", "贪污"] 71 | 72 | def doFilter(self, elements): 73 | # 敏感词列表转换成正则表达式 74 | regex = "" 75 | for word in self.__sensitives: 76 | regex += word + "|" 77 | regex = regex[0: len(regex) - 1] 78 | 79 | # 对每个元素进行过滤 80 | newElements = [] 81 | for element in elements: 82 | item, num = re.subn(regex, "", element) 83 | newElements.append(item) 84 | 85 | return newElements 86 | 87 | 88 | class HtmlFilter(Filter): 89 | """HTML特殊字符转换""" 90 | 91 | def __init__(self): 92 | self.__wordMap = { 93 | "&": "&", 94 | "'": " '", 95 | ">": ">", 96 | "<": "<", 97 | "\"": " "", 98 | } 99 | 100 | def doFilter(self, elements): 101 | newElements = [] 102 | for element in elements: 103 | for key, value in self.__wordMap.items(): 104 | element = element.replace(key, value) 105 | newElements.append(element) 106 | return newElements 107 | 108 | 109 | # Test 110 | #======================================================================================================================= 111 | 112 | def testFilterScreen(): 113 | rawMaterials = ["豆浆", "豆渣"] 114 | print("过滤前:", rawMaterials) 115 | filter = FilterScreen() 116 | filteredMaterials = filter.doFilter(rawMaterials) 117 | print("过滤后:",filteredMaterials) 118 | 119 | 120 | 121 | def testFilter(): 122 | rawMaterials = ["豆浆", "豆渣"] 123 | print("过滤前:", rawMaterials) 124 | filteredMaterials = list(filter(lambda material: material == "豆浆", rawMaterials)) 125 | print("过滤后:", filteredMaterials) 126 | 127 | def isSoybeanMilk(material): 128 | return material == "豆浆" 129 | 130 | 131 | 132 | def testFiltercontent(): 133 | contents = [ 134 | '有人出售黄色书:<黄情味道>', 135 | '有人企图搞台独活动, ——"造谣咨询"', 136 | ] 137 | print("过滤前的内容:", contents) 138 | filterChain = FilterChain() 139 | filterChain.addFilter(SensitiveFilter()) 140 | filterChain.addFilter(HtmlFilter()) 141 | newContents = filterChain.doFilter(contents) 142 | print("过滤后的内容:", newContents) 143 | 144 | 145 | # testFilterScreen() 146 | # testFilter() 147 | testFiltercontent() 148 | -------------------------------------------------------------------------------- /advanced_pattern/MVC.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 12/08/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | import random 8 | # 引入随机数模块 9 | 10 | class Camera: 11 | """相机机身""" 12 | 13 | # 对焦类型 14 | SingleFocus = "单点对焦" 15 | AreaFocus = "区域对焦" 16 | BigAreaFocus = "大区域对焦" 17 | Focus45 = "45点自动对焦" 18 | 19 | def __init__(self, name): 20 | self.__name = name 21 | self.__aperture = 0.0 # 光圈 22 | self.__shutterSpeed = 0 # 快门速度 23 | self.__ligthSensitivity = 0 # 感光度 24 | self.__lens = Lens() # 镜头 25 | self.__sdCard = SDCard() # SD卡 26 | self.__display = Display() # 显示器 27 | 28 | def shooting(self): 29 | """拍照""" 30 | print("[开始拍摄中") 31 | imageLighting = self.__lens.collecting() 32 | # 通过快门、光圈和感光度、测光来控制拍摄的过程,省略此部分 33 | image = self.__transferImage(imageLighting) 34 | self.__sdCard.addImage(image) 35 | print("拍摄完成]") 36 | 37 | def viewImage(self, index): 38 | """查看图像""" 39 | print("查看第%d张图像:" % (index + 1)) 40 | image = self.__sdCard.getImage(index) 41 | self.__display.showImage(image) 42 | 43 | def __transferImage(self, imageLighting): 44 | """接收光线并处理成数字信号,简单模拟""" 45 | print("接收光线并处理成数字信号") 46 | return Image(6000, 4000, imageLighting) 47 | 48 | def setting(self, aperture, shutterSpeed, ligthSensitivity): 49 | """设置相机的拍摄属性:光圈、快门、感光度""" 50 | self.__aperture = aperture 51 | self.__shutterSpeed = shutterSpeed 52 | self.__ligthSensitivity = ligthSensitivity 53 | 54 | def focusing(self, focusMode): 55 | """对焦,要通过镜头来调节焦点""" 56 | self.__lens.setFocus(focusMode) 57 | 58 | def showInfo(self): 59 | """显示相机的属性""" 60 | print("%s的设置 光圈:F%0.1f 快门:1/%d 感光度:ISO %d" % 61 | (self.__name, self.__aperture, self.__shutterSpeed, self.__ligthSensitivity)) 62 | 63 | 64 | class Lens: 65 | """镜头""" 66 | 67 | def __init__(self): 68 | self.__focusMode = '' # 对焦 69 | self.__scenes = {0 : '风光', 1 : '生态', 2 : '人文', 3 : '纪实', 4 : '人像', 5 : '建筑'} 70 | 71 | def setFocus(self, focusMode): 72 | self.__focusMode = focusMode 73 | 74 | def collecting(self): 75 | """图像采集,采用随机的方式来模拟自然的拍摄过程""" 76 | print("采集光线,%s" % self.__focusMode) 77 | index = random.randint(0, len(self.__scenes)-1) 78 | scens = self.__scenes[index] 79 | return "美丽的 " + scens + " 图像" 80 | 81 | 82 | class Display: 83 | """显示器""" 84 | 85 | def showImage(self, image): 86 | print("图片大小:%d x %d, 图片内容:%s" % (image.getWidth(), image.getHeight(), image.getPix())) 87 | 88 | 89 | class SDCard: 90 | """SD存储卡""" 91 | 92 | def __init__(self): 93 | self.__images = [] 94 | 95 | def addImage(self, image): 96 | print("存储图像") 97 | self.__images.append(image) 98 | 99 | def getImage(self, index): 100 | if (index >= 0 and index < len(self.__images)): 101 | return self.__images[index] 102 | else: 103 | return None 104 | 105 | 106 | class Image: 107 | """图像(图片), 方便起见用字符串来代码图像的内容(像素)""" 108 | 109 | def __init__(self, width, height, pixels): 110 | self.__width = width 111 | self.__height = height 112 | self.__pixels = pixels 113 | 114 | def getWidth(self): 115 | return self.__width 116 | 117 | def getHeight(self): 118 | return self.__height 119 | 120 | def getPix(self): 121 | return self.__pixels 122 | 123 | 124 | # Version 2.0 125 | #======================================================================================================================= 126 | # 代码框架 127 | #============================== 128 | 129 | # 基于框架的实现 130 | #============================== 131 | 132 | 133 | # Test 134 | #======================================================================================================================= 135 | def testCamera(): 136 | camera = Camera("EOS 80D") 137 | camera.setting(3.5, 60, 200) 138 | camera.showInfo() 139 | camera.focusing(Camera.BigAreaFocus) 140 | camera.shooting() 141 | print() 142 | 143 | camera.setting(5.6, 720, 100) 144 | camera.showInfo() 145 | camera.focusing(Camera.Focus45) 146 | camera.shooting() 147 | print() 148 | 149 | camera.viewImage(0) 150 | camera.viewImage(1) 151 | 152 | 153 | testCamera() -------------------------------------------------------------------------------- /advanced_pattern/ObjectPool.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 5/27/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | # class PowerBank: 8 | # """移动电源""" 9 | # 10 | # def __init__(self, serialNum, electricQuantity): 11 | # self.__serialNum = serialNum 12 | # self.__electricQuantity = electricQuantity 13 | # self.__user = "" 14 | # 15 | # def getSerialNum(self): 16 | # return self.__serialNum 17 | # 18 | # def getElectricQuantity(self): 19 | # return self.__electricQuantity 20 | # 21 | # def setUser(self, user): 22 | # self.__user = user 23 | # 24 | # def getUser(self): 25 | # return self.__user 26 | # 27 | # def showInfo(self): 28 | # print("序列号:%s 电量:%d%% 使用者:%s" % (self.__serialNum, self.__electricQuantity, self.__user) ) 29 | 30 | 31 | class ObjectPack: 32 | """对象的包装类 33 | 封装指定的对象(如充电宝)是否被使用中""" 34 | def __init__(self, obj, inUsing = False): 35 | self.__obj = obj 36 | self.__inUsing = inUsing 37 | 38 | def inUsing(self): 39 | return self.__inUsing 40 | 41 | def setUsing(self, isUsing): 42 | self.__inUsing = isUsing 43 | 44 | def getObj(self): 45 | return self.__obj 46 | 47 | 48 | class PowerBankBox: 49 | """存放移动电源的智能箱盒""" 50 | 51 | def __init__(self): 52 | self.__pools = {} 53 | self.__pools["0001"] = ObjectPack(PowerBank("0001", 100)) 54 | self.__pools["0002"] = ObjectPack(PowerBank("0002", 100)) 55 | 56 | def borrow(self, serialNum): 57 | """借用移动电源""" 58 | item = self.__pools.get(serialNum) 59 | result = None 60 | if(item is None): 61 | print("没有可用的电源!") 62 | elif(not item.inUsing()): 63 | item.setUsing(True) 64 | result = item.getObj() 65 | else: 66 | print("%s电源 已被借用!" % serialNum) 67 | return result 68 | 69 | def giveBack(self, serialNum): 70 | """归还移动电源""" 71 | item = self.__pools.get(serialNum) 72 | if(item is not None): 73 | item.setUsing(False) 74 | print("%s电源 已归还!" % serialNum) 75 | 76 | 77 | # Version 2.0 78 | #======================================================================================================================= 79 | # 代码框架 80 | #============================== 81 | from abc import ABCMeta, abstractmethod 82 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 83 | import logging 84 | # 引入logging模块用于输出日志信息 85 | import time 86 | # 引入时间模块 87 | logging.basicConfig(level=logging.INFO) 88 | # 如果想在控制台打印INFO以上的信息,则加上此配制 89 | 90 | class PooledObject: 91 | """池对象,也称池化对象""" 92 | 93 | def __init__(self, obj): 94 | self.__obj = obj 95 | self.__busy = False 96 | 97 | def getObject(self): 98 | return self.__obj 99 | 100 | def setObject(self, obj): 101 | self.__obj = obj 102 | 103 | def isBusy(self): 104 | return self.__busy 105 | 106 | def setBusy(self, busy): 107 | self.__busy = busy 108 | 109 | 110 | class ObjectPool(metaclass=ABCMeta): 111 | """对象池""" 112 | 113 | """对象池初始化大小""" 114 | InitialNumOfObjects = 10 115 | """对象池最大的大小""" 116 | MaxNumOfObjects = 50 117 | 118 | def __init__(self): 119 | self.__pools = [] 120 | for i in range(0, ObjectPool.InitialNumOfObjects): 121 | obj = self.createPooledObject() 122 | self.__pools.append(obj) 123 | 124 | @abstractmethod 125 | def createPooledObject(self): 126 | """创建池对象, 由子类实现该方法""" 127 | pass 128 | 129 | def borrowObject(self): 130 | """借用对象""" 131 | # 如果找到空闲对象,直接返回 132 | obj = self._findFreeObject() 133 | if(obj is not None): 134 | logging.info("%x对象已被借用, time:%s", id(obj), 135 | time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())) ) 136 | return obj 137 | # 如果对象池未满,则添加新的对象 138 | if(len(self.__pools) < ObjectPool.MaxNumOfObjects): 139 | pooledObj = self.addObject() 140 | if (pooledObj is not None): 141 | pooledObj.setBusy(True) 142 | logging.info("%x对象已被借用, time:%s", id(obj), 143 | time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))) 144 | return pooledObj.getObject() 145 | # 对象池已满且没有空闲对象,则返回None 146 | return None 147 | 148 | def returnObject(self, obj): 149 | """归还对象""" 150 | for pooledObj in self.__pools: 151 | if(pooledObj.getObject() == obj): 152 | pooledObj.setBusy(False) 153 | logging.info("%x对象已归还, time:%s", id(obj), 154 | time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))) 155 | break 156 | 157 | def addObject(self): 158 | """添加新对象""" 159 | obj = None 160 | if(len(self.__pools) < ObjectPool.MaxNumOfObjects): 161 | obj = self.createPooledObject() 162 | self.__pools.append(obj) 163 | logging.info("添加新对象%x, time:", id(obj), 164 | time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))) 165 | return obj 166 | 167 | def clear(self): 168 | """清空对象池""" 169 | self.__pools.clear() 170 | 171 | def _findFreeObject(self): 172 | """查找空闲的对象""" 173 | obj = None 174 | for pooledObj in self.__pools: 175 | if(not pooledObj.isBusy()): 176 | obj = pooledObj.getObject() 177 | pooledObj.setBusy(True) 178 | break 179 | return obj 180 | 181 | 182 | # 基于框架的实现 183 | #============================== 184 | class PowerBank: 185 | """移动电源""" 186 | 187 | def __init__(self, serialNum, electricQuantity): 188 | self.__serialNum = serialNum 189 | self.__electricQuantity = electricQuantity 190 | self.__user = "" 191 | 192 | def getSerialNum(self): 193 | return self.__serialNum 194 | 195 | def getElectricQuantity(self): 196 | return self.__electricQuantity 197 | 198 | def setUser(self, user): 199 | self.__user = user 200 | 201 | def getUser(self): 202 | return self.__user 203 | 204 | def showInfo(self): 205 | print("序列号:%03d 电量:%d%% 使用者:%s" % (self.__serialNum, self.__electricQuantity, self.__user)) 206 | 207 | class PowerBankPool(ObjectPool): 208 | """存放移动电源的智能箱盒""" 209 | 210 | __serialNum = 0 211 | 212 | @classmethod 213 | def getSerialNum(cls): 214 | cls.__serialNum += 1 215 | return cls.__serialNum 216 | 217 | 218 | def createPooledObject(self): 219 | powerBank = PowerBank(PowerBankPool.getSerialNum(), 100) 220 | return PooledObject(powerBank) 221 | 222 | # Test 223 | #======================================================================================================================= 224 | def testPowerBank(): 225 | box = PowerBankBox() 226 | powerBank1 = box.borrow("0001") 227 | if(powerBank1 is not None): 228 | powerBank1.setUser("Tony") 229 | powerBank1.showInfo() 230 | powerBank2 = box.borrow("0002") 231 | if(powerBank2 is not None): 232 | powerBank2.setUser("Sam") 233 | powerBank2.showInfo() 234 | powerBank3 = box.borrow("0001") 235 | box.giveBack("0001") 236 | powerBank3 = box.borrow("0001") 237 | if(powerBank3 is not None): 238 | powerBank3.setUser("Aimee") 239 | powerBank3.showInfo() 240 | 241 | 242 | def testObjectPool(): 243 | powerBankPool = PowerBankPool() 244 | powerBank1 = powerBankPool.borrowObject() 245 | if (powerBank1 is not None): 246 | powerBank1.setUser("Tony") 247 | powerBank1.showInfo() 248 | powerBank2 = powerBankPool.borrowObject() 249 | if (powerBank2 is not None): 250 | powerBank2.setUser("Sam") 251 | powerBank2.showInfo() 252 | powerBankPool.returnObject(powerBank1) 253 | # powerBank1归还后,不能再对其进行相关操作 254 | powerBank3 = powerBankPool.borrowObject() 255 | if (powerBank3 is not None): 256 | powerBank3.setUser("Aimee") 257 | powerBank3.showInfo() 258 | 259 | powerBankPool.returnObject(powerBank2) 260 | powerBankPool.returnObject(powerBank3) 261 | powerBankPool.clear() 262 | 263 | # testPowerBank() 264 | testObjectPool() 265 | 266 | -------------------------------------------------------------------------------- /advanced_programming/Decorator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 9/24/2018 4 | 5 | # Python中的装饰器 6 | #======================================================================================================================= 7 | # Python中函数的特殊功能 8 | #============================== 9 | def func(num): 10 | """定义内部函数并返回""" 11 | 12 | def firstInnerFunc(): 13 | return "这是第一个内部函数" 14 | 15 | def secondInnerFunc(): 16 | return "这是第二个内部函数" 17 | 18 | if num == 1: 19 | return firstInnerFunc 20 | else: 21 | return secondInnerFunc 22 | 23 | 24 | # print(func(1)) 25 | # print(func(2)) 26 | # print(func(1)()) 27 | # print(func(2)()) 28 | 29 | 30 | # firstFunc = func(1) 31 | # secondFunc = func(2) 32 | # print(firstFunc) 33 | # print(secondFunc) 34 | # print(firstFunc()) 35 | # print(secondFunc()) 36 | 37 | 38 | # 装饰器修饰函数 39 | #============================== 40 | import logging 41 | logging.basicConfig(level=logging.INFO) 42 | 43 | def loggingDecorator(func): 44 | """记录日志的装饰器""" 45 | def wrapperLogging(*args, **kwargs): 46 | logging.info("开始执行 %s() ..." % func.__name__) 47 | func(*args, **kwargs) 48 | logging.info("%s() 执行完成!" % func.__name__) 49 | return wrapperLogging 50 | 51 | def showInfo(*args, **kwargs): 52 | print("这是一个测试函数,参数:", args, kwargs) 53 | 54 | 55 | # decoratedShowInfo = loggingDecorator(showInfo) 56 | # decoratedShowInfo('arg1', 'arg2', kwarg1 = 1, kwarg2 = 2) 57 | 58 | 59 | # def showMin(a, b): 60 | # print("%d、%d 中的最小值是:%d" % (a, b, a + b)) 61 | # 62 | # decoratedShowMin = loggingDecorator(showMin) 63 | # decoratedShowMin(2, 3) 64 | 65 | 66 | # @loggingDecorator 67 | # def showMin(a, b): 68 | # print("%d、%d 中的最小值是:%d" % (a, b, a + b)) 69 | # 70 | # showMin(2, 3) 71 | 72 | 73 | # 装饰器修饰类 74 | #============================== 75 | class ClassDecorator: 76 | """类装饰器,记录一个类被实例化的次数""" 77 | 78 | def __init__(self, func): 79 | self.__numOfCall = 0 80 | self.__func = func 81 | 82 | def __call__(self, *args, **kwargs): 83 | self.__numOfCall += 1 84 | obj = self.__func(*args, *kwargs) 85 | print("创建%s的第%d个实例:%s" % (self.__func.__name__, self.__numOfCall, id(obj))) 86 | return obj 87 | 88 | @ClassDecorator 89 | class MyClass: 90 | 91 | def __init__(self, name): 92 | self.__name = name 93 | 94 | def getName(self): 95 | return self.__name 96 | 97 | 98 | tony = MyClass("Tony") 99 | karry = MyClass("Karry") 100 | print(id(tony)) 101 | print(id(karry)) 102 | -------------------------------------------------------------------------------- /advanced_programming/MagicMethod.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 9/15/2018 4 | 5 | # ClassA 6 | #======================================================================================================================= 7 | # class ClassA: 8 | # def __new__(cls): 9 | # print("ClassA.__new__") 10 | # return super().__new__(cls) 11 | # 12 | # def __init__(self): 13 | # print("ClassA.__init__") 14 | # 15 | # def __call__(self, *args): 16 | # print("ClassA.__call__ args:", args) 17 | # 18 | # a = ClassA() 19 | # a("arg1", "arg2") 20 | 21 | # ClassB 22 | #======================================================================================================================= 23 | # class Sample(object): 24 | # def __str__(self): 25 | # return "SAMPLE" 26 | # 27 | # class ClassB: 28 | # 29 | # def __new__(cls): 30 | # print("ClassB.__new__") 31 | # return super().__new__(Sample) 32 | # # return Sample() # 也可以是这种写法 33 | # 34 | # def __init__(self): 35 | # print("ClassB.__init__") 36 | # 37 | # b = ClassB() 38 | # print(b) 39 | # print(type(b)) 40 | 41 | # ClassC 42 | #======================================================================================================================= 43 | # class ClassC: 44 | # def __init__(self, *args, **kwargs): 45 | # print("init", args, kwargs) 46 | # 47 | # def __new__(cls, *args, **kwargs): 48 | # print("new", args, kwargs) 49 | # return super().__new__(cls) 50 | # 51 | # c = ClassC("arg1", "arg2", a=1, b=2) 52 | 53 | 54 | 55 | # ClassD 56 | #======================================================================================================================= 57 | # class ClassD: 58 | # 59 | # def __new__(cls): 60 | # print("ClassB.__new__") 61 | # self = super().__new__(cls) 62 | # print(self) 63 | # return self 64 | # 65 | # def __init__(self): 66 | # print("ClassC.__init__") 67 | # print(self) 68 | # 69 | # d = ClassD() 70 | 71 | 72 | 73 | # Callable 74 | #======================================================================================================================= 75 | # def funTest(name): 76 | # print("This is test function, name:", name) 77 | # 78 | # print(callable(filter)) 79 | # print(callable(max)) 80 | # print(callable(object)) 81 | # print(callable(funTest)) 82 | # var = "Test" 83 | # print(callable(var)) 84 | # funTest("Python") 85 | 86 | 87 | # __call__ 88 | #======================================================================================================================= 89 | class ClassE: 90 | 91 | def __call__(self, *args): 92 | print("This is __call__ function, args:", args) 93 | 94 | e = ClassE() 95 | print(callable(e)) 96 | e("arg1", "arg2") 97 | -------------------------------------------------------------------------------- /advanced_programming/Metaclass.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 9/16/2018 4 | 5 | # type() 6 | #======================================================================================================================= 7 | # class ClassA: 8 | # name = "type test" 9 | # 10 | # a = ClassA() 11 | # b = 3.0 12 | # 13 | # print(type(a)) 14 | # print(type(b)) 15 | # print(type("This is string")) 16 | # print() 17 | # 18 | # print(a.__class__) 19 | # print(b.__class__) 20 | 21 | 22 | 23 | # ClassVariable = type('ClassA', (object,), dict(name="type test")) 24 | # a = ClassVariable() 25 | # print(type(a)) 26 | # print(a.name) 27 | 28 | # isinstance() 29 | #======================================================================================================================= 30 | class BaseClass: 31 | name = "Base" 32 | 33 | class SubClass(BaseClass): 34 | pass 35 | 36 | 37 | base = BaseClass() 38 | sub = SubClass() 39 | 40 | # print(isinstance(base, BaseClass)) 41 | # print(isinstance(base, SubClass)) 42 | # print() 43 | # 44 | # print(isinstance(sub, SubClass)) 45 | # print(isinstance(sub, BaseClass)) 46 | 47 | 48 | # print(issubclass(SubClass, BaseClass)) 49 | # print(issubclass(BaseClass, SubClass)) 50 | # print(SubClass.__bases__) 51 | 52 | 53 | # Version 2.0 54 | #======================================================================================================================= 55 | # class MyClass: 56 | # pass 57 | # 58 | # m = MyClass() 59 | # print(type(MyClass)) 60 | # print(type(m)) 61 | # print() 62 | # 63 | # print(isinstance(m, MyClass)) 64 | # print(isinstance(MyClass, type)) 65 | 66 | 67 | 68 | # MetaClass 69 | #======================================================================================================================= 70 | # class CustomMetaclass(type): 71 | # pass 72 | # 73 | # class CustomClass(metaclass=CustomMetaclass): 74 | # pass 75 | # 76 | # print(type(object)) 77 | # print(type(type)) 78 | # print() 79 | # 80 | # obj = CustomClass() 81 | # print(type(CustomClass)) 82 | # print(type(obj)) 83 | # 84 | # print() 85 | # print(isinstance(obj, CustomClass)) 86 | # print(isinstance(obj, object)) 87 | 88 | 89 | 90 | # CustomMetaClass 91 | #======================================================================================================================= 92 | class CustomMetaclass(type): 93 | 94 | def __init__(cls, what, bases=None, dict=None): 95 | print("CustomMetaclass.__init__ cls:", cls) 96 | super().__init__(what, bases, dict) 97 | 98 | def __call__(cls, *args, **kwargs): 99 | print("CustomMetaclass.__call__ args:", args, kwargs) 100 | self = super(CustomMetaclass, cls).__call__(*args, **kwargs) 101 | print("CustomMetaclass.__call__ self:", self) 102 | return self 103 | 104 | class CustomClass(metaclass=CustomMetaclass): 105 | 106 | def __init__(self, *args, **kwargs): 107 | print("CustomClass.__init__ self:", self) 108 | super().__init__() 109 | 110 | def __new__(cls, *args, **kwargs): 111 | self = super().__new__(cls) 112 | print("CustomClass.__new__, self:", self) 113 | return self 114 | 115 | def __call__(self, *args, **kwargs): 116 | print("CustomClass.__call__ args:", args) 117 | 118 | obj = CustomClass("Meta arg1", "Meta arg2", kwarg1=1, kwarg2=2) 119 | print(type(CustomClass)) 120 | print(obj) 121 | obj("arg1", "arg2") 122 | 123 | 124 | # class Singleton2(type): 125 | # # def __init__(cls, name, bases, attrs): 126 | # # super(Singleton2, cls).__init__(name, bases, attrs) 127 | # # cls._instance = None 128 | # 129 | # def __call__(cls, *args, **kwargs): 130 | # # if not cls._instance: 131 | # # cls._instance = super(Singleton2, cls).__call__(*args, **kwargs) 132 | # return super(Singleton2, cls).__call__(*args, **kwargs) 133 | # 134 | # class MyClass(metaclass=Singleton2): 135 | # def __init__(self, name): 136 | # self.__name = name 137 | # 138 | # def getName(self): 139 | # return self.__name 140 | # 141 | # 142 | # # Test 143 | # s0 = MyClass("Zhangsan") 144 | # s1 = MyClass("Lisi") 145 | # print(s0.getName(), s1.getName()) 146 | # print("id(s0):", id(s0), "id(s1):", id(s1)) 147 | # print("s0 == s1:", s0 == s1) 148 | 149 | # object -------------------------------------------------------------------------------- /advanced_programming/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 9/15/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | 8 | 9 | # Version 2.0 10 | #======================================================================================================================= 11 | # 代码框架 12 | #============================== 13 | 14 | 15 | # 基于框架的实现 16 | #============================== 17 | 18 | 19 | # Test 20 | #======================================================================================================================= 21 | 22 | -------------------------------------------------------------------------------- /application/GameCommand.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: UTF-8 -*- 3 | # Authoer: Spencer.Luo 4 | # Date: 5/18/2018 5 | 6 | from abc import ABCMeta, abstractmethod 7 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 8 | import time 9 | # 引入time模块进行时间的控制 10 | 11 | class GameRole: 12 | """游戏的角色""" 13 | 14 | # 每次移动的步距 15 | STEP = 5 16 | 17 | def __init__(self, name): 18 | self.__name = name 19 | self.__x = 0 20 | self.__y = 0 21 | self.__z = 0 22 | 23 | def leftMove(self): 24 | self.__x -= self.STEP 25 | 26 | def rightMove(self): 27 | self.__x += self.STEP 28 | 29 | def upMove(self): 30 | self.__y += self.STEP 31 | 32 | def downMove(self): 33 | self.__y -= self.STEP 34 | 35 | def jumpMove(self): 36 | self.__z += self.STEP 37 | 38 | def squatMove(self): 39 | self.__z -= self.STEP 40 | 41 | def attack(self): 42 | print("%s发动攻击..." % self.__name) 43 | 44 | def showPosition(self): 45 | print("%s的位置:(x:%s, y:%s, z:%s)" % (self.__name, self.__x, self.__y, self.__z) ) 46 | 47 | class GameCommand(metaclass=ABCMeta): 48 | """游戏角色的命令类""" 49 | 50 | def __init__(self, role): 51 | self._role = role 52 | 53 | def setRole(self, role): 54 | self._role = role 55 | 56 | @abstractmethod 57 | def execute(self): 58 | pass 59 | 60 | class Left(GameCommand): 61 | """左移命令""" 62 | 63 | def execute(self): 64 | self._role.leftMove() 65 | self._role.showPosition() 66 | 67 | class Right(GameCommand): 68 | """右移命令""" 69 | 70 | def execute(self): 71 | self._role.rightMove() 72 | self._role.showPosition() 73 | 74 | class Up(GameCommand): 75 | """上移命令""" 76 | 77 | def execute(self): 78 | self._role.upMove() 79 | self._role.showPosition() 80 | 81 | class Down(GameCommand): 82 | """下移命令""" 83 | 84 | def execute(self): 85 | self._role.downMove() 86 | self._role.showPosition() 87 | 88 | 89 | class Jump(GameCommand): 90 | """弹跳命令""" 91 | 92 | def execute(self): 93 | self._role.jumpMove() 94 | self._role.showPosition() 95 | # 跳起后空中停留半秒 96 | time.sleep(0.5) 97 | 98 | class Squat(GameCommand): 99 | """下蹲命令""" 100 | 101 | def execute(self): 102 | self._role.squatMove() 103 | self._role.showPosition() 104 | # 下蹲后伏地半秒 105 | time.sleep(0.5) 106 | 107 | 108 | class Attack(GameCommand): 109 | """攻击命令""" 110 | 111 | def execute(self): 112 | self._role.attack() 113 | 114 | class MacroCommand(GameCommand): 115 | """宏命令,也就是组合命令""" 116 | 117 | def __init__(self, role = None): 118 | super().__init__(role) 119 | self.__commands = [] 120 | 121 | def addCommand(self, command): 122 | # 让所有的命令作用于同一个对象 123 | self.__commands.append(command) 124 | 125 | def removeCommand(self, command): 126 | self.__commands.remove(command) 127 | 128 | def execute(self): 129 | for command in self.__commands: 130 | command.execute() 131 | 132 | class GameInvoker: 133 | """命令调度者""" 134 | 135 | def __init__(self): 136 | self.__command = None 137 | 138 | def setCommand(self, command): 139 | self.__command = command 140 | return self 141 | 142 | def action(self): 143 | if self.__command is not None: 144 | self.__command.execute() 145 | 146 | def testGame(): 147 | """在控制台用字符来模拟命令""" 148 | role = GameRole("常山赵子龙") 149 | invoker = GameInvoker() 150 | while True: 151 | strCmd = input("请输入命令:"); 152 | strCmd = strCmd.upper() 153 | if (strCmd == "L"): 154 | invoker.setCommand(Left(role)).action() 155 | elif (strCmd == "R"): 156 | invoker.setCommand(Right(role)).action() 157 | elif (strCmd == "U"): 158 | invoker.setCommand(Up(role)).action() 159 | elif (strCmd == "D"): 160 | invoker.setCommand(Down(role)).action() 161 | elif (strCmd == "JP"): 162 | cmd = MacroCommand() 163 | cmd.addCommand(Jump(role)) 164 | cmd.addCommand(Squat(role)) 165 | invoker.setCommand(cmd).action() 166 | elif (strCmd == "A"): 167 | invoker.setCommand(Attack(role)).action() 168 | elif (strCmd == "LU"): 169 | cmd = MacroCommand() 170 | cmd.addCommand(Left(role)) 171 | cmd.addCommand(Up(role)) 172 | invoker.setCommand(cmd).action() 173 | elif (strCmd == "LD"): 174 | cmd = MacroCommand() 175 | cmd.addCommand(Left(role)) 176 | cmd.addCommand(Down(role)) 177 | invoker.setCommand(cmd).action() 178 | elif (strCmd == "RU"): 179 | cmd = MacroCommand() 180 | cmd.addCommand(Right(role)) 181 | cmd.addCommand(Up(role)) 182 | invoker.setCommand(cmd).action() 183 | elif (strCmd == "RD"): 184 | cmd = MacroCommand() 185 | cmd.addCommand(Right(role)) 186 | cmd.addCommand(Down(role)) 187 | invoker.setCommand(cmd).action() 188 | elif (strCmd == "LA"): 189 | cmd = MacroCommand() 190 | cmd.addCommand(Left(role)) 191 | cmd.addCommand(Attack(role)) 192 | invoker.setCommand(cmd).action() 193 | elif (strCmd == "RA"): 194 | cmd = MacroCommand() 195 | cmd.addCommand(Right(role)) 196 | cmd.addCommand(Attack(role)) 197 | invoker.setCommand(cmd).action() 198 | elif (strCmd == "UA"): 199 | cmd = MacroCommand() 200 | cmd.addCommand(Up(role)) 201 | cmd.addCommand(Attack(role)) 202 | invoker.setCommand(cmd).action() 203 | elif (strCmd == "DA"): 204 | cmd = MacroCommand() 205 | cmd.addCommand(Down(role)) 206 | cmd.addCommand(Attack(role)) 207 | invoker.setCommand(cmd).action() 208 | elif (strCmd == "JA"): 209 | cmd = MacroCommand() 210 | cmd.addCommand(Jump(role)) 211 | cmd.addCommand(Attack(role)) 212 | cmd.addCommand(Squat(role)) 213 | invoker.setCommand(cmd).action() 214 | elif (strCmd == "Q"): 215 | exit() 216 | 217 | testGame() -------------------------------------------------------------------------------- /application/ImageProcessing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 6/30/2018 4 | 5 | import cv2 6 | from abc import ABCMeta, abstractmethod 7 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 8 | 9 | class ImageProcessor(metaclass=ABCMeta): 10 | "图像处理的接口类" 11 | 12 | @abstractmethod 13 | def processing(self, img): 14 | "图像处理的抽象方法" 15 | pass 16 | 17 | class EdgeExtractionProcessor(ImageProcessor): 18 | "边缘提取算法" 19 | 20 | def processing(self, img): 21 | super().processing(img) 22 | print("真正的核心算法:边缘提取算法") 23 | newImg = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 10) 24 | return newImg 25 | 26 | 27 | class ImageDecorator(ImageProcessor): 28 | "图像装饰器" 29 | 30 | def __init__(self, processor): 31 | self._decorator = processor 32 | 33 | def processing(self, img): 34 | tmpImg = self.preProcessing(img) 35 | return self._decorator.processing(tmpImg) 36 | 37 | @abstractmethod 38 | def preProcessing(self, img): 39 | "预处理方法,由子类实现" 40 | pass 41 | 42 | 43 | class GrayProcessor(ImageDecorator): 44 | "灰度化处理器" 45 | 46 | def __init__(self, processor): 47 | super().__init__(processor) 48 | 49 | def preProcessing(self, img): 50 | print("灰度化处理...") 51 | return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换了灰度化 52 | 53 | 54 | class GradientProcessor(ImageDecorator): 55 | "梯度化处理器" 56 | 57 | def __init__(self, processor): 58 | super().__init__(processor) 59 | 60 | def preProcessing(self, img): 61 | print("梯度化处理...") 62 | x = cv2.Sobel(img, cv2.CV_16S, 1, 0) 63 | y = cv2.Sobel(img, cv2.CV_16S, 0, 1) 64 | absX = cv2.convertScaleAbs(x) # 转回uint8 65 | absY = cv2.convertScaleAbs(y) 66 | return cv2.addWeighted(absX, 0.5, absY, 0.5, 0) 67 | 68 | 69 | 70 | # 一阶微分算子 71 | #======================================================================================================================= 72 | from abc import ABCMeta, abstractmethod 73 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 74 | import numpy as np 75 | # 引入numpy模块进行矩阵的计算 76 | 77 | class DifferentialDerivative(metaclass=ABCMeta): 78 | """微分求导算法""" 79 | 80 | def imgProcessing(self, img, width, height): 81 | """模板方法,进行图像处理""" 82 | # 这里特别需要注意:OpenCv for Python中,(x, y)坐标点的像素用img[y, x]表示 83 | newImg = np.zeros([height, width], dtype=np.uint8) 84 | for y in range(0, height): 85 | for x in range(0, width): 86 | # 因为是采用(3*3)的核进行处理,所以最边上一圈的像素无法处理,需保留原值 87 | if (y != 0 and y != height-1 and x != 0 and x != width-1): 88 | value = self.derivation(img, x, y) 89 | # 小于0的值置为0,大于255的值置为255 90 | value = 0 if value < 0 else (255 if value > 255 else value) 91 | newImg[y, x] = value 92 | else: 93 | newImg[y, x] = img[y, x] 94 | return newImg 95 | 96 | @abstractmethod 97 | def derivation(self, img, x, y): 98 | """具体的步骤由子类实现""" 99 | pass 100 | 101 | class DifferentialDerivativeX(DifferentialDerivative): 102 | """水平微分求导算法""" 103 | 104 | def derivation(self, img, x, y): 105 | """Gx=f(x-1,y-1) + 2f(x-1,y) + f(x-1,y+1) - f(x+1,y-1) - 2f(x+1,y) - f(x+1, y+1)""" 106 | pix = img[y-1, x-1] + 2 * img[y, x-1] + img[y+1, x-1] - img[y-1, x+1] - 2 *img[y, x+1] - img[y+1, x+1] 107 | return pix 108 | 109 | 110 | class DifferentialDerivativeY(DifferentialDerivative): 111 | """垂直微分求导算法""" 112 | 113 | def derivation(self, img, x, y): 114 | """Gy=f(x-1,y-1) + 2f(x,y-1) + f(x+1,y-1) - f(x-1,y+1) - 2f(x,y+1) - f(x+1,y+1)""" 115 | pix = img[y-1, x-1] + 2*img[y-1, x] + img[y-1, x+1] - img[y+1, x-1] - 2*img[y+1, x] - img[y+1, x+1] 116 | return pix 117 | 118 | 119 | def testImageProcessing(): 120 | img = cv2.imread("E:\\TestImages\\bird.jpg") 121 | print("灰度化 --> 梯度化 --> 核心算法:边缘提取算法:") 122 | resultImg1 = GrayProcessor(GradientProcessor(EdgeExtractionProcessor())).processing(img) 123 | print() 124 | 125 | print("梯度化 --> 灰度化 --> 核心算法:边缘提取算法:") 126 | resultImg2 = GradientProcessor(GrayProcessor(EdgeExtractionProcessor())).processing(img) 127 | print() 128 | 129 | cv2.imshow("The result of image process1", resultImg1) 130 | cv2.imshow("The result of image process2", resultImg2) 131 | cv2.waitKey(0) 132 | cv2.destroyAllWindows() 133 | 134 | def differentialDerivativeOpenCv(): 135 | img = cv2.imread("E:\\TestImages\\person.jpg") 136 | 137 | # 转换成单通道灰度图 138 | img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 139 | 140 | x = cv2.Sobel(img, cv2.CV_16S, 1, 0) 141 | y = cv2.Sobel(img, cv2.CV_16S, 0, 1) 142 | # 进行微分计算后,可能会出现负值,将每个像素加上最小负数的绝对值 143 | absX = cv2.convertScaleAbs(x) # 转回uint8 144 | absY = cv2.convertScaleAbs(y) 145 | # img = cv2.addWeighted(absX, 0.5, absY, 0.5, 0) 146 | 147 | cv2.imshow("First order differential X", absX) 148 | cv2.imshow("First order differential Y", absY) 149 | cv2.waitKey(0) 150 | cv2.destroyAllWindows() 151 | 152 | 153 | def differentialDerivative(): 154 | img = cv2.imread("E:\\TestImages\\person.jpg") 155 | 156 | # 转换成单通道的灰度图 157 | img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 158 | # 均值滤波 159 | # img = cv2.blur(img, (3, 3)) 160 | 161 | # 获取图片的宽和高 162 | width = img.shape[1] 163 | height = img.shape[0] 164 | # 进行微分求导 165 | derivativeX = DifferentialDerivativeX() 166 | imgX = derivativeX.imgProcessing(img, width, height) 167 | derivativeY = DifferentialDerivativeY() 168 | imgY = derivativeY.imgProcessing(img, width, height) 169 | # 实现Sobel微分算子 170 | imgScobel = cv2.addWeighted(imgX, 0.5, imgY, 0.5, 0) 171 | 172 | cv2.imshow("First order differential X", imgX) 173 | cv2.imshow("First order differential Y", imgY) 174 | cv2.imshow("First order differential Scobel", imgScobel) 175 | cv2.waitKey(0) 176 | cv2.destroyAllWindows() 177 | 178 | 179 | # testImageProcessing() 180 | # differentialDerivativeOpenCv() 181 | differentialDerivative() 182 | 183 | -------------------------------------------------------------------------------- /application/TerminalMonitor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 5/20/2018 4 | 5 | # 引入升级版备忘录模式关键类 6 | from pattern.Memento import Originator, Caretaker, Memento 7 | import logging 8 | 9 | class TerminalCmd(Originator): 10 | """终端命令""" 11 | 12 | def __init__(self, text): 13 | self.__cmdName = "" 14 | self.__cmdArgs = [] 15 | self.parseCmd(text) 16 | 17 | def parseCmd(self, text): 18 | """从字符串中解析命令""" 19 | subStrs = self.getArgumentsFromString(text, " ") 20 | # 获取第一个字段作为命令名称 21 | if(len(subStrs) > 0): 22 | self.__cmdName = subStrs[0] 23 | 24 | # 获取第一个字段之后的所有字符作为命令的参数 25 | if (len(subStrs) > 1): 26 | self.__cmdArgs = subStrs[1:] 27 | 28 | def getArgumentsFromString(self, str, splitFlag): 29 | """通过splitFlag进行分割,获得参数数组""" 30 | 31 | if (splitFlag == ""): 32 | logging.warning("splitFlag 为空!") 33 | return "" 34 | 35 | data = str.split(splitFlag) 36 | result = [] 37 | for item in data: 38 | item.strip() 39 | if (item != ""): 40 | result.append(item) 41 | 42 | return result; 43 | 44 | def showCmd(self): 45 | print(self.__cmdName, self.__cmdArgs) 46 | 47 | class TerminalCaretaker(Caretaker): 48 | """终端命令的备忘录管理类""" 49 | 50 | def showHistoryCmds(self): 51 | """显示历史命令""" 52 | for key, obj in self._mementos.items(): 53 | name = "" 54 | value = [] 55 | if(obj._TerminalCmd__cmdName): 56 | name = obj._TerminalCmd__cmdName 57 | if(obj._TerminalCmd__cmdArgs): 58 | value = obj._TerminalCmd__cmdArgs 59 | print("第%s条命令: %s %s" % (key, name, value) ) 60 | 61 | 62 | def testTerminal(): 63 | cmdIdx = 0 64 | caretaker = TerminalCaretaker() 65 | curCmd = TerminalCmd("") 66 | while (True): 67 | strCmd = input("请输入指令:"); 68 | strCmd = strCmd.lower() 69 | if (strCmd.startswith("q")): 70 | exit(0) 71 | elif(strCmd.startswith("h")): 72 | caretaker.showHistoryCmds() 73 | # 通过"!"符号表示获取历史的某个指令 74 | elif(strCmd.startswith("!")): 75 | idx = int(strCmd[1:]) 76 | curCmd.restoreFromMemento(caretaker.getMemento(idx)) 77 | curCmd.showCmd() 78 | else: 79 | curCmd = TerminalCmd(strCmd) 80 | curCmd.showCmd() 81 | caretaker.addMemento(cmdIdx, curCmd.createMemento()) 82 | cmdIdx +=1 83 | 84 | 85 | testTerminal() -------------------------------------------------------------------------------- /application/WhiteBoard.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 4/21/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | from enum import Enum 8 | # Python3.4 之后支持枚举Enum的语法 9 | 10 | class ShapeType(Enum): 11 | "形状类型" 12 | ShapeTypeLine = 1 13 | ShapeTypeRect = 2 14 | ShapeTypeEllipse = 3 15 | 16 | 17 | class Shape: 18 | "形状" 19 | 20 | def __init__(self, name): 21 | self.__name = name 22 | 23 | def getType(self): 24 | pass 25 | 26 | def getName(self): 27 | return self.__name 28 | 29 | 30 | class Line(Shape): 31 | "直线" 32 | 33 | def __init__(self, name): 34 | super().__init__(name) 35 | 36 | def getType(self): 37 | return ShapeType.ShapeTypeLine 38 | 39 | class Rectangle(Shape): 40 | "矩形" 41 | 42 | def __init__(self, name): 43 | super().__init__(name) 44 | 45 | def getType(self): 46 | return ShapeType.ShapeTypeRect 47 | 48 | 49 | class Ellipse(Shape): 50 | "椭圆" 51 | 52 | def __init__(self, name): 53 | super().__init__(name) 54 | 55 | def getType(self): 56 | return ShapeType.ShapeTypeEllipse 57 | 58 | class ShapeFactory: 59 | "形状的工厂类" 60 | 61 | @staticmethod 62 | def createShape(self, type): 63 | pass 64 | 65 | def createPen(self, penType): 66 | "创建形状" 67 | # Python中没有switch/case的语法,我们通过字典来来模拟switch/case的实现方式 68 | switcher = { 69 | ShapeType.ShapeTypeLine : Line("直线"), 70 | ShapeType.ShapeTypeRect : Rectangle("矩形"), 71 | ShapeType.ShapeTypeEllipse : Ellipse("椭圆"), 72 | } 73 | return switcher.get(penType, "create pen error") 74 | 75 | class ShapeType(Enum): 76 | "形状类型" 77 | ColorRed = 1 78 | ColorGreen = 2 79 | ColorBlue = 3 80 | 81 | class Color: 82 | "颜色" 83 | 84 | def __init__(self, value): 85 | self.__value = value 86 | 87 | def getType(self): 88 | pass 89 | 90 | # Version 2.0 91 | #======================================================================================================================= 92 | # 代码框架 93 | #============================== 94 | 95 | 96 | # 基于框架的实现 97 | #============================== 98 | 99 | 100 | # Test 101 | #======================================================================================================================= 102 | 103 | -------------------------------------------------------------------------------- /application/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 4/21/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | 8 | 9 | # Version 2.0 10 | #======================================================================================================================= 11 | # 代码框架 12 | #============================== 13 | 14 | 15 | # 基于框架的实现 16 | #============================== 17 | 18 | 19 | # Test 20 | #======================================================================================================================= 21 | 22 | -------------------------------------------------------------------------------- /docs/DesignPattern.eap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencer-luo/PyDesignPattern/9438043854cf4ad2ac191cfdf3dab133f38a00d1/docs/DesignPattern.eap -------------------------------------------------------------------------------- /docs/EverybodyKnowsDesgnPatterns.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spencer-luo/PyDesignPattern/9438043854cf4ad2ac191cfdf3dab133f38a00d1/docs/EverybodyKnowsDesgnPatterns.jpg -------------------------------------------------------------------------------- /pattern/Adapter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 4/24/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class IHightPerson(metaclass=ABCMeta): 11 | """接口类,提供空实现的方法,由子类去实现""" 12 | 13 | @abstractmethod 14 | def getName(self): 15 | """获取姓名""" 16 | pass 17 | 18 | @abstractmethod 19 | def getHeight(self): 20 | """获取身高""" 21 | pass 22 | 23 | @abstractmethod 24 | def appearance(self, person): 25 | """外貌""" 26 | pass 27 | 28 | 29 | class HighPerson(IHightPerson): 30 | """个高的人""" 31 | 32 | def __init__(self, name): 33 | self.__name = name 34 | 35 | def getName(self): 36 | return self.__name 37 | 38 | def getHeight(self): 39 | return 170 40 | 41 | def appearance(self): 42 | print(self.getName() + "身高" + str(self.getHeight()) + ",完美如你,天生的美女!") 43 | 44 | 45 | class ShortPerson: 46 | """个矮的人""" 47 | 48 | def __init__(self, name): 49 | self.__name = name 50 | 51 | def getName(self): 52 | return self.__name 53 | 54 | def getRealHeight(self): 55 | return 160 56 | 57 | def getShoesHeight(self): 58 | return 6 59 | 60 | 61 | class DecoratePerson(ShortPerson, IHightPerson): 62 | """有高跟鞋搭配的人""" 63 | 64 | def __init__(self, name): 65 | super().__init__(name) 66 | 67 | def getName(self): 68 | return super().getName() 69 | 70 | def getHeight(self): 71 | return super().getRealHeight() + super().getShoesHeight() 72 | 73 | def appearance(self): 74 | print(self.getName() + "身高" + str(self.getHeight()) + ", 在高跟鞋的适配下,你身高不输高圆圆,气质不输范冰冰!") 75 | 76 | 77 | class HeightMatch: 78 | """身高匹配""" 79 | 80 | def __init__(self, person): 81 | self.__person = person 82 | 83 | def matching(self, person1): 84 | """假设标准身高差为10厘米内""" 85 | distance = abs(self.__person.getHeight() - person1.getHeight()) 86 | isMatch = distance <= 10 87 | print(self.__person.getName() + "和" + person1.getName() + "是否为情侣的标准身高差:" 88 | + ("是" if isMatch else "否") + ", 差值:" + str(distance)) 89 | 90 | 91 | class Hotel: 92 | """(高级)酒店""" 93 | 94 | def recruit(self, person): 95 | """ 96 | :param person: IHightPerson的对象 97 | """ 98 | suitable = self.receptionistSuitable(person) 99 | print(person.getName() + "是否适合做接待员:", "符合" if suitable else "不符合") 100 | 101 | def receptionistSuitable(self, person): 102 | """ 103 | 是否可以成为(高级酒店)接待员 104 | :param person: IHightPerson的对象 105 | :return: 是否符合做接待员的条件 106 | """ 107 | return person.getHeight() >= 165; 108 | 109 | # Version 1.0 110 | # ======================================================================================================================= 111 | from abc import ABCMeta, abstractmethod 112 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 113 | 114 | class SocketEntity: 115 | """接口类型定义""" 116 | 117 | def __init__(self, numOfPin, typeOfPin): 118 | self.__numOfPin = numOfPin 119 | self.__typeOfPin = typeOfPin 120 | 121 | def getNumOfPin(self): 122 | return self.__numOfPin 123 | 124 | def setNumOfPin(self, numOfPin): 125 | self.__numOfPin = numOfPin 126 | 127 | def getTypeOfPin(self): 128 | return self.__typeOfPin 129 | 130 | def setTypeOfPin(self, typeOfPin): 131 | self.__typeOfPin = typeOfPin 132 | 133 | 134 | class ISocket(metaclass=ABCMeta): 135 | """插座类型""" 136 | 137 | def getName(self): 138 | """插座名称""" 139 | pass 140 | 141 | def getSocket(self): 142 | """获取接口""" 143 | pass 144 | 145 | 146 | class ChineseSocket(ISocket): 147 | """国标插座""" 148 | 149 | def getName(self): 150 | return "国标插座" 151 | 152 | def getSocket(self): 153 | return SocketEntity(3, "八字扁型") 154 | 155 | 156 | class BritishSocket: 157 | """英标插座""" 158 | 159 | def name(self): 160 | return "英标插座" 161 | 162 | def socketInterface(self): 163 | return SocketEntity(3, "T字方型") 164 | 165 | class AdapterSocket(ISocket): 166 | """插座转换器""" 167 | 168 | def __init__(self, britishSocket): 169 | self.__britishSocket = britishSocket 170 | 171 | def getName(self): 172 | return self.__britishSocket.name() + "转换器" 173 | 174 | def getSocket(self): 175 | socket = self.__britishSocket.socketInterface() 176 | socket.setTypeOfPin("八字扁型") 177 | return socket 178 | 179 | 180 | 181 | # Version 2.0 182 | #======================================================================================================================= 183 | # 代码框架 184 | #============================== 185 | from abc import ABCMeta, abstractmethod 186 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 187 | 188 | class Target(metaclass=ABCMeta): 189 | """目标类""" 190 | 191 | @abstractmethod 192 | def function(self): 193 | pass 194 | 195 | 196 | class Adaptee: 197 | """源对象类""" 198 | 199 | def speciaficFunction(self): 200 | print("被适配对象的特殊功能") 201 | 202 | class Adapter(Target): 203 | """适配器""" 204 | 205 | def __init__(self, adaptee): 206 | self.__adaptee = adaptee 207 | 208 | def function(self): 209 | print("进行功能的转换") 210 | self.__adaptee.speciaficFunction() 211 | 212 | 213 | 214 | # 基于框架的实现 215 | #============================== 216 | from abc import ABCMeta, abstractmethod 217 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 218 | import os 219 | # 导入os库,用于文件、路径相关的解析 220 | 221 | class Page: 222 | """电子书一页的内容""" 223 | def __init__(self, pageNum): 224 | self.__pageNum = pageNum 225 | 226 | def getContent(self): 227 | return "第 " + str(self.__pageNum) + " 页的内容..." 228 | 229 | 230 | class Catalogue: 231 | """目录结构""" 232 | 233 | def __init__(self, title): 234 | self.__title = title 235 | self.__chapters = [] 236 | 237 | def addChapter(self, title): 238 | self.__chapters.append(title) 239 | 240 | def showInfo(self): 241 | print("书名:" + self.__title) 242 | print("目录:") 243 | for chapter in self.__chapters: 244 | print(" " + chapter) 245 | 246 | 247 | class IBook(metaclass=ABCMeta): 248 | """电子书文档的接口类""" 249 | 250 | @abstractmethod 251 | def parseFile(self, filePath): 252 | """解析文档""" 253 | pass 254 | 255 | @abstractmethod 256 | def getCatalogue(self): 257 | """获取目录""" 258 | pass 259 | 260 | @abstractmethod 261 | def getPageCount(self): 262 | """获取页数""" 263 | pass 264 | 265 | @abstractmethod 266 | def getPage(self, pageNum): 267 | """获取第pageNum页的内容""" 268 | pass 269 | 270 | 271 | class TxtBook(IBook): 272 | """TXT解析类""" 273 | 274 | def parseFile(self, filePath): 275 | # 模拟文档的解析 276 | print(filePath + " 文件解析成功") 277 | self.__title = os.path.splitext(filePath)[0] 278 | self.__pageCount = 500 279 | return True 280 | 281 | def getCatalogue(self): 282 | catalogue = Catalogue(self.__title) 283 | catalogue.addChapter("第一章 标题") 284 | catalogue.addChapter("第二章 标题") 285 | return catalogue 286 | 287 | def getPageCount(self): 288 | return self.__pageCount 289 | 290 | def getPage(self, pageNum): 291 | return Page(pageNum) 292 | 293 | 294 | class EpubBook(IBook): 295 | """Epub解析类""" 296 | 297 | def parseFile(self, filePath): 298 | # 模拟文档的解析 299 | print(filePath + " 文件解析成功") 300 | self.__title = os.path.splitext(filePath)[0] 301 | self.__pageCount = 800 302 | return True 303 | 304 | def getCatalogue(self): 305 | catalogue = Catalogue(self.__title) 306 | catalogue.addChapter("第一章 标题") 307 | catalogue.addChapter("第二章 标题") 308 | return catalogue 309 | 310 | def getPageCount(self): 311 | return self.__pageCount 312 | 313 | def getPage(self, pageNum): 314 | return Page(pageNum) 315 | 316 | 317 | class Outline: 318 | """第三方PDF解析库的目录类""" 319 | def __init__(self): 320 | self.__outlines = [] 321 | 322 | def addOutline(self, title): 323 | self.__outlines.append(title) 324 | 325 | def getOutlines(self): 326 | return self.__outlines 327 | 328 | 329 | class PdfPage: 330 | "PDF页" 331 | 332 | def __init__(self, pageNum): 333 | self.__pageNum = pageNum 334 | 335 | def getPageNum(self): 336 | return self.__pageNum 337 | 338 | 339 | class ThirdPdf: 340 | """第三方PDF解析库""" 341 | 342 | def __init__(self): 343 | self.__pageSize = 0 344 | self.__title = "" 345 | 346 | def open(self, filePath): 347 | print("第三方库解析PDF文件:" + filePath) 348 | self.__title = os.path.splitext(filePath)[0] 349 | self.__pageSize = 1000 350 | return True 351 | 352 | def getTitle(self): 353 | return self.__title 354 | 355 | def getOutline(self): 356 | outline = Outline() 357 | outline.addOutline("第一章 PDF电子书标题") 358 | outline.addOutline("第二章 PDF电子书标题") 359 | return outline 360 | 361 | def pageSize(self): 362 | return self.__pageSize 363 | 364 | def page(self, index): 365 | return PdfPage(index) 366 | 367 | 368 | class PdfAdapterBook(ThirdPdf, IBook): 369 | """对第三方的PDF解析库重新进行包装""" 370 | 371 | def __init__(self, thirdPdf): 372 | self.__thirdPdf = thirdPdf 373 | 374 | def parseFile(self, filePath): 375 | # 模拟文档的解析 376 | rtn = self.__thirdPdf.open(filePath) 377 | if(rtn): 378 | print(filePath + "文件解析成功") 379 | return rtn 380 | 381 | def getCatalogue(self): 382 | outline = self.getOutline() 383 | print("将Outline结构的目录转换成Catalogue结构的目录") 384 | catalogue = Catalogue(self.__thirdPdf.getTitle()) 385 | for title in outline.getOutlines(): 386 | catalogue.addChapter(title) 387 | return catalogue 388 | 389 | def getPageCount(self): 390 | return self.__thirdPdf.pageSize() 391 | 392 | def getPage(self, pageNum): 393 | page = self.page(pageNum) 394 | print("将PdfPage的面对象转换成Page的对象") 395 | return Page(page.getPageNum()) 396 | 397 | 398 | class Reader: 399 | "阅读器" 400 | 401 | def __init__(self, name): 402 | self.__name = name 403 | self.__filePath = "" 404 | self.__curBook = None 405 | self.__curPageNum = -1 406 | 407 | def __initBook(self, filePath): 408 | self.__filePath = filePath 409 | extName = os.path.splitext(filePath)[1] 410 | if(extName.lower() == ".epub"): 411 | self.__curBook = EpubBook() 412 | elif(extName.lower() == ".txt"): 413 | self.__curBook = TxtBook() 414 | elif(extName.lower() == ".pdf"): 415 | self.__curBook = PdfAdapterBook(ThirdPdf()) 416 | else: 417 | self.__curBook = None 418 | 419 | def openFile(self, filePath): 420 | self.__initBook(filePath) 421 | if(self.__curBook is not None): 422 | rtn = self.__curBook.parseFile(filePath) 423 | if(rtn): 424 | self.__curPageNum = 1 425 | return rtn 426 | return False 427 | 428 | def closeFile(self): 429 | print("关闭 " + self.__filePath + " 文件") 430 | return True 431 | 432 | def showCatalogue(self): 433 | catalogue = self.__curBook.getCatalogue() 434 | catalogue.showInfo() 435 | 436 | def prePage(self): 437 | print("往前翻一页:", end="") 438 | return self.gotoPage(self.__curPageNum - 1) 439 | 440 | def nextPage(self): 441 | print("往后翻一页:", end="") 442 | return self.gotoPage(self.__curPageNum + 1) 443 | 444 | def gotoPage(self, pageNum): 445 | if(pageNum > 1 and pageNum < self.__curBook.getPageCount() -1): 446 | self.__curPageNum = pageNum 447 | 448 | print("显示第" + str(self.__curPageNum) + "页") 449 | page = self.__curBook.getPage(self.__curPageNum) 450 | page.getContent() 451 | return page 452 | 453 | 454 | # Test 455 | #======================================================================================================================= 456 | 457 | def testPerson(): 458 | lira = HighPerson("Lira") 459 | lira.appearance() 460 | demi = DecoratePerson("Demi"); 461 | demi.appearance() 462 | 463 | haigerMatching = HeightMatch(HighPerson("Haiger")) 464 | haigerMatching.matching(lira) 465 | haigerMatching.matching(demi) 466 | # hotel = Hotel() 467 | # hotel.recruit(lira) 468 | # hotel.recruit(demi) 469 | 470 | def testAdapter(): 471 | adpater = Adapter(Adaptee()) 472 | adpater.function() 473 | 474 | def testReader(): 475 | reader = Reader("阅读器") 476 | if(not reader.openFile("平凡的世界.txt")): 477 | return 478 | reader.showCatalogue() 479 | reader.prePage() 480 | reader.nextPage() 481 | reader.nextPage() 482 | reader.closeFile() 483 | print() 484 | 485 | if (not reader.openFile("追风筝的人.epub")): 486 | return 487 | reader.showCatalogue() 488 | reader.nextPage() 489 | reader.nextPage() 490 | reader.prePage() 491 | reader.closeFile() 492 | print() 493 | 494 | if (not reader.openFile("如何从生活中领悟设计模式.pdf")): 495 | return 496 | reader.showCatalogue() 497 | reader.nextPage() 498 | reader.nextPage() 499 | reader.closeFile() 500 | 501 | 502 | def canChargeforDigtalDevice(name, socket): 503 | if socket.getNumOfPin() == 3 and socket.getTypeOfPin() == "八字扁型": 504 | isStandard = "符合" 505 | canCharge = "可以" 506 | else: 507 | isStandard = "不符合" 508 | canCharge = "不能" 509 | 510 | print("[%s]:\n针脚数量:%d,针脚类型:%s; %s中国标准,%s给大陆的电子设备充电!" 511 | % (name, socket.getNumOfPin(), socket.getTypeOfPin(), isStandard, canCharge)) 512 | 513 | def testSocket(): 514 | chineseSocket = ChineseSocket() 515 | canChargeforDigtalDevice(chineseSocket.getName(), chineseSocket.getSocket()) 516 | 517 | britishSocket = BritishSocket() 518 | canChargeforDigtalDevice(britishSocket.name(), britishSocket.socketInterface()) 519 | 520 | adapterSocket = AdapterSocket(britishSocket) 521 | canChargeforDigtalDevice(adapterSocket.getName(), adapterSocket.getSocket()) 522 | 523 | 524 | # testPerson() 525 | # testAdapter() 526 | testReader() 527 | # testSocket() -------------------------------------------------------------------------------- /pattern/Bridge.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 7/8/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class Shape(metaclass=ABCMeta): 11 | """形状""" 12 | 13 | def __init__(self, color): 14 | self._color = color 15 | 16 | @abstractmethod 17 | def getShapeType(self): 18 | pass 19 | 20 | def getShapeInfo(self): 21 | return self._color.getColor() + "的" + self.getShapeType() 22 | 23 | 24 | class Rectange(Shape): 25 | """矩形""" 26 | 27 | def __init__(self, color): 28 | super().__init__(color) 29 | 30 | def getShapeType(self): 31 | return "矩形" 32 | 33 | class Ellipse(Shape): 34 | """椭圆""" 35 | 36 | def __init__(self, color): 37 | super().__init__(color) 38 | 39 | def getShapeType(self): 40 | return "椭圆" 41 | 42 | class Color(metaclass=ABCMeta): 43 | """颜色""" 44 | 45 | @abstractmethod 46 | def getColor(self): 47 | pass 48 | 49 | 50 | class Red(Color): 51 | """红色""" 52 | 53 | def getColor(self): 54 | return "红色" 55 | 56 | 57 | class Green(Color): 58 | """绿色""" 59 | 60 | def getColor(self): 61 | return "绿色" 62 | 63 | # Version 2.0 64 | #======================================================================================================================= 65 | # 代码框架 66 | #============================== 67 | 68 | 69 | # 基于框架的实现 70 | #============================== 71 | 72 | 73 | # Test 74 | #======================================================================================================================= 75 | 76 | def testShap(): 77 | redRect = Rectange(Red()) 78 | print(redRect.getShapeInfo()) 79 | greenRect = Rectange(Green()) 80 | print(greenRect.getShapeInfo()) 81 | 82 | redEllipse = Ellipse(Red()) 83 | print(redEllipse.getShapeInfo()) 84 | greenEllipse = Ellipse(Green()) 85 | print(greenEllipse.getShapeInfo()) 86 | 87 | 88 | testShap() -------------------------------------------------------------------------------- /pattern/Builder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 4/6/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | # from abc import ABCMeta, abstractmethod 8 | # # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | # 10 | # class Toy(metaclass=ABCMeta): 11 | # """玩具""" 12 | # 13 | # def __init__(self, name): 14 | # self._name = name 15 | # self.__components = [] 16 | # 17 | # def getName(self): 18 | # return self._name 19 | # 20 | # def addComponent(self, component, count = 1, unit = "个"): 21 | # self.__components.append([component, count, unit]) 22 | # print("%s 增加了 %d %s%s" % (self._name, count, unit, component) ); 23 | # 24 | # @abstractmethod 25 | # def feature(self): 26 | # pass 27 | # 28 | # 29 | # class Car(Toy): 30 | # """小车""" 31 | # 32 | # def feature(self): 33 | # print("我是 %s,我可以快速奔跑……" % self._name) 34 | # 35 | # 36 | # class Manor(Toy): 37 | # """庄园""" 38 | # 39 | # def feature(self): 40 | # print("我是 %s,我可供观赏,也可用来游玩!" % self._name) 41 | # 42 | # 43 | # class ToyBuilder: 44 | # """玩具构建者""" 45 | # 46 | # def buildCar(self): 47 | # car = Car("迷你小车") 48 | # print("正在构建 %s ……" % car.getName()) 49 | # car.addComponent("轮子", 4) 50 | # car.addComponent("车身", 1) 51 | # car.addComponent("发动机", 1) 52 | # car.addComponent("方向盘") 53 | # return car 54 | # 55 | # def buildManor(self): 56 | # manor = Manor("淘淘小庄园") 57 | # print("正在构建 %s ……" % manor.getName()) 58 | # manor.addComponent('客厅', 1, "间") 59 | # manor.addComponent('卧室', 2, "间") 60 | # manor.addComponent("书房", 1, "间") 61 | # manor.addComponent("厨房", 1, "间") 62 | # manor.addComponent("花园", 1, "个") 63 | # manor.addComponent("围墙", 1, "堵") 64 | # return manor 65 | # 66 | # 67 | # # Test 68 | # #============================== 69 | # def testBuilder(): 70 | # builder = ToyBuilder() 71 | # car = builder.buildCar() 72 | # car.feature() 73 | # 74 | # print() 75 | # mannor = builder.buildManor() 76 | # mannor.feature() 77 | 78 | 79 | 80 | 81 | # Version 2.0 82 | #======================================================================================================================= 83 | from abc import ABCMeta, abstractmethod 84 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 85 | 86 | class Toy(metaclass=ABCMeta): 87 | """玩具""" 88 | 89 | def __init__(self, name): 90 | self._name = name 91 | self.__components = [] 92 | 93 | def getName(self): 94 | return self._name 95 | 96 | def addComponent(self, component, count = 1, unit = "个"): 97 | self.__components.append([component, count, unit]) 98 | # print("%s 增加了 %d %s%s" % (self._name, count, unit, component) ); 99 | 100 | @abstractmethod 101 | def feature(self): 102 | pass 103 | 104 | 105 | class Car(Toy): 106 | """小车""" 107 | 108 | def feature(self): 109 | print("我是 %s,我可以快速奔跑……" % self._name) 110 | 111 | 112 | class Manor(Toy): 113 | """庄园""" 114 | 115 | def feature(self): 116 | print("我是 %s,我可供观赏,也可用来游玩!" % self._name) 117 | 118 | 119 | class ToyBuilder(metaclass=ABCMeta): 120 | """玩具构建者""" 121 | 122 | @abstractmethod 123 | def buildProduct(self): 124 | pass 125 | 126 | 127 | class CarBuilder(ToyBuilder): 128 | """车的构建类""" 129 | 130 | def buildProduct(self): 131 | car = Car("迷你小车") 132 | print("正在构建 %s ……" % car.getName()) 133 | car.addComponent("轮子", 4) 134 | car.addComponent("车身", 1) 135 | car.addComponent("发动机", 1) 136 | car.addComponent("方向盘") 137 | return car 138 | 139 | 140 | class ManorBuilder(ToyBuilder): 141 | """庄园的构建类""" 142 | 143 | def buildProduct(self): 144 | manor = Manor("淘淘小庄园") 145 | print("正在构建 %s ……" % manor.getName()) 146 | manor.addComponent('客厅', 1, "间") 147 | manor.addComponent('卧室', 2, "间") 148 | manor.addComponent("书房", 1, "间") 149 | manor.addComponent("厨房", 1, "间") 150 | manor.addComponent("花园", 1, "个") 151 | manor.addComponent("围墙", 1, "堵") 152 | return manor 153 | 154 | class BuilderMgr: 155 | """建构类的管理类""" 156 | 157 | def __init__(self): 158 | self.__carBuilder = CarBuilder() 159 | self.__manorBuilder = ManorBuilder() 160 | 161 | def buildCar(self, num): 162 | count = 0 163 | products = [] 164 | while(count < num): 165 | car = self.__carBuilder.buildProduct() 166 | products.append(car) 167 | count +=1 168 | print("建造完成第 %d 辆 %s" % (count, car.getName()) ) 169 | return products 170 | 171 | def buildManor(self, num): 172 | count = 0 173 | products = [] 174 | while (count < num): 175 | manor = self.__manorBuilder.buildProduct() 176 | products.append(manor) 177 | count += 1 178 | print("建造完成第 %d 个 %s" % (count, manor.getName())) 179 | return products 180 | 181 | 182 | # Test 183 | # ============================== 184 | def testAdvancedBuilder(): 185 | builderMgr = BuilderMgr() 186 | builderMgr.buildManor(2) 187 | print() 188 | builderMgr.buildCar(4) 189 | 190 | 191 | # testBuilder() 192 | testAdvancedBuilder() 193 | -------------------------------------------------------------------------------- /pattern/Clone.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 4/1/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | # from copy import copy, deepcopy 8 | # 9 | # class Person: 10 | # """人""" 11 | # 12 | # def __init__(self, name, age): 13 | # self.__name = name 14 | # self.__age = age 15 | # 16 | # def showMyself(self): 17 | # print("我是" + self.__name + ",年龄" + str(self.__age) + ".") 18 | # 19 | # def coding(self): 20 | # print("我是码农,我用程序改变世界,Coding...") 21 | # 22 | # def reading(self): 23 | # print("阅读使我快乐!知识使我成长!如饥似渴地阅读是生活的一部分...") 24 | # 25 | # def fallInLove(self): 26 | # print("春风吹,月亮明,花前月下好相约...") 27 | # 28 | # def clone(self): 29 | # return copy(self) 30 | 31 | 32 | # 浅拷贝与深拷贝 33 | #======================================================================================================================= 34 | from copy import copy, deepcopy 35 | 36 | class PetStore: 37 | """宠物店""" 38 | 39 | def __init__(self, name): 40 | self.__name = name 41 | self.__petList = [] 42 | 43 | def setName(self, name): 44 | self.__name = name 45 | 46 | def showMyself(self): 47 | print("%s 宠物店有以下宠物:" % self.__name) 48 | for pet in self.__petList: 49 | print(pet + "\t", end="") 50 | print() 51 | 52 | def addPet(self, pet): 53 | self.__petList.append(pet) 54 | 55 | 56 | # Version 2.0 57 | #======================================================================================================================= 58 | # 代码框架 59 | #============================== 60 | from copy import copy, deepcopy 61 | 62 | class Clone: 63 | """克隆的基类""" 64 | 65 | def clone(self): 66 | """浅拷贝的方式克隆对象""" 67 | return copy(self) 68 | 69 | def deepClone(self): 70 | """深拷贝的方式克隆对象""" 71 | return deepcopy(self) 72 | 73 | 74 | # 基于框架的实现 75 | #============================== 76 | class Person(Clone): 77 | """人""" 78 | 79 | def __init__(self, name, age): 80 | self.__name = name 81 | self.__age = age 82 | 83 | def showMyself(self): 84 | print("我是" + self.__name + ",年龄" + str(self.__age) + ".") 85 | 86 | def coding(self): 87 | print("我是码农,我用程序改变世界,Coding...") 88 | 89 | def reading(self): 90 | print("阅读使我快乐!知识使我成长!如饥似渴地阅读是生活的一部分...") 91 | 92 | def fallInLove(self): 93 | print("春风吹,月亮明,花前月下好相约...") 94 | 95 | 96 | # 实战应用 97 | # ======================================================================================================================= 98 | class AppConfig(Clone): 99 | """应用程序功能配置""" 100 | 101 | def __init__(self, configName): 102 | self.__configName = configName 103 | self.parseFromFile("./config/default.xml") 104 | 105 | def parseFromFile(self, filePath): 106 | """ 107 | 从配置文件中解析配置项 108 | 真实项目中通过会将配置保存到配置文件中,保证下次开启时依然能够生效; 109 | 这里为简单起见,不从文件中读取,以初始化的方式来模拟。 110 | """ 111 | self.__fontType = "宋体" 112 | self.__fontSize = 14 113 | self.__language = "中文" 114 | self.__logPath = "./logs/appException.log" 115 | 116 | def saveToFile(self, filePath): 117 | """ 118 | 将配置保存到配置文件中 119 | 这里为简单起见,不再实现 120 | """ 121 | pass 122 | 123 | def copyConfig(self, configName): 124 | """创建一个配置的副本""" 125 | config = self.deepClone() 126 | config.__configName = configName 127 | return config 128 | 129 | def showInfo(self): 130 | print("%s 的配置信息如下:" % self.__configName) 131 | print("字体:", self.__fontType) 132 | print("字号:", self.__fontSize) 133 | print("语言:", self.__language) 134 | print("异常文件的路径:", self.__logPath) 135 | 136 | def setFontType(self, fontType): 137 | self.__fontType = fontType 138 | 139 | def setFontSize(self, fontSize): 140 | self.__fontSize = fontSize 141 | 142 | def setLanguage(self, language): 143 | self.__language = language 144 | 145 | def setLogPath(self, logPath): 146 | self.__logPath = logPath 147 | 148 | 149 | # Test 150 | #======================================================================================================================= 151 | 152 | def testClone(): 153 | tony = Person("Tony", 27) 154 | tony.showMyself() 155 | tony.coding() 156 | 157 | tony1 = tony.clone() 158 | tony1.showMyself() 159 | tony1.reading() 160 | 161 | tony2 = tony.clone() 162 | tony2.showMyself() 163 | tony2.fallInLove() 164 | 165 | 166 | def testPetStore(): 167 | petter = PetStore("Petter") 168 | petter.addPet("小狗Coco") 169 | print("父本petter:", end="") 170 | petter.showMyself() 171 | print() 172 | 173 | petter1 = deepcopy(petter) 174 | petter1.addPet("小猫Amy") 175 | print("副本petter1:", end="") 176 | petter1.showMyself() 177 | print("父本petter:", end="") 178 | petter.showMyself() 179 | print() 180 | 181 | petter2 = copy(petter) 182 | petter2.addPet("小兔Ricky") 183 | print("副本petter2:", end="") 184 | petter2.showMyself() 185 | print("父本petter:", end="") 186 | petter.showMyself() 187 | 188 | 189 | def testList(): 190 | list = [1, 2, 3]; 191 | list1 = list; 192 | print("id(list):", id(list)) 193 | print("id(list1):", id(list1)) 194 | print("修改之前:") 195 | print("list:", list) 196 | print("list1:", list1) 197 | list1.append(4); 198 | print("修改之后:") 199 | print("list:", list) 200 | print("list1:", list1) 201 | 202 | # petter = PetStore("Petter") 203 | # petter.addPet("小狗Coco") 204 | # print("父本tony:", end="") 205 | # petter.showMyself() 206 | # 207 | # petter1 = petter 208 | # petter1.addPet("小猫Amy") 209 | # print("副本tony1:", end="") 210 | # petter1.showMyself() 211 | # print("父本tony:", end="") 212 | # petter.showMyself() 213 | 214 | 215 | 216 | def testAppConfig(): 217 | defaultConfig = AppConfig("default") 218 | defaultConfig.showInfo() 219 | print() 220 | 221 | newConfig = defaultConfig.copyConfig("tonyConfig") 222 | newConfig.setFontType("雅黑") 223 | newConfig.setFontSize(18) 224 | newConfig.setLanguage("English") 225 | newConfig.showInfo() 226 | 227 | 228 | # testClone() 229 | # testPetStore() 230 | # testList() 231 | testAppConfig() -------------------------------------------------------------------------------- /pattern/Command.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 4/24/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class Chef(): 11 | """厨师""" 12 | 13 | def steamFood(self, originalMaterial): 14 | print("%s清蒸中..." % originalMaterial) 15 | return "清蒸" + originalMaterial 16 | 17 | def stirFriedFood(self, originalMaterial): 18 | print("%s爆炒中..." % originalMaterial) 19 | return "香辣炒" + originalMaterial 20 | 21 | class Order(metaclass=ABCMeta): 22 | """订单""" 23 | 24 | def __init__(self, name, originalMaterial): 25 | self._chef = Chef() 26 | self._name = name 27 | self._originalMaterial = originalMaterial 28 | 29 | def getDisplayName(self): 30 | return self._name + self._originalMaterial 31 | 32 | @abstractmethod 33 | def processingOrder(self): 34 | pass 35 | 36 | class SteamedOrder(Order): 37 | """清蒸""" 38 | 39 | def __init__(self, originalMaterial): 40 | super().__init__("清蒸", originalMaterial) 41 | 42 | def processingOrder(self): 43 | if(self._chef is not None): 44 | return self._chef.steamFood(self._originalMaterial) 45 | return "" 46 | 47 | 48 | class SpicyOrder(Order): 49 | """香辣炒""" 50 | 51 | def __init__(self, originalMaterial): 52 | super().__init__("香辣炒", originalMaterial) 53 | 54 | def processingOrder(self): 55 | if (self._chef is not None): 56 | return self._chef.stirFriedFood(self._originalMaterial) 57 | return "" 58 | 59 | 60 | class Waiter: 61 | """服务员""" 62 | 63 | def __init__(self, name): 64 | self.__name = name 65 | self.__order = None 66 | 67 | def receiveOrder(self, order): 68 | self.__order = order 69 | print("服务员%s:您的 %s 订单已经收到,请耐心等待" % (self.__name, order.getDisplayName()) ) 70 | 71 | def placeOrder(self): 72 | food = self.__order.processingOrder() 73 | print("服务员%s:您的餐 %s 已经准备好,请您慢用!" % (self.__name, food) ) 74 | 75 | 76 | 77 | # class Customer: 78 | # "顾客" 79 | # 80 | # def __init__(self, name): 81 | # self.__name = name 82 | # 83 | # def order(self): 84 | 85 | # Version 2.0 86 | #======================================================================================================================= 87 | # 代码框架 88 | #============================== 89 | from abc import ABCMeta, abstractmethod 90 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 91 | 92 | class Command(metaclass=ABCMeta): 93 | """命令的抽象类""" 94 | 95 | @abstractmethod 96 | def execute(self): 97 | pass 98 | 99 | class CommandImpl(Command): 100 | """命令的具体实现类""" 101 | 102 | def __init__(self, receiver): 103 | self.__receiver = receiver 104 | 105 | def execute(self): 106 | self.__receiver.doSomething() 107 | 108 | class Receiver: 109 | """命令的接收者""" 110 | 111 | def doSomething(self): 112 | print("do something...") 113 | 114 | class Invoker: 115 | """调度者""" 116 | 117 | def __init__(self): 118 | self.__command = None 119 | 120 | def setCommand(self, command): 121 | self.__command = command 122 | 123 | def action(self): 124 | if self.__command is not None: 125 | self.__command.execute() 126 | 127 | 128 | # 基于框架的实现 129 | #============================== 130 | 131 | # Test 132 | #======================================================================================================================= 133 | 134 | def testOrder(): 135 | waiter = Waiter("Anna") 136 | steamedOrder = SteamedOrder("大闸蟹") 137 | print("客户David:我要一份 %s" % steamedOrder.getDisplayName()) 138 | waiter.receiveOrder(steamedOrder) 139 | waiter.placeOrder() 140 | print() 141 | 142 | spicyOrder = SpicyOrder("大闸蟹") 143 | print("客户Tony:我要一份 %s" % spicyOrder.getDisplayName()) 144 | waiter.receiveOrder(spicyOrder) 145 | waiter.placeOrder() 146 | 147 | 148 | def client(): 149 | invoker = Invoker() 150 | command = CommandImpl(Receiver()) 151 | invoker.setCommand(command) 152 | invoker.action() 153 | 154 | 155 | # testOrder() 156 | client() 157 | 158 | -------------------------------------------------------------------------------- /pattern/ComputerComposite.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 12/16/2017 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class ComputerComponent(metaclass=ABCMeta): 11 | """组件,所有子配件的基类""" 12 | 13 | def __init__(self, name): 14 | self._name = name 15 | 16 | @abstractmethod 17 | def showInfo(self, indent = ""): 18 | pass 19 | 20 | def isComposite(self): 21 | return False 22 | 23 | def startup(self, indent = ""): 24 | print("%s%s 准备开始工作..." % (indent, self._name) ) 25 | 26 | def shutdown(self, indent = ""): 27 | print("%s%s 即将结束工作..." % (indent, self._name) ) 28 | 29 | 30 | class CPU(ComputerComponent): 31 | """中央处理器""" 32 | 33 | def __init__(self, name): 34 | super().__init__(name) 35 | 36 | def showInfo(self, indent): 37 | print("%sCPU:%s,可以进行高速计算。" % (indent, self._name)) 38 | 39 | 40 | class MemoryCard(ComputerComponent): 41 | """内存条""" 42 | 43 | def __init__(self, name): 44 | super().__init__(name) 45 | 46 | def showInfo(self, indent): 47 | print("%s内存:%s,可以缓存数据,读写速度快。" % (indent, self._name)) 48 | 49 | 50 | class HardDisk(ComputerComponent): 51 | """硬盘""" 52 | 53 | def __init__(self, name): 54 | super().__init__(name) 55 | 56 | def showInfo(self, indent): 57 | print("%s硬盘:%s,可以永久存储数据,容量大。" % (indent, self._name) ) 58 | 59 | 60 | class GraphicsCard(ComputerComponent): 61 | """显卡""" 62 | 63 | def __init__(self, name): 64 | super().__init__(name) 65 | 66 | def showInfo(self, indent): 67 | print("%s显卡:%s,可以高速计算和处理图形图像。" % (indent, self._name) ) 68 | 69 | 70 | class Battery(ComputerComponent): 71 | """电源""" 72 | 73 | def __init__(self, name): 74 | super().__init__(name) 75 | 76 | def showInfo(self, indent): 77 | print("%s电源:%s,可以持续给主板和外接配件供电。" % (indent, self._name) ) 78 | 79 | 80 | class Fan(ComputerComponent): 81 | """风扇""" 82 | 83 | def __init__(self, name): 84 | super().__init__(name) 85 | 86 | def showInfo(self, indent): 87 | print("%s风扇:%s,辅助CPU散热。" % (indent, self._name) ) 88 | 89 | 90 | class Displayer(ComputerComponent): 91 | """"显示器""" 92 | 93 | def __init__(self, name): 94 | super().__init__(name) 95 | 96 | def showInfo(self, indent): 97 | print("%s显示器:%s,负责内容的显示。" % (indent, self._name) ) 98 | 99 | 100 | class ComputerComposite(ComputerComponent): 101 | """配件组合器""" 102 | 103 | def __init__(self, name): 104 | super().__init__(name) 105 | self._components = [] 106 | 107 | def showInfo(self, indent): 108 | print("%s,由以下部件组成:" % (self._name) ) 109 | indent += "\t" 110 | for element in self._components: 111 | element.showInfo(indent) 112 | 113 | def isComposite(self): 114 | return True 115 | 116 | def addComponent(self, component): 117 | self._components.append(component) 118 | 119 | def removeComponent(self, component): 120 | self._components.remove(component) 121 | 122 | def startup(self, indent): 123 | super().startup(indent) 124 | indent += "\t" 125 | for element in self._components: 126 | element.startup(indent) 127 | 128 | def shutdown(self, indent): 129 | super().shutdown(indent) 130 | indent += "\t" 131 | for element in self._components: 132 | element.shutdown(indent) 133 | 134 | 135 | class Mainboard(ComputerComposite): 136 | """主板""" 137 | 138 | def __init__(self, name): 139 | super().__init__(name) 140 | 141 | def showInfo(self, indent): 142 | print(indent + "主板:", end="") 143 | super().showInfo(indent) 144 | 145 | 146 | class ComputerCase(ComputerComposite): 147 | """机箱""" 148 | 149 | def __init__(self, name): 150 | super().__init__(name) 151 | 152 | def showInfo(self, indent): 153 | print(indent + "机箱:", end="") 154 | super().showInfo(indent) 155 | 156 | 157 | class Computer(ComputerComposite): 158 | """电脑""" 159 | 160 | def __init__(self, name): 161 | super().__init__(name) 162 | 163 | def showInfo(self, indent): 164 | print(indent + "电脑:", end="") 165 | super().showInfo(indent) 166 | 167 | 168 | # Version 2.0 169 | #======================================================================================================================= 170 | # 代码框架 171 | #============================== 172 | 173 | from abc import ABCMeta, abstractmethod 174 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 175 | 176 | class Component(metaclass=ABCMeta): 177 | """组件""" 178 | 179 | def __init__(self, name): 180 | self._name = name 181 | 182 | def getName(self): 183 | return self._name 184 | 185 | def isComposite(self): 186 | return False 187 | 188 | @abstractmethod 189 | def feature(self, indent): 190 | # indent 仅用于内容输出时的缩进 191 | pass 192 | 193 | class Composite(Component): 194 | """复合组件""" 195 | 196 | def __init__(self, name): 197 | super().__init__(name) 198 | self._components = [] 199 | 200 | def addComponent(self, component): 201 | self._components.append(component) 202 | 203 | def removeComponent(self, component): 204 | self._components.remove(component) 205 | 206 | def isComposite(self): 207 | return True 208 | 209 | def feature(self, indent): 210 | indent += "\t" 211 | for component in self._components: 212 | print(indent, end="") 213 | component.feature(indent) 214 | 215 | 216 | 217 | class ComponentImplA(Component): 218 | "Test" 219 | 220 | def __init__(self, name): 221 | super().__init__(name) 222 | 223 | def feature(self): 224 | print("name:%s" % self._name) 225 | 226 | 227 | # 基于框架的实现 228 | #============================== 229 | import os 230 | # 引入 os 模块 231 | 232 | class FileDetail(Component): 233 | """谇详情""" 234 | def __init__(self, name): 235 | super().__init__(name) 236 | self._size = 0 237 | 238 | def setSize(self, size): 239 | self._size = size 240 | 241 | def getFileSize(self): 242 | return self._size 243 | 244 | def feature(self, indent): 245 | # 文件大小,单位:KB,精确度:2位小数 246 | fileSize = round(self._size / float(1024), 2) 247 | print("文件名称:%s, 文件大小:%sKB" % (self._name, fileSize) ) 248 | 249 | 250 | class FolderDetail(Composite): 251 | """文件夹详情""" 252 | 253 | def __init__(self, name): 254 | super().__init__(name) 255 | self._count = 0 256 | 257 | def setCount(self, fileNum): 258 | self._count = fileNum 259 | 260 | def getCount(self): 261 | return self._count 262 | 263 | def feature(self, indent): 264 | print("文件夹名:%s, 文件数量:%d。包含的文件:" % (self._name, self._count) ) 265 | super().feature(indent) 266 | 267 | 268 | def scanDir(rootPath, folderDetail): 269 | """扫描某一文件夹下的所有目录""" 270 | if not os.path.isdir(rootPath): 271 | raise ValueError("rootPath不是有效的路径:%s" % rootPath) 272 | 273 | if folderDetail is None: 274 | raise ValueError("folderDetail不能为空!") 275 | 276 | 277 | fileNames = os.listdir(rootPath) 278 | for fileName in fileNames: 279 | filePath = os.path.join(rootPath, fileName) 280 | if os.path.isdir(filePath): 281 | folder = FolderDetail(fileName) 282 | scanDir(filePath, folder) 283 | folderDetail.addComponent(folder) 284 | else: 285 | fileDetail = FileDetail(fileName) 286 | fileDetail.setSize(os.path.getsize(filePath)) 287 | folderDetail.addComponent(fileDetail) 288 | folderDetail.setCount(folderDetail.getCount() + 1) 289 | 290 | 291 | 292 | # Test 293 | #======================================================================================================================= 294 | def testComputer(): 295 | mainBoard = Mainboard("GIGABYTE Z170M M-ATX") 296 | mainBoard.addComponent(CPU("Intel Core i5-6600K")) 297 | mainBoard.addComponent(MemoryCard("Kingston Fury DDR4")) 298 | mainBoard.addComponent(HardDisk("Kingston V300 ")) 299 | mainBoard.addComponent(GraphicsCard("Colorful iGame750")) 300 | 301 | computerCase = ComputerCase("SAMA MATX") 302 | computerCase.addComponent(mainBoard) 303 | computerCase.addComponent(Battery("Antec VP 450P")) 304 | computerCase.addComponent(Fan("DEEPCOOL 120T")) 305 | 306 | computer = Computer("Tony DIY电脑") 307 | computer.addComponent(computerCase) 308 | computer.addComponent(Displayer("AOC LV243XIP")) 309 | 310 | computer.showInfo("") 311 | print("\n开机过程:") 312 | computer.startup("") 313 | print("\n关机过程:") 314 | computer.shutdown("") 315 | 316 | 317 | def testComposite(): 318 | tony = ComponentImplA("Tony") 319 | tony.feature() 320 | karry = ComponentImplA("Karry") 321 | composite = Composite("Composite") 322 | composite.addComponent(tony) 323 | composite.addComponent(karry) 324 | composite.feature() 325 | 326 | 327 | def testDir(): 328 | folder = FolderDetail("生活中的设计模式") 329 | scanDir("E:\生活中的设计模式", folder) 330 | folder.feature("") 331 | 332 | # isDir = os.path.isfile("D:\Test\file1.txt") 333 | # print(isDir) 334 | 335 | # testComputer() 336 | # testComposite() 337 | testDir() -------------------------------------------------------------------------------- /pattern/Decorator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 11/26/2017 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class Person(metaclass=ABCMeta): 11 | """人""" 12 | 13 | def __init__(self, name): 14 | self._name = name 15 | 16 | @abstractmethod 17 | def wear(self): 18 | print("着装:") 19 | 20 | 21 | class Engineer(Person): 22 | """工程师""" 23 | 24 | def __init__(self, name, skill): 25 | super().__init__(name) 26 | self.__skill = skill 27 | 28 | def getSkill(self): 29 | return self.__skill 30 | 31 | def wear(self): 32 | print("我是 " + self.getSkill() + "工程师 " + self._name, end=", ") 33 | super().wear() 34 | 35 | class Teacher(Person): 36 | "教师" 37 | 38 | def __init__(self, name, title): 39 | super().__init__(name) 40 | self.__title = title 41 | 42 | def getTitle(self): 43 | return self.__title 44 | 45 | def wear(self): 46 | print("我是 " + self._name + self.getTitle(), end=", ") 47 | super().wear() 48 | 49 | class ClothingDecorator(Person): 50 | """服装装饰器的基类""" 51 | 52 | def __init__(self, person): 53 | self._decorated = person 54 | 55 | def wear(self): 56 | self._decorated.wear() 57 | self.decorate() 58 | 59 | @abstractmethod 60 | def decorate(self): 61 | pass 62 | 63 | 64 | class CasualPantDecorator(ClothingDecorator): 65 | """休闲裤装饰器""" 66 | 67 | def __init__(self, person): 68 | super().__init__(person) 69 | 70 | def decorate(self): 71 | print("一条卡其色休闲裤") 72 | 73 | 74 | class BeltDecorator(ClothingDecorator): 75 | """腰带装饰器""" 76 | 77 | def __init__(self, person): 78 | super().__init__(person) 79 | 80 | def decorate(self): 81 | print("一条银色针扣头的黑色腰带") 82 | 83 | class LeatherShoesDecorator(ClothingDecorator): 84 | """皮鞋装饰器""" 85 | 86 | def __init__(self, person): 87 | super().__init__(person) 88 | 89 | def decorate(self): 90 | print("一双深色休闲皮鞋") 91 | 92 | class KnittedSweaterDecorator(ClothingDecorator): 93 | """针织毛衣装饰器""" 94 | 95 | def __init__(self, person): 96 | super().__init__(person) 97 | 98 | def decorate(self): 99 | print("一件紫红色针织毛衣") 100 | 101 | 102 | class WhiteShirtDecorator(ClothingDecorator): 103 | """白色衬衫装饰器""" 104 | 105 | def __init__(self, person): 106 | super().__init__(person) 107 | 108 | def decorate(self): 109 | print("一件白色衬衫") 110 | 111 | 112 | class GlassesDecorator(ClothingDecorator): 113 | """眼镜装饰器""" 114 | 115 | def __init__(self, person): 116 | super().__init__(person) 117 | 118 | def decorate(self): 119 | print("一副方形黑框眼镜") 120 | 121 | 122 | 123 | 124 | # Test 125 | #======================================================================================================================= 126 | def testDecorator(): 127 | tony = Engineer("Tony", "客户端") 128 | pant = CasualPantDecorator(tony) 129 | belt = BeltDecorator(pant) 130 | shoes = LeatherShoesDecorator(belt) 131 | shirt = WhiteShirtDecorator(shoes) 132 | sweater = KnittedSweaterDecorator(shirt) 133 | glasses = GlassesDecorator(sweater) 134 | glasses.wear() 135 | 136 | print() 137 | decorateTeacher = GlassesDecorator(WhiteShirtDecorator(LeatherShoesDecorator(Teacher("wells", "教授")))) 138 | decorateTeacher.wear() 139 | 140 | 141 | def testDecorator2(): 142 | tony = Engineer("Tony", "客户端") 143 | sweater = KnittedSweaterDecorator(tony) 144 | shirt = WhiteShirtDecorator(sweater) 145 | glasses = GlassesDecorator(shirt) 146 | glasses.wear() 147 | 148 | # testDecorator() 149 | # testDecorator2() -------------------------------------------------------------------------------- /pattern/Facade.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 6/23/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | class Register: 8 | """报到登记""" 9 | 10 | def register(self, name): 11 | print("活动中心:%s同学报到成功!" % name) 12 | 13 | 14 | class Payment: 15 | """缴费中心""" 16 | 17 | def pay(self, name, money): 18 | print("缴费中心:收到%s同学%s元付款,缴费成功!" % (name, money) ) 19 | 20 | 21 | class DormitoryManagementCenter: 22 | """生活中心(宿舍管理中心)""" 23 | 24 | def provideLivingGoods(self, name): 25 | print("生活中心:%s同学的生活用品已发放。" % name) 26 | 27 | 28 | class Dormitory: 29 | """宿舍""" 30 | 31 | def meetRoommate(self, name): 32 | print("宿 舍:" + "大家好!这是刚来的%s同学,是你们未来需要共度四年的室友!相互认识一下……" % name) 33 | 34 | 35 | class Volunteer: 36 | """迎新志愿者""" 37 | 38 | def __init__(self, name): 39 | self.__name = name 40 | self.__register = Register() 41 | self.__payment = Payment() 42 | self.__lifeCenter = DormitoryManagementCenter() 43 | self.__dormintory = Dormitory() 44 | 45 | def welcomeFreshmen(self, name): 46 | print("你好,%s同学! 我是新生报到的志愿者%s,我将带你完成整个报到流程。" % (name, self.__name)) 47 | self.__register.register(name) 48 | self.__payment.pay(name, 10000) 49 | self.__lifeCenter.provideLivingGoods(name) 50 | self.__dormintory.meetRoommate(name) 51 | 52 | 53 | # Version 2.0 54 | #======================================================================================================================= 55 | # 代码框架 56 | #============================== 57 | 58 | 59 | # 基于框架的实现 60 | #============================== 61 | from os import path 62 | # 引入path,进行路径相关的处理 63 | import logging 64 | # 引入logging,进行错误时的日志记录 65 | 66 | class ZIPModel: 67 | """ZIP模块,负责ZIP文件的压缩与解压 68 | 这里只进行简单模拟,不进行具体的解压缩逻辑""" 69 | 70 | def compress(self, srcFilePath, dstFilePath): 71 | print("ZIP模块正在进行“%s”文件的压缩......" % srcFilePath) 72 | print("文件压缩成功,已保存至“%s”" % dstFilePath) 73 | 74 | def decompress(self, srcFilePath, dstFilePath): 75 | print("ZIP模块正在进行“%s”文件的解压......" % srcFilePath) 76 | print("文件解压成功,已保存至“%s”" % dstFilePath) 77 | 78 | 79 | class RARModel: 80 | """RAR模块,负责RAR文件的压缩与解压 81 | 这里只进行简单模拟,不进行具体的解压缩逻辑""" 82 | 83 | def compress(self, srcFilePath, dstFilePath): 84 | print("RAR模块正在进行“%s”文件的压缩......" % srcFilePath) 85 | print("文件压缩成功,已保存至“%s”" % dstFilePath) 86 | 87 | def decompress(self, srcFilePath, dstFilePath): 88 | print("RAR模块正在进行“%s”文件的解压......" % srcFilePath) 89 | print("文件解压成功,已保存至“%s”" % dstFilePath) 90 | 91 | 92 | class ZModel: 93 | """7Z模块,负责7Z文件的压缩与解压 94 | 这里只进行简单模拟,不进行具体的解压缩逻辑""" 95 | 96 | def compress(self, srcFilePath, dstFilePath): 97 | print("7Z模块正在进行“%s”文件的压缩......" % srcFilePath) 98 | print("文件压缩成功,已保存至“%s”" % dstFilePath) 99 | 100 | def decompress(self, srcFilePath, dstFilePath): 101 | print("7Z模块正在进行“%s”文件的解压......" % srcFilePath) 102 | print("文件解压成功,已保存至“%s”" % dstFilePath) 103 | 104 | 105 | class CompressionFacade: 106 | """压缩系统的外观类""" 107 | 108 | def __init__(self): 109 | self.__zipModel = ZIPModel() 110 | self.__rarModel = RARModel() 111 | self.__zModel = ZModel() 112 | 113 | def compress(self, srcFilePath, dstFilePath, type): 114 | """根据不同的压缩类型,压缩成不同的格式""" 115 | # 获取新的文件名 116 | extName = "." + type 117 | fullName = dstFilePath + extName 118 | if (type.lower() == "zip") : 119 | self.__zipModel.compress(srcFilePath, fullName) 120 | elif(type.lower() == "rar"): 121 | self.__rarModel.compress(srcFilePath, fullName) 122 | elif(type.lower() == "7z"): 123 | self.__zModel.compress(srcFilePath, fullName) 124 | else: 125 | logging.error("Not support this format:" + str(type)) 126 | return False 127 | return True 128 | 129 | def decompress(self, srcFilePath, dstFilePath): 130 | """从srcFilePath中获取后缀,根据不同的后缀名(拓展名),进行不同格式的解压""" 131 | baseName = path.basename(srcFilePath) 132 | extName = baseName.split(".")[1] 133 | if (extName.lower() == "zip") : 134 | self.__zipModel.decompress(srcFilePath, dstFilePath) 135 | elif(extName.lower() == "rar"): 136 | self.__rarModel.decompress(srcFilePath, dstFilePath) 137 | elif(extName.lower() == "7z"): 138 | self.__zModel.decompress(srcFilePath, dstFilePath) 139 | else: 140 | logging.error("Not support this format:" + str(extName)) 141 | return False 142 | return True 143 | 144 | 145 | # Test 146 | #======================================================================================================================= 147 | def testRegister(): 148 | volunteer = Volunteer("Frank") 149 | volunteer.welcomeFreshmen("Tony") 150 | 151 | 152 | def testCompression(): 153 | facade = CompressionFacade() 154 | facade.compress("E:\标准文件\生活中的外观模式.md", 155 | "E:\压缩文件\生活中的外观模式", "zip") 156 | facade.decompress("E:\压缩文件\生活中的外观模式.zip", 157 | "E:\标准文件\生活中的外观模式.md") 158 | print() 159 | 160 | facade.compress("E:\标准文件\Python编程——从入门到实践.pdf", 161 | "E:\压缩文件\Python编程——从入门到实践", "rar") 162 | facade.decompress("E:\压缩文件\Python编程——从入门到实践.rar", 163 | "E:\标准文件\Python编程——从入门到实践.pdf") 164 | print() 165 | 166 | facade.compress("E:\标准文件\谈谈我对项目重构的看法.doc", 167 | "E:\压缩文件\谈谈我对项目重构的看法", "7z") 168 | facade.decompress("E:\压缩文件\谈谈我对项目重构的看法.7z", 169 | "E:\标准文件\谈谈我对项目重构的看法.doc") 170 | print() 171 | 172 | 173 | def testPath(): 174 | filePath = "E:\解析文件\生活中的外观模式——学妹别慌,学长帮你.md" 175 | dirName = path.dirname(filePath) 176 | baseName = path.basename(filePath) 177 | fileName, extName = baseName.split('.') 178 | fullName = path.join(dirName, fileName + extName) 179 | i = 0 180 | 181 | 182 | # testRegister() 183 | testCompression() 184 | # testPath() -------------------------------------------------------------------------------- /pattern/Flyweight.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 6/4/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | import logging 8 | # 引入logging模块记录异常 9 | 10 | class Pigment: 11 | """颜料""" 12 | 13 | def __init__(self, color): 14 | self.__color = color 15 | self.__user = "" 16 | 17 | def getColor(self): 18 | return self.__color 19 | 20 | def setUser(self, user): 21 | self.__user = user 22 | return self 23 | 24 | def showInfo(self): 25 | print("%s 取得 %s色颜料" % (self.__user, self.__color) ) 26 | 27 | class PigmengFactory: 28 | """资料的工厂类""" 29 | 30 | def __init__(self): 31 | self.__sigmentSet = { 32 | "红": Pigment("红"), 33 | "黄": Pigment("黄"), 34 | "蓝": Pigment("蓝"), 35 | "绿": Pigment("绿"), 36 | "紫": Pigment("紫"), 37 | } 38 | 39 | def getPigment(self, color): 40 | pigment = self.__sigmentSet.get(color) 41 | if pigment is None: 42 | logging.error("没有%s颜色的颜料!", color) 43 | return pigment 44 | 45 | 46 | # Version 2.0 47 | #======================================================================================================================= 48 | # 代码框架 49 | #============================== 50 | from abc import ABCMeta, abstractmethod 51 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 52 | 53 | class Flyweight(metaclass=ABCMeta): 54 | """享元类""" 55 | 56 | @abstractmethod 57 | def operation(self, extrinsicState): 58 | pass 59 | 60 | class FlyweightImpl(Flyweight): 61 | """享元类的具体实现类""" 62 | 63 | def __init__(self, color): 64 | self.__color = color 65 | 66 | def operation(self, extrinsicState): 67 | print("%s 取得 %s色颜料" % (extrinsicState, self.__color)) 68 | 69 | class FlyweightFactory: 70 | """享元工厂""" 71 | 72 | def __init__(self): 73 | self.__flyweights = {} 74 | 75 | def getFlyweight(self, key): 76 | pigment = self.__flyweights.get(key) 77 | if pigment is None: 78 | pigment = FlyweightImpl(key) 79 | return pigment 80 | 81 | # 基于框架的实现 82 | #============================== 83 | 84 | 85 | # Test 86 | #======================================================================================================================= 87 | def testPigment(): 88 | factory = PigmengFactory() 89 | pigmentRed = factory.getPigment("红").setUser("梦之队") 90 | pigmentRed.showInfo() 91 | pigmentYellow = factory.getPigment("黄").setUser("梦之队") 92 | pigmentYellow.showInfo() 93 | pigmentBlue1 = factory.getPigment("蓝").setUser("梦之队") 94 | pigmentBlue1.showInfo() 95 | pigmentBlue2 = factory.getPigment("蓝").setUser("和平队") 96 | pigmentBlue2.showInfo() 97 | 98 | 99 | def testFlyweight(): 100 | factory = FlyweightFactory() 101 | pigmentRed = factory.getFlyweight("红") 102 | pigmentRed.operation("梦之队") 103 | pigmentYellow = factory.getFlyweight("黄") 104 | pigmentYellow.operation("梦之队") 105 | pigmentBlue1 = factory.getFlyweight("蓝") 106 | pigmentBlue1.operation("梦之队") 107 | pigmentBlue2 = factory.getFlyweight("蓝") 108 | pigmentBlue2.operation("和平队") 109 | 110 | 111 | # print("Blue1:" + str(id(pigmentBlue1)) + ", Bule2:" + str(id(pigmentBlue2)) 112 | # + ", Blue1==Blue2:" + str(pigmentBlue1 == pigmentBlue2)) 113 | 114 | 115 | 116 | # testPigment() 117 | testFlyweight() 118 | -------------------------------------------------------------------------------- /pattern/Interpreter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 7/14/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class Expression(metaclass=ABCMeta): 11 | """抽象表达式""" 12 | 13 | @abstractmethod 14 | def interpreter(self, var): 15 | pass 16 | 17 | 18 | class VarExpression(Expression): 19 | """变量解析器""" 20 | 21 | def __init__(self, key): 22 | self.__key = key 23 | 24 | def interpreter(self, var): 25 | return var.get(self.__key) 26 | 27 | 28 | class SymbolExpression(Expression): 29 | """运算符解析器,运算符的抽象类""" 30 | 31 | def __init__(self, left, right): 32 | self._left = left 33 | self._right = right 34 | 35 | 36 | class AddExpression(SymbolExpression): 37 | """加法解析器""" 38 | 39 | def __init__(self, left, right): 40 | super().__init__(left, right) 41 | 42 | def interpreter(self, var): 43 | return self._left.interpreter(var) + self._right.interpreter(var) 44 | 45 | 46 | class SubExpression(SymbolExpression): 47 | """减法解析器""" 48 | 49 | def __init__(self, left, right): 50 | super().__init__(left, right) 51 | 52 | def interpreter(self, var): 53 | return self._left.interpreter(var) - self._right.interpreter(var) 54 | 55 | 56 | 57 | class Stack: 58 | """封装一个堆栈类""" 59 | 60 | def __init__(self): 61 | self.items = [] 62 | 63 | def isEmpty(self): 64 | return len(self.items) == 0 65 | 66 | def push(self, item): 67 | self.items.append(item) 68 | 69 | def pop(self): 70 | return self.items.pop() 71 | 72 | def peek(self): 73 | if not self.isEmpty(): 74 | return self.items[len(self.items) - 1] 75 | 76 | def size(self): 77 | return len(self.items) 78 | 79 | 80 | class Calculator: 81 | """计算器类""" 82 | 83 | def __init__(self, text): 84 | self.__expression = self.parserText(text) 85 | 86 | def parserText(self, expText): 87 | # 定义一个栈,处理运算的先后顺序 88 | stack = Stack() 89 | left = right = None # 左右表达式 90 | idx = 0 91 | while(idx < len(expText)): 92 | if (expText[idx] == '+'): 93 | left = stack.pop() 94 | idx += 1 95 | right = VarExpression(expText[idx]) 96 | stack.push(AddExpression(left, right)) 97 | elif(expText[idx] == '-'): 98 | left = stack.pop() 99 | idx += 1 100 | right = VarExpression(expText[idx]) 101 | stack.push(SubExpression(left, right)) 102 | else: 103 | stack.push(VarExpression(expText[idx])) 104 | idx += 1 105 | return stack.pop() 106 | 107 | def run(self, var): 108 | return self.__expression.interpreter(var) 109 | 110 | 111 | 112 | 113 | 114 | # Version 2.0 115 | #======================================================================================================================= 116 | # 代码框架 117 | #============================== 118 | 119 | 120 | # 基于框架的实现 121 | #============================== 122 | 123 | 124 | # Test 125 | #======================================================================================================================= 126 | 127 | def testStack(): 128 | s = Stack() 129 | print(s.isEmpty()) 130 | s.push(4) 131 | s.push('dog') 132 | print(s.peek()) 133 | s.push(True) 134 | print(s.size()) 135 | print(s.isEmpty()) 136 | s.push(8.4) 137 | print(s.pop()) 138 | print(s.pop()) 139 | print(s.size()) 140 | 141 | 142 | 143 | def testCalculator(): 144 | # 获取表达式 145 | expStr = input("请输入表达式:"); 146 | # 获取各参数的键值对 147 | newExp, expressionMap = getMapValue(expStr) 148 | calculator = Calculator(newExp) 149 | result = calculator.run(expressionMap) 150 | print("运算结果为:" + expStr + " = " + str(result)) 151 | 152 | def getMapValue(expStr): 153 | preIdx = 0 154 | expressionMap = {} 155 | newExp = [] 156 | for i in range(0, len(expStr)): 157 | if (expStr[i] == '+' or expStr[i] == '-'): 158 | key = expStr[preIdx:i] 159 | key = key.strip() # 去除前后空字符 160 | newExp.append(key) 161 | newExp.append(expStr[i]) 162 | var = input("请输入参数" + key + "的值:"); 163 | var = var.strip() 164 | expressionMap[key] = float(var) 165 | preIdx = i + 1 166 | 167 | # 处理最后一个参数 168 | key = expStr[preIdx:len(expStr)] 169 | key = key.strip() # 去除前后空字符 170 | newExp.append(key) 171 | var = input("请输入参数" + key + "的值:"); 172 | var = var.strip() 173 | expressionMap[key] = float(var) 174 | 175 | return newExp, expressionMap 176 | 177 | 178 | # testStack() 179 | testCalculator() -------------------------------------------------------------------------------- /pattern/Iterator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 12/7/2017 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | 8 | class Customer: 9 | """客户""" 10 | 11 | def __init__(self, name): 12 | self.__name = name 13 | self.__num = 0 14 | self.__clinics = None 15 | 16 | def getName(self): 17 | return self.__name 18 | 19 | def register(self, system): 20 | system.pushCustomer(self) 21 | 22 | def setNum(self, num): 23 | self.__num = num 24 | 25 | def getNum(self): 26 | return self.__num 27 | 28 | def setClinic(self, clinic): 29 | self.__clinics = clinic 30 | 31 | def getClinic(self): 32 | return self.__clinics 33 | 34 | 35 | class NumeralIterator: 36 | """迭代器""" 37 | 38 | def __init__(self, data): 39 | self.__data = data 40 | self.__curIdx = -1 41 | 42 | def next(self): 43 | """移动至下一个元素""" 44 | if (self.__curIdx < len(self.__data) - 1): 45 | self.__curIdx += 1 46 | return True 47 | else: 48 | return False 49 | 50 | def current(self): 51 | """获取当前的元素""" 52 | return self.__data[self.__curIdx] if (self.__curIdx < len(self.__data) and self.__curIdx >= 0) else None 53 | 54 | 55 | class NumeralSystem: 56 | """排号系统""" 57 | 58 | __clinics = ("1号分诊室", "2号分诊室", "3号分诊室") 59 | 60 | def __init__(self, name): 61 | self.__customers = [] 62 | self.__curNum = 0 63 | self.__name = name 64 | 65 | def pushCustomer(self, customer): 66 | customer.setNum(self.__curNum + 1) 67 | click = NumeralSystem.__clinics[self.__curNum % len(NumeralSystem.__clinics)] 68 | customer.setClinic(click) 69 | self.__curNum += 1 70 | self.__customers.append(customer) 71 | print("%s 您好!您已在%s成功挂号,序号:%04d,请耐心等待!" 72 | % (customer.getName(), self.__name, customer.getNum()) ) 73 | 74 | def getIterator(self): 75 | return NumeralIterator(self.__customers) 76 | 77 | 78 | def visit(self): 79 | for customer in self.__customers: 80 | print("下一位病人 %04d(%s) 请到 %s 就诊。" 81 | % (customer.getNum(), customer.getName(), customer.getClinic()) ) 82 | 83 | 84 | # Version 2.0 85 | #======================================================================================================================= 86 | # 代码框架 87 | #============================== 88 | class BaseIterator: 89 | """迭代器""" 90 | 91 | def __init__(self, data): 92 | self.__data = data 93 | self.toBegin() 94 | 95 | def toBegin(self): 96 | """将指针移至起始位置""" 97 | self.__curIdx = -1 98 | 99 | def toEnd(self): 100 | """将指针移至结尾位置""" 101 | self.__curIdx = len(self.__data) 102 | 103 | def next(self): 104 | """移动至下一个元素""" 105 | if (self.__curIdx < len(self.__data) - 1): 106 | self.__curIdx += 1 107 | return True 108 | else: 109 | return False 110 | 111 | def previous(self): 112 | "移动至上一个元素" 113 | if (self.__curIdx > 0): 114 | self.__curIdx -= 1 115 | return True 116 | else: 117 | return False 118 | 119 | def current(self): 120 | """获取当前的元素""" 121 | return self.__data[self.__curIdx] if (self.__curIdx < len(self.__data) and self.__curIdx >= 0) else None 122 | 123 | 124 | # 基于框架的实现 125 | #============================== 126 | 127 | 128 | # Test 129 | #======================================================================================================================= 130 | 131 | def testHospital(): 132 | numeralSystem = NumeralSystem("挂号台") 133 | lily = Customer("Lily") 134 | lily.register(numeralSystem); 135 | pony = Customer("Pony") 136 | pony.register(numeralSystem) 137 | nick = Customer("Nick") 138 | nick.register(numeralSystem) 139 | tony = Customer("Tony") 140 | tony.register(numeralSystem) 141 | print() 142 | 143 | iterator = numeralSystem.getIterator() 144 | while(iterator.next()): 145 | customer = iterator.current() 146 | print("下一位病人 %04d(%s) 请到 %s 就诊。" 147 | % (customer.getNum(), customer.getName(), customer.getClinic()) ) 148 | 149 | # numeralSystem.visit() 150 | 151 | 152 | 153 | def testBaseIterator(): 154 | print("从前往后遍历:") 155 | iterator = BaseIterator(range(0, 10)) 156 | while(iterator.next()): 157 | customer = iterator.current() 158 | print(customer, end="\t") 159 | print() 160 | 161 | print("从后往前遍历:") 162 | iterator.toEnd() 163 | while (iterator.previous()): 164 | customer = iterator.current() 165 | print(customer, end="\t") 166 | 167 | 168 | 169 | 170 | 171 | 172 | def testLoop(): 173 | arr = [0, 1, 2, 3, 4, 5, 6, 7 ,8 , 9]; 174 | for e in arr: 175 | print(e, end="\t") 176 | 177 | 178 | # 方法一:使用()定义生成器 179 | gen = (x * x for x in range(10)) 180 | 181 | # 方法二:使用yield定义generator函数 182 | def fibonacci(maxNum): 183 | """斐波那契数列的生成器""" 184 | a = b = 1 185 | for i in range(maxNum): 186 | yield a 187 | a, b = b, a + b 188 | 189 | def testIterable(): 190 | print("方法一,0-9的平方数:") 191 | for e in gen: 192 | print(e, end="\t") 193 | print() 194 | 195 | print("方法二,斐波那契数列:") 196 | fib = fibonacci(10) 197 | for n in fib: 198 | print(n, end="\t") 199 | print() 200 | 201 | print("内置容器的for循环:") 202 | arr = [x * x for x in range(10)] 203 | for e in arr: 204 | print(e, end="\t") 205 | print() 206 | 207 | print() 208 | print(type(gen)) 209 | print(type(fib)) 210 | print(type(arr)) 211 | 212 | 213 | from collections import Iterable, Iterator 214 | # 引入Iterable和Iterator 215 | 216 | def testIsIterator(): 217 | print("是否为Iterable对象:") 218 | print(isinstance([], Iterable)) 219 | print(isinstance({}, Iterable)) 220 | print(isinstance((1, 2, 3), Iterable)) 221 | print(isinstance(set([1, 2, 3]), Iterable)) 222 | print(isinstance("string", Iterable)) 223 | print(isinstance(gen, Iterable)) 224 | print(isinstance(fibonacci(10), Iterable)) 225 | print("是否为Iterator对象:") 226 | print(isinstance([], Iterator)) 227 | print(isinstance({}, Iterator)) 228 | print(isinstance((1, 2, 3), Iterator)) 229 | print(isinstance(set([1, 2, 3]), Iterator)) 230 | print(isinstance("string", Iterator)) 231 | print(isinstance(gen, Iterator)) 232 | print(isinstance(fibonacci(10), Iterator)) 233 | 234 | 235 | def testNextItem(): 236 | print("将Iterable对象转成Iterator对象:") 237 | l = [1, 2, 3] 238 | itrL = iter(l) 239 | print(next(itrL)) 240 | print(next(itrL)) 241 | print(next(itrL)) 242 | 243 | print("next()函数遍历迭代器元素:") 244 | fib = fibonacci(4) 245 | print(next(fib)) 246 | print(next(fib)) 247 | print(next(fib)) 248 | print(next(fib)) 249 | # print(next(fib)) 250 | 251 | 252 | class NumberSequence: 253 | """生成一个间隔为step的数字系列""" 254 | 255 | def __init__(self, init, step, max = 100): 256 | self.__data = init 257 | self.__step = step 258 | self.__max = max 259 | 260 | def __iter__(self): 261 | return self 262 | 263 | def __next__(self): 264 | if(self.__data < self.__max): 265 | tmp = self.__data 266 | self.__data += self.__step 267 | return tmp 268 | else: 269 | raise StopIteration 270 | 271 | 272 | def testNumberSequence(): 273 | numSeq = NumberSequence(0, 5, 20) 274 | print(isinstance(numSeq, Iterable)) 275 | print(isinstance(numSeq, Iterator)) 276 | for n in numSeq: 277 | print(n, end="\t") 278 | 279 | 280 | # testHospital() 281 | # testBaseIterator() 282 | # testLoop() 283 | # testIterable() 284 | testIsIterator() 285 | # testNextItem() 286 | # testNumberSequence() 287 | 288 | -------------------------------------------------------------------------------- /pattern/Mediator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 11/17/2017 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | class HouseInfo: 8 | """房源信息""" 9 | 10 | def __init__(self, area, price, hasWindow, hasBathroom, hasKitchen, address, owner): 11 | self.__area = area 12 | self.__price = price 13 | self.__hasWindow = hasWindow 14 | self.__hasBathroom = hasBathroom 15 | self.__hasKitchen = hasKitchen 16 | self.__address = address 17 | self.__owner = owner 18 | 19 | def getAddress(self): 20 | return self.__address 21 | 22 | def getOwnerName(self): 23 | return self.__owner.getName() 24 | 25 | def showInfo(self, isShowOwner = True): 26 | print("面积:" + str(self.__area) + "平米", 27 | "价格:" + str(self.__price) + "元", 28 | "窗户:" + ("有" if self.__hasWindow else "没有"), 29 | "卫生间:" + self.__hasBathroom, 30 | "厨房:" + ("有" if self.__hasKitchen else "没有"), 31 | "地址:" + self.__address, 32 | "房东:" + self.getOwnerName() if isShowOwner else "") 33 | 34 | 35 | class HousingAgency: 36 | """房屋中介""" 37 | 38 | def __init__(self, name): 39 | self.__houseInfos = [] 40 | self.__name = name 41 | 42 | def getName(self): 43 | return self.__name 44 | 45 | def addHouseInfo(self, houseInfo): 46 | self.__houseInfos.append(houseInfo) 47 | 48 | def removeHouseInfo(self, houseInfo): 49 | for info in self.__houseInfos: 50 | if(info == houseInfo): 51 | self.__houseInfos.remove(info) 52 | 53 | def getSearchCondition(self, description): 54 | """这里有一个将用户描述信息转换成搜索条件的逻辑 55 | (为节省篇幅这里原样返回描述)""" 56 | return description 57 | 58 | def getMatchInfos(self, searchCondition): 59 | """根据房源信息的各个属性查找最匹配的信息 60 | (为节省篇幅这里略去匹配的过程,全部输出)""" 61 | print(self.getName(), "为您找到以下最适合的房源:") 62 | for info in self.__houseInfos: 63 | info.showInfo(False) 64 | return self.__houseInfos 65 | 66 | def signContract(self, houseInfo, period): 67 | """与房东签订协议""" 68 | print(self.getName(), "与房东", houseInfo.getOwnerName(), "签订", houseInfo.getAddress(), 69 | "的房子的的租赁合同,租期", period, "年。 合同期内", self.getName(), "有权对其进行使用和转租!") 70 | 71 | def signContracts(self, period): 72 | for info in self.__houseInfos : 73 | self.signContract(info, period) 74 | 75 | 76 | class HouseOwner: 77 | """房东""" 78 | 79 | def __init__(self, name): 80 | self.__name = name 81 | self.__houseInfo = None 82 | 83 | def getName(self): 84 | return self.__name 85 | 86 | def setHouseInfo(self, address, area, price, hasWindow, bathroom, kitchen): 87 | self.__houseInfo = HouseInfo(area, price, hasWindow, bathroom, kitchen, address, self) 88 | 89 | def publishHouseInfo(self, agency): 90 | agency.addHouseInfo(self.__houseInfo) 91 | print(self.getName() + "在", agency.getName(), "发布房源出租信息:") 92 | self.__houseInfo.showInfo() 93 | 94 | 95 | class Customer: 96 | """用户,租房的贫下中农""" 97 | 98 | def __init__(self, name): 99 | self.__name = name 100 | 101 | def getName(self): 102 | return self.__name 103 | 104 | def findHouse(self, description, agency): 105 | print("我是" + self.getName() + ", 我想要找一个\"" + description + "\"的房子") 106 | print() 107 | return agency.getMatchInfos(agency.getSearchCondition(description)) 108 | 109 | def seeHouse(self, houseInfos): 110 | """去看房,选择最使用的房子 111 | (这里省略看房的过程)""" 112 | size = len(houseInfos) 113 | return houseInfos[size-1] 114 | 115 | def signContract(self, houseInfo, agency, period): 116 | """与中介签订协议""" 117 | print(self.getName(), "与中介", agency.getName(), "签订", houseInfo.getAddress(), 118 | "的房子的租赁合同, 租期", period, "年。合同期内", self.__name, "有权对其进行使用!") 119 | 120 | # Version 2.0 121 | #======================================================================================================================= 122 | # 代码框架 123 | #============================== 124 | class InteractiveObject: 125 | """进行交互的对象""" 126 | pass 127 | 128 | class InteractiveObjectImplA: 129 | """实现类A""" 130 | pass 131 | 132 | class InteractiveObjectImplB: 133 | """实现类B""" 134 | pass 135 | 136 | class Meditor: 137 | """中介类""" 138 | 139 | def __init__(self): 140 | self.__interactiveObjA = InteractiveObjectImplA() 141 | self.__interactiveObjB = InteractiveObjectImplB() 142 | 143 | def interative(self): 144 | """进行交互的操作""" 145 | # 通过self.__interactiveObjA和self.__interactiveObjB完成相应的交互操作 146 | pass 147 | 148 | 149 | # 基于框架的实现 150 | #============================== 151 | from abc import ABCMeta, abstractmethod 152 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 153 | from enum import Enum 154 | # Python3.4 之后支持枚举Enum的语法 155 | 156 | class DeviceType(Enum): 157 | "设备类型" 158 | TypeSpeaker = 1 159 | TypeMicrophone = 2 160 | TypeCamera = 3 161 | 162 | class DeviceItem: 163 | """设备项""" 164 | 165 | def __init__(self, id, name, type, isDefault = False): 166 | self.__id = id 167 | self.__name = name 168 | self.__type = type 169 | self.__isDefault = isDefault 170 | 171 | def __str__(self): 172 | return "type:" + str(self.__type) + " id:" + str(self.__id) \ 173 | + " name:" + str(self.__name) + " isDefault:" + str(self.__isDefault) 174 | 175 | def getId(self): 176 | return self.__id 177 | 178 | def getName(self): 179 | return self.__name 180 | 181 | def getType(self): 182 | return self.__type 183 | 184 | def isDefault(self): 185 | return self.__isDefault 186 | 187 | 188 | class DeviceList: 189 | """设备列表""" 190 | 191 | def __init__(self): 192 | self.__devices = [] 193 | 194 | def add(self, deviceItem): 195 | self.__devices.append(deviceItem) 196 | 197 | def getCount(self): 198 | return len(self.__devices) 199 | 200 | def getByIdx(self, idx): 201 | if idx < 0 or idx >= self.getCount(): 202 | return None 203 | return self.__devices[idx] 204 | 205 | def getById(self, id): 206 | for item in self.__devices: 207 | if( item.getId() == id): 208 | return item 209 | return None 210 | 211 | class DeviceMgr(metaclass=ABCMeta): 212 | 213 | @abstractmethod 214 | def enumerate(self): 215 | """枚举设备列表 216 | (在程序初始化时,有设备插拔时都要重新获取设备列表)""" 217 | pass 218 | 219 | @abstractmethod 220 | def active(self, deviceId): 221 | """选择要使用的设备""" 222 | pass 223 | 224 | @abstractmethod 225 | def getCurDeviceId(self): 226 | """获取当前正在使用的设计ID""" 227 | pass 228 | 229 | 230 | class SpeakerMgr(DeviceMgr): 231 | """扬声器设备管理类""" 232 | 233 | def __init__(self): 234 | self.__curDeviceId = None 235 | 236 | def enumerate(self): 237 | """枚举设备列表 238 | (真实的项目应该通过驱动程序去读取设备信息,这里只用初始化来模拟)""" 239 | devices = DeviceList() 240 | devices.add(DeviceItem("369dd760-893b-4fe0-89b1-671eca0f0224", "Realtek High Definition Audio", DeviceType.TypeSpeaker)) 241 | devices.add(DeviceItem("59357639-6a43-4b79-8184-f79aed9a0dfc", "NVIDIA High Definition Audio", DeviceType.TypeSpeaker, True)) 242 | return devices 243 | 244 | def active(self, deviceId): 245 | """激活指定的设备作为当前要用的设备""" 246 | self.__curDeviceId = deviceId 247 | 248 | def getCurDeviceId(self): 249 | return self.__curDeviceId 250 | 251 | 252 | class DeviceUtil: 253 | """设备工具类""" 254 | 255 | def __init__(self): 256 | self.__mgrs = {} 257 | self.__mgrs[DeviceType.TypeSpeaker] = SpeakerMgr() 258 | # 为节省篇幅,MicrophoneMgr和CameraMgr不再实现 259 | # self.__microphoneMgr = MicrophoneMgr() 260 | # self.__cameraMgr = CameraMgr 261 | 262 | def __getDeviceMgr(self, type): 263 | return self.__mgrs[type] 264 | 265 | def getDeviceList(self, type): 266 | return self.__getDeviceMgr(type).enumerate() 267 | 268 | def active(self, type, deviceId): 269 | self.__getDeviceMgr(type).active(deviceId) 270 | 271 | def getCurDeviceId(self, type): 272 | return self.__getDeviceMgr(type).getCurDeviceId() 273 | 274 | 275 | # Test 276 | #======================================================================================================================= 277 | 278 | def testRenting(): 279 | myHome = HousingAgency("我爱我家") 280 | zhangsan = HouseOwner("张三"); 281 | zhangsan.setHouseInfo("上地西里", 20, 2500, 1, "独立卫生间", 0) 282 | zhangsan.publishHouseInfo(myHome) 283 | lisi = HouseOwner("李四") 284 | lisi.setHouseInfo("当代城市家园", 16, 1800, 1, "公用卫生间", 0) 285 | lisi.publishHouseInfo(myHome) 286 | wangwu = HouseOwner("王五") 287 | wangwu.setHouseInfo("金隅美和园", 18, 2600, 1, "独立卫生间", 1) 288 | wangwu.publishHouseInfo(myHome) 289 | print() 290 | 291 | myHome.signContracts(3) 292 | print() 293 | 294 | tony = Customer("Tony") 295 | houseInfos = tony.findHouse("18平米左右,要有独卫,要有窗户,最好是朝南,有厨房更好!价位在2000左右", myHome) 296 | print() 297 | print("正在看房,寻找最合适的住巢……") 298 | print() 299 | AppropriateHouse = tony.seeHouse(houseInfos) 300 | tony.signContract(AppropriateHouse, myHome, 1) 301 | 302 | 303 | def testDevices(): 304 | deviceUtil = DeviceUtil() 305 | deviceList = deviceUtil.getDeviceList(DeviceType.TypeSpeaker) 306 | print("麦克风设备列表:") 307 | if deviceList.getCount() > 0: 308 | # 设置第一个设备为要用的设备 309 | deviceUtil.active(DeviceType.TypeSpeaker, deviceList.getByIdx(0).getId()) 310 | for idx in range(0, deviceList.getCount()): 311 | device = deviceList.getByIdx(idx) 312 | print(device) 313 | print("当前使用的设备:" 314 | + deviceList.getById(deviceUtil.getCurDeviceId(DeviceType.TypeSpeaker)).getName()) 315 | 316 | 317 | # testRenting() 318 | testDevices() 319 | -------------------------------------------------------------------------------- /pattern/Memento.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 5/19/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | class Engineer: 8 | """工程师""" 9 | 10 | def __init__(self, name): 11 | self.__name = name 12 | self.__workItems = [] 13 | 14 | def addWorkItem(self, item): 15 | self.__workItems.append(item) 16 | 17 | def forget(self): 18 | self.__workItems.clear() 19 | print(self.__name + "工作太忙了,都忘记要做什么了!") 20 | 21 | def writeTodoList(self): 22 | """将工作项记录TodoList""" 23 | todoList = TodoList() 24 | for item in self.__workItems: 25 | todoList.writeWorkItem(item) 26 | return todoList 27 | 28 | def retrospect(self, todoList): 29 | """回忆工作项""" 30 | self.__workItems = todoList.getWorkItems() 31 | print(self.__name + "想起要做什么了!") 32 | 33 | def showWorkItem(self): 34 | if(len(self.__workItems)): 35 | print(self.__name + "的工作项:") 36 | for idx in range(0, len(self.__workItems)): 37 | print(str(idx + 1) + ". " + self.__workItems[idx] + ";") 38 | else: 39 | print(self.__name + "暂无工作项!") 40 | 41 | 42 | class TodoList: 43 | """工作项""" 44 | 45 | def __init__(self): 46 | self.__workItems = [] 47 | 48 | def writeWorkItem(self, item): 49 | self.__workItems.append(item) 50 | 51 | def getWorkItems(self): 52 | return self.__workItems 53 | 54 | 55 | class TodoListCaretaker: 56 | """TodoList管理类""" 57 | 58 | def __init__(self): 59 | self.__todoList = None 60 | 61 | def setTodoList(self, todoList): 62 | self.__todoList = todoList 63 | 64 | def getTodoList(self): 65 | return self.__todoList 66 | 67 | 68 | # Version 2.0 69 | #======================================================================================================================= 70 | # 代码框架 71 | #============================== 72 | from copy import deepcopy 73 | 74 | class Memento: 75 | """备忘录""" 76 | 77 | def setAttributes(self, dict): 78 | """深度拷贝字典dict中的所有属性""" 79 | self.__dict__ = deepcopy(dict) 80 | 81 | def getAttributes(self): 82 | """获取属性字典""" 83 | return self.__dict__ 84 | 85 | 86 | class Caretaker: 87 | """备忘录管理类""" 88 | 89 | def __init__(self): 90 | self._mementos = {} 91 | 92 | def addMemento(self, name, memento): 93 | self._mementos[name] = memento 94 | 95 | def getMemento(self, name): 96 | return self._mementos[name] 97 | 98 | class Originator: 99 | """备份发起人""" 100 | 101 | def createMemento(self): 102 | memento = Memento() 103 | memento.setAttributes(self.__dict__) 104 | return memento 105 | 106 | def restoreFromMemento(self, memento): 107 | self.__dict__.update(memento.getAttributes()) 108 | 109 | 110 | # 基于框架的实现 111 | #============================== 112 | 113 | # Test 114 | #======================================================================================================================= 115 | 116 | def testEngineer(): 117 | tony = Engineer("Tony") 118 | tony.addWorkItem("解决线上部分用户因昵称太长而无法显示全的问题") 119 | tony.addWorkItem("完成PDF的解析") 120 | tony.addWorkItem("在阅读器中显示PDF第一页的内容") 121 | tony.showWorkItem() 122 | caretaker = TodoListCaretaker() 123 | caretaker.setTodoList(tony.writeTodoList()) 124 | 125 | print() 126 | tony.forget() 127 | tony.showWorkItem() 128 | 129 | print() 130 | tony.retrospect(caretaker.getTodoList()) 131 | tony.showWorkItem() 132 | 133 | # testEngineer() -------------------------------------------------------------------------------- /pattern/Observer.py: -------------------------------------------------------------------------------- 1 | ##!/usr/bin/python 2 | 3 | # Version 1.0 4 | ######################################################################################################################## 5 | # from abc import ABCMeta, abstractmethod 6 | # # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 7 | # 8 | # class WaterHeater: 9 | # """热水器:战胜寒冬的有利武器""" 10 | # 11 | # def __init__(self): 12 | # self.__observers = [] 13 | # self.__temperature = 25 14 | # 15 | # def getTemperature(self): 16 | # return self.__temperature 17 | # 18 | # def setTemperature(self, temperature): 19 | # self.__temperature = temperature 20 | # print("当前温度是:" + str(self.__temperature) + "℃") 21 | # self.notifies() 22 | # 23 | # def addObserver(self, observer): 24 | # self.__observers.append(observer) 25 | # 26 | # def notifies(self): 27 | # for o in self.__observers: 28 | # o.update(self) 29 | # 30 | # 31 | # class Observer(metaclass=ABCMeta): 32 | # "洗澡模式和饮用模式的父类" 33 | # 34 | # @abstractmethod 35 | # def update(self, waterHeater): 36 | # pass 37 | # 38 | # 39 | # class WashingMode(Observer): 40 | # """该模式用于洗澡""" 41 | # 42 | # def update(self, waterHeater): 43 | # if waterHeater.getTemperature() >= 50 and waterHeater.getTemperature() < 70: 44 | # print("水已烧好!温度正好,可以用来洗澡了。") 45 | # 46 | # 47 | # class DrinkingMode(Observer): 48 | # """该模式用于饮用""" 49 | # 50 | # def update(self, waterHeater): 51 | # if waterHeater.getTemperature() >= 100: 52 | # print("水已烧开!可以用来饮用了。") 53 | 54 | 55 | # Version 2.0 56 | ######################################################################################################################## 57 | from abc import ABCMeta, abstractmethod 58 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 59 | 60 | class Observer(metaclass=ABCMeta): 61 | """观察者的基类""" 62 | 63 | @abstractmethod 64 | def update(self, observable, object): 65 | pass 66 | 67 | 68 | class Observable: 69 | """被观察者的基类""" 70 | 71 | def __init__(self): 72 | self.__observers = [] 73 | 74 | def addObserver(self, observer): 75 | self.__observers.append(observer) 76 | 77 | def removeObserver(self, observer): 78 | self.__observers.remove(observer) 79 | 80 | def notifyObservers(self, object=0): 81 | for o in self.__observers: 82 | o.update(self, object) 83 | 84 | 85 | class WaterHeater(Observable): 86 | """热水器:战胜寒冬的有利武器""" 87 | 88 | def __init__(self): 89 | super().__init__() 90 | self.__temperature = 25 91 | 92 | def getTemperature(self): 93 | return self.__temperature 94 | 95 | def setTemperature(self, temperature): 96 | self.__temperature = temperature 97 | print("当前温度是:" + str(self.__temperature) + "℃") 98 | self.notifyObservers() 99 | 100 | 101 | class WashingMode(Observer): 102 | """该模式用于洗澡用""" 103 | 104 | def update(self, observable, object): 105 | if isinstance(observable, WaterHeater) \ 106 | and observable.getTemperature() >= 50 and observable.getTemperature() < 70: 107 | print("水已烧好!温度正好,可以用来洗澡了。") 108 | 109 | 110 | class DrinkingMode(Observer): 111 | "该模式用于饮用" 112 | 113 | def update(self, observable, object): 114 | if isinstance(observable, WaterHeater) and observable.getTemperature() >= 100: 115 | print("水已烧开!可以用来饮用了。") 116 | 117 | 118 | import time 119 | # 导入时间处理模块 120 | 121 | class Account(Observable): 122 | """用户账户""" 123 | 124 | def __init__(self): 125 | super().__init__() 126 | self.__latestIp = {} 127 | self.__latestRegion = {} 128 | 129 | def login(self, name, ip, time): 130 | region = self.__getRegion(ip) 131 | if self.__isLongDistance(name, region): 132 | self.notifyObservers({"name": name, "ip": ip, "region": region, "time": time}) 133 | self.__latestRegion[name] = region 134 | self.__latestIp[name] = ip 135 | 136 | def __getRegion(self, ip): 137 | # 由IP地址获取地区信息。这里只是模拟,真实项目中应该调用IP地址解析服务 138 | ipRegions = { 139 | "101.47.18.9": "浙江省杭州市", 140 | "67.218.147.69":"美国洛杉矶" 141 | } 142 | region = ipRegions.get(ip) 143 | return "" if region is None else region 144 | 145 | 146 | def __isLongDistance(self, name, region): 147 | # 计算本次登录与最近几次登录的地区差距。 148 | # 这里只是简单地用字符串匹配来模拟,真实的项目中应该调用地理信息相关的服务 149 | latestRegion = self.__latestRegion.get(name) 150 | return latestRegion is not None and latestRegion != region; 151 | 152 | 153 | class SmsSender(Observer): 154 | """短信发送器""" 155 | 156 | def update(self, observable, object): 157 | print("[短信发送] " + object["name"] + "您好!检测到您的账户可能登录异常。最近一次登录信息:\n" 158 | + "登录地区:" + object["region"] + " 登录ip:" + object["ip"] + " 登录时间:" 159 | + time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(object["time"]))) 160 | 161 | 162 | class MailSender(Observer): 163 | """邮件发送器""" 164 | 165 | def update(self, observable, object): 166 | print("[邮件发送] " + object["name"] + "您好!检测到您的账户可能登录异常。最近一次登录信息:\n" 167 | + "登录地区:" + object["region"] + " 登录ip:" + object["ip"] + " 登录时间:" 168 | + time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(object["time"]))) 169 | 170 | 171 | def testWaterHeater(): 172 | heater = WaterHeater() 173 | washingObser = WashingMode() 174 | drinkingObser = DrinkingMode() 175 | heater.addObserver(washingObser) 176 | heater.addObserver(drinkingObser) 177 | heater.setTemperature(40) 178 | heater.setTemperature(60) 179 | heater.setTemperature(100) 180 | 181 | 182 | def testLogin(): 183 | accout = Account() 184 | accout.addObserver(SmsSender()) 185 | accout.addObserver(MailSender()) 186 | accout.login("Tony", "101.47.18.9", time.time()) 187 | accout.login("Tony", "67.218.147.69", time.time()) 188 | 189 | 190 | 191 | def testTime(): 192 | print(time.time()) 193 | strTime = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(time.time())) 194 | print(strTime) 195 | 196 | # testWaterHeater() 197 | testLogin() 198 | # testTime() 199 | 200 | # ipRegion = { 201 | # "101.47.18.9": "浙江省杭州市", 202 | # "67.218.147.69":"美国洛杉矶" 203 | # } 204 | # 205 | # print(ipRegion["101.47.18.90"]) 206 | -------------------------------------------------------------------------------- /pattern/Proxy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 11/12/2017 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class ReceiveParcel(metaclass=ABCMeta): 11 | """接收包裹抽象类""" 12 | 13 | def __init__(self, name): 14 | self.__name = name 15 | 16 | def getName(self): 17 | return self.__name 18 | 19 | @abstractmethod 20 | def receive(self, parcelContent): 21 | pass 22 | 23 | 24 | # class TonyReception(ReceiveParcel): 25 | # """Tony接收""" 26 | # 27 | # def __init__(self, name, phoneNum): 28 | # super().__init__(name) 29 | # self.__phoneNum = phoneNum 30 | # 31 | # def getPhoneNum(self): 32 | # return self.__phoneNum 33 | # 34 | # def receive(self, parcelContent): 35 | # print("货物主人:%s,手机号:%s" % (self.getName(), self.getPhoneNum()) ) 36 | # print("接收到一个包裹,包裹内容:%s" % parcelContent) 37 | # 38 | # 39 | # class WendyReception(ReceiveParcel): 40 | # """Wendy代收""" 41 | # 42 | # def __init__(self, name, receiver): 43 | # super().__init__(name) 44 | # self.__receiver = receiver 45 | # 46 | # def receive(self, parcelContent): 47 | # print("我是%s的朋友,我来帮他代收快递!" % (self.__receiver.getName() + "") ) 48 | # if(self.__receiver is not None): 49 | # self.__receiver.receive(parcelContent) 50 | # print("代收人:%s" % self.getName()) 51 | 52 | 53 | # Version 2.0 54 | #======================================================================================================================= 55 | # 代码框架 56 | #============================== 57 | from abc import ABCMeta, abstractmethod 58 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 59 | 60 | class Subject(metaclass=ABCMeta): 61 | """主题类""" 62 | 63 | def __init__(self, name): 64 | self.__name = name 65 | 66 | def getName(self): 67 | return self.__name 68 | 69 | @abstractmethod 70 | def request(self, content = ''): 71 | pass 72 | 73 | 74 | class RealSubject(Subject): 75 | """真实主题类""" 76 | 77 | def request(self, content): 78 | print("RealSubject todo something...") 79 | 80 | 81 | class ProxySubject(Subject): 82 | """代理主题类""" 83 | 84 | def __init__(self, name, subject): 85 | super().__init__(name) 86 | self._realSubject = subject 87 | 88 | def request(self, content = ''): 89 | self.preRequest() 90 | if(self._realSubject is not None): 91 | self._realSubject.request(content) 92 | self.afterRequest() 93 | 94 | def preRequest(self): 95 | print("preRequest") 96 | 97 | def afterRequest(self): 98 | print("afterRequest") 99 | 100 | 101 | # 基于框架的实现 102 | #============================== 103 | 104 | class TonyReception(Subject): 105 | """Tony接收""" 106 | 107 | def __init__(self, name, phoneNum): 108 | super().__init__(name) 109 | self.__phoneNum = phoneNum 110 | 111 | def getPhoneNum(self): 112 | return self.__phoneNum 113 | 114 | def request(self, content): 115 | print("货物主人:%s,手机号:%s" % (self.getName(), self.getPhoneNum())) 116 | print("接收到一个包裹,包裹内容:%s" % str(content)) 117 | 118 | 119 | class WendyReception(ProxySubject): 120 | """Wendy代收""" 121 | 122 | def __init__(self, name, receiver): 123 | super().__init__(name, receiver) 124 | 125 | def preRequest(self): 126 | print("我是%s的朋友,我来帮他代收快递!" % (self._realSubject.getName() + "")) 127 | 128 | def afterRequest(self): 129 | print("代收人:%s" % self.getName()) 130 | 131 | 132 | # Test 133 | #======================================================================================================================= 134 | def testReceiveParcel(): 135 | tony = TonyReception("Tony", "18512345678") 136 | print("Tony接收:") 137 | tony.receive("雪地靴") 138 | print() 139 | 140 | print("Wendy代收:") 141 | wendy = WendyReception("Wendy", tony) 142 | wendy.receive("雪地靴") 143 | 144 | 145 | def testProxy(): 146 | realObj = RealSubject('RealSubject') 147 | proxyObj = ProxySubject('ProxySubject', realObj) 148 | proxyObj.request() 149 | 150 | def testReceiveParcel2(): 151 | tony = TonyReception("Tony", "18512345678") 152 | print("Tony接收:") 153 | tony.request("雪地靴") 154 | print() 155 | 156 | print("Wendy代收:") 157 | wendy = WendyReception("Wendy", tony) 158 | wendy.request("雪地靴") 159 | 160 | # testReceiveParcel() 161 | # testProxy() 162 | testReceiveParcel2() 163 | 164 | -------------------------------------------------------------------------------- /pattern/Responsibility.py: -------------------------------------------------------------------------------- 1 | ##!/usr/bin/python 2 | 3 | # Version 1.0 4 | ######################################################################################################################## 5 | # from abc import ABCMeta, abstractmethod 6 | # # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 7 | # 8 | # class Person: 9 | # """请假申请人""" 10 | # def __init__(self, name, dayoff, reason): 11 | # self.__name = name 12 | # self.__dayoff = dayoff 13 | # self.__reason = reason 14 | # self.__leader = None 15 | # 16 | # def getName(self): 17 | # return self.__name 18 | # 19 | # def getDayOff(self): 20 | # return self.__dayoff 21 | # 22 | # def getReason(self): 23 | # return self.__reason 24 | # 25 | # def setLeader(self, leader): 26 | # self.__leader = leader 27 | # 28 | # def reuqest(self): 29 | # print("%s 申请请假 %d 天。请假事由:%s" % (self.__name, self.__dayoff, self.__reason) ) 30 | # if( self.__leader is not None): 31 | # self.__leader.handleRequest(self) 32 | # 33 | # 34 | # class Manager(metaclass=ABCMeta): 35 | # """公司管理人员""" 36 | # 37 | # def __init__(self, name, title): 38 | # self.__name = name 39 | # self.__title = title 40 | # self._nextHandler = None 41 | # 42 | # def getName(self): 43 | # return self.__name 44 | # 45 | # def getTitle(self): 46 | # return self.__title 47 | # 48 | # def setNextHandler(self, nextHandler): 49 | # self._nextHandler = nextHandler 50 | # 51 | # @abstractmethod 52 | # def handleRequest(self, person): 53 | # pass 54 | # 55 | # class Supervisor(Manager): 56 | # """主管""" 57 | # 58 | # def __init__(self, name, title): 59 | # super().__init__(name, title) 60 | # 61 | # def handleRequest(self, person): 62 | # if(person.getDayOff() <= 2): 63 | # print("同意 %s 请假,签字人:%s(%s)" % (person.getName(), self.getName(), self.getTitle()) ) 64 | # if(self._nextHandler is not None): 65 | # self._nextHandler.handleRequest(person) 66 | # 67 | # 68 | # class DepartmentManager(Manager): 69 | # """部门总监""" 70 | # def __init__(self, name, title): 71 | # super().__init__(name, title) 72 | # 73 | # def handleRequest(self, person): 74 | # if(person.getDayOff() >2 and person.getDayOff() <= 5): 75 | # print("同意 %s 请假,签字人:%s(%s)" % (person.getName(), self.getName(), self.getTitle())) 76 | # if(self._nextHandler is not None): 77 | # self._nextHandler.handleRequest(person) 78 | # 79 | # class CEO(Manager): 80 | # """CEO""" 81 | # 82 | # def __init__(self, name, title): 83 | # super().__init__(name, title) 84 | # 85 | # def handleRequest(self, person): 86 | # if (person.getDayOff() > 5 and person.getDayOff() <= 22): 87 | # print("同意 %s 请假,签字人:%s(%s)" % (person.getName(), self.getName(), self.getTitle())) 88 | # 89 | # if (self._nextHandler is not None): 90 | # self._nextHandler.handleRequest(person) 91 | # 92 | # class Administrator(Manager): 93 | # """行政人员""" 94 | # 95 | # def __init__(self, name, title): 96 | # super().__init__(name, title) 97 | # 98 | # def handleRequest(self, person): 99 | # print("%s 的请假申请已审核,情况属实!已备案处理。处理人:%s(%s)\n" % (person.getName(), self.getName(), self.getTitle())) 100 | 101 | 102 | # Version 2.0 103 | ######################################################################################################################## 104 | # 代码框架 105 | ################## 106 | from abc import ABCMeta, abstractmethod 107 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 108 | 109 | class Request: 110 | """请求(内容)""" 111 | 112 | def __init__(self, name, dayoff, reason): 113 | self.__name = name 114 | self.__dayoff = dayoff 115 | self.__reason = reason 116 | self.__leader = None 117 | 118 | def getName(self): 119 | return self.__name 120 | 121 | def getDayOff(self): 122 | return self.__dayoff 123 | 124 | def getReason(self): 125 | return self.__reason 126 | 127 | 128 | class Responsible(metaclass=ABCMeta): 129 | """责任人抽象类""" 130 | 131 | def __init__(self, name, title): 132 | self.__name = name 133 | self.__title = title 134 | self._nextHandler = None 135 | 136 | def getName(self): 137 | return self.__name 138 | 139 | def getTitle(self): 140 | return self.__title 141 | 142 | def setNextHandler(self, nextHandler): 143 | self._nextHandler = nextHandler 144 | 145 | def getNextHandler(self): 146 | return self._nextHandler 147 | 148 | def handleRequest(self, request): 149 | """请求处理""" 150 | # 当前责任人处理请求 151 | self._handleRequestImpl(request) 152 | # 如果存在下一个责任人,则将请求传递(提交)给下一个责任人 153 | if (self._nextHandler is not None): 154 | self._nextHandler.handleRequest(request) 155 | 156 | @abstractmethod 157 | def _handleRequestImpl(self, request): 158 | """真正处理请求的方法""" 159 | pass 160 | 161 | 162 | # 基于框架的实现 163 | ################## 164 | class Person: 165 | """请求者(请假人)""" 166 | 167 | def __init__(self, name): 168 | self.__name = name 169 | self.__leader = None 170 | 171 | def setName(self, name): 172 | self.__name = name 173 | 174 | def getName(self): 175 | return self.__name 176 | 177 | def setLeader(self, leader): 178 | self.__leader = leader 179 | 180 | def getLeader(self): 181 | return self.__leader 182 | 183 | def sendReuqest(self, request): 184 | print("%s 申请请假 %d 天。请假事由:%s" % (self.__name, request.getDayOff(), request.getReason())) 185 | if (self.__leader is not None): 186 | self.__leader.handleRequest(request) 187 | 188 | 189 | class Supervisor(Responsible): 190 | """主管""" 191 | 192 | def __init__(self, name, title): 193 | super().__init__(name, title) 194 | 195 | def _handleRequestImpl(self, request): 196 | if (request.getDayOff() <= 2): 197 | print("同意 %s 请假,签字人:%s(%s)" % (request.getName(), self.getName(), self.getTitle())) 198 | 199 | 200 | class DepartmentManager(Responsible): 201 | """部门总监""" 202 | 203 | def __init__(self, name, title): 204 | super().__init__(name, title) 205 | 206 | def _handleRequestImpl(self, request): 207 | if (request.getDayOff() > 2 and request.getDayOff() <= 5): 208 | print("同意 %s 请假,签字人:%s(%s)" % (request.getName(), self.getName(), self.getTitle())) 209 | 210 | 211 | class CEO(Responsible): 212 | """CEO""" 213 | 214 | def __init__(self, name, title): 215 | super().__init__(name, title) 216 | 217 | def _handleRequestImpl(self, request): 218 | if (request.getDayOff() > 5 and request.getDayOff() <= 22): 219 | print("同意 %s 请假,签字人:%s(%s)" % (request.getName(), self.getName(), self.getTitle())) 220 | 221 | 222 | class Administrator(Responsible): 223 | """行政人员""" 224 | 225 | def __init__(self, name, title): 226 | super().__init__(name, title) 227 | 228 | def _handleRequestImpl(self, request): 229 | print("%s 的请假申请已审核,情况属实!已备案处理。处理人:%s(%s)\n" % (request.getName(), self.getName(), self.getTitle())) 230 | 231 | # Test 232 | ######################################################################################################################## 233 | # def testAskForLeave(): 234 | # directLeader = Supervisor("Eren", "客户端研发部经理") 235 | # departmentLeader = DepartmentManager("Eric", "技术研发中心总监") 236 | # ceo = CEO("Helen", "创新文化公司CEO") 237 | # administrator = Administrator("Nina", "行政中心总监") 238 | # directLeader.setNextHandler(departmentLeader) 239 | # departmentLeader.setNextHandler(ceo) 240 | # ceo.setNextHandler(administrator) 241 | # 242 | # sunny = Person("Sunny", 1, "参加MDCC大会。") 243 | # sunny.setLeader(directLeader) 244 | # sunny.reuqest() 245 | # tony = Person("Tony", 5, "家里有紧急事情!") 246 | # tony.setLeader(directLeader) 247 | # tony.reuqest() 248 | # pony = Person("Pony", 15, "出国深造。") 249 | # pony.setLeader(directLeader) 250 | # pony.reuqest() 251 | 252 | 253 | def testChainOfResponsibility(): 254 | directLeader = Supervisor("Eren", "客户端研发部经理") 255 | departmentLeader = DepartmentManager("Eric", "技术研发中心总监") 256 | ceo = CEO("Helen", "创新文化公司CEO") 257 | administrator = Administrator("Nina", "行政中心总监") 258 | directLeader.setNextHandler(departmentLeader) 259 | departmentLeader.setNextHandler(ceo) 260 | ceo.setNextHandler(administrator) 261 | 262 | sunny = Person("Sunny") 263 | sunny.setLeader(directLeader) 264 | sunny.sendReuqest(Request(sunny.getName(), 1, "参加MDCC大会。")) 265 | tony = Person("Tony") 266 | tony.setLeader(directLeader) 267 | tony.sendReuqest(Request(tony.getName(), 5, "家里有紧急事情!")) 268 | pony = Person("Pony") 269 | pony.setLeader(directLeader) 270 | pony.sendReuqest(Request(pony.getName(), 15, "出国深造。")) 271 | 272 | 273 | # testAskForLeave() 274 | testChainOfResponsibility() -------------------------------------------------------------------------------- /pattern/SimpleFactory.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 12/2/2017 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class Coffee(metaclass=ABCMeta): 11 | """咖啡""" 12 | 13 | def __init__(self, name): 14 | self.__name = name 15 | 16 | def getName(self): 17 | return self.__name 18 | 19 | @abstractmethod 20 | def getTaste(self): 21 | pass 22 | 23 | 24 | class LatteCaffe(Coffee): 25 | """拿铁咖啡""" 26 | 27 | def __init__(self, name): 28 | super().__init__(name) 29 | 30 | def getTaste(self): 31 | return "轻柔而香醇" 32 | 33 | class MochaCoffee(Coffee): 34 | """摩卡咖啡""" 35 | 36 | def __init__(self, name): 37 | super().__init__(name) 38 | 39 | def getTaste(self): 40 | return "丝滑与醇厚" 41 | 42 | class Coffeemaker: 43 | """咖啡机""" 44 | 45 | @staticmethod 46 | def makeCoffee(coffeeBean): 47 | "通过staticmethod装饰器修饰来定义一个静态方法" 48 | if(coffeeBean == "拿铁咖啡豆"): 49 | coffee = LatteCaffe("拿铁咖啡") 50 | elif(coffeeBean == "摩卡咖啡豆"): 51 | coffee = MochaCoffee("摩卡咖啡") 52 | else: 53 | raise ValueError("不支持的参数:%s" % coffeeBean) 54 | return coffee 55 | 56 | 57 | 58 | # Version 2.0 59 | #======================================================================================================================= 60 | # 代码框架 61 | #============================== 62 | from abc import ABCMeta, abstractmethod 63 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 64 | from enum import Enum 65 | # Python3.4 之后支持枚举Enum的语法 66 | 67 | class PenType(Enum): 68 | """画笔类型""" 69 | PenTypeLine = 1 70 | PenTypeRect = 2 71 | PenTypeEllipse = 3 72 | 73 | 74 | class Pen(metaclass=ABCMeta): 75 | """画笔""" 76 | 77 | def __init__(self, name): 78 | self.__name = name 79 | 80 | @abstractmethod 81 | def getType(self): 82 | pass 83 | 84 | def getName(self): 85 | return self.__name 86 | 87 | 88 | class LinePen(Pen): 89 | """直线画笔""" 90 | 91 | def __init__(self, name): 92 | super().__init__(name) 93 | 94 | def getType(self): 95 | return PenType.PenTypeLine 96 | 97 | class RectanglePen(Pen): 98 | """矩形画笔""" 99 | 100 | def __init__(self, name): 101 | super().__init__(name) 102 | 103 | def getType(self): 104 | return PenType.PenTypeRect 105 | 106 | 107 | class EllipsePen(Pen): 108 | """椭圆画笔""" 109 | 110 | def __init__(self, name): 111 | super().__init__(name) 112 | 113 | def getType(self): 114 | return PenType.PenTypeEllipse 115 | 116 | 117 | class PenFactory: 118 | """画笔工厂类""" 119 | 120 | def __init__(self): 121 | "定义一个字典(key:PenType,value:Pen)来存放对象,确保每一个类型只会有一个对象" 122 | self.__pens = {} 123 | 124 | def getSingleObj(self, penType, name): 125 | """获得唯一实例的对象""" 126 | 127 | 128 | def createPen(self, penType): 129 | """创建画笔""" 130 | if (self.__pens.get(penType) is None): 131 | # 如果该对象不存在,则创建一个对象并存到字典中 132 | if penType == PenType.PenTypeLine: 133 | pen = LinePen("直线画笔") 134 | elif penType == PenType.PenTypeRect: 135 | pen = RectanglePen("矩形画笔") 136 | elif penType == PenType.PenTypeEllipse: 137 | pen = EllipsePen("椭圆画笔") 138 | else: 139 | pen = Pen("") 140 | self.__pens[penType] = pen 141 | # 否则直接返回字典中的对象 142 | return self.__pens[penType] 143 | 144 | 145 | # 基于框架的实现 146 | #============================== 147 | 148 | 149 | # Test 150 | #======================================================================================================================= 151 | def testCoffeeMaker(): 152 | latte = Coffeemaker.makeCoffee("拿铁咖啡豆") 153 | print("%s已为您准备好了,口感:%s。请慢慢享用!" % (latte.getName(), latte.getTaste()) ) 154 | mocha = Coffeemaker.makeCoffee("摩卡咖啡豆") 155 | print("%s已为您准备好了,口感:%s。请慢慢享用!" % (mocha.getName(), mocha.getTaste())) 156 | 157 | 158 | def testPenFactory(): 159 | factory = PenFactory() 160 | linePen = factory.createPen(PenType.PenTypeLine) 161 | print("创建了 %s,对象id:%s, 类型:%s" % (linePen.getName(), id(linePen), linePen.getType()) ) 162 | rectPen = factory.createPen(PenType.PenTypeRect) 163 | print("创建了 %s,对象id:%s, 类型:%s" % (rectPen.getName(), id(rectPen), rectPen.getType()) ) 164 | rectPen2 = factory.createPen(PenType.PenTypeRect) 165 | print("创建了 %s,对象id:%s, 类型:%s" % (rectPen2.getName(), id(rectPen2), rectPen2.getType()) ) 166 | ellipsePen = factory.createPen(PenType.PenTypeEllipse) 167 | print("创建了 %s,对象id:%s, 类型:%s" % (ellipsePen.getName(), id(ellipsePen), ellipsePen.getType()) ) 168 | 169 | 170 | # testCoffeeMaker() 171 | testPenFactory() -------------------------------------------------------------------------------- /pattern/Singleton.py: -------------------------------------------------------------------------------- 1 | ##!/usr/bin/python 2 | 3 | # Version 1.0 4 | ######################################################################################################################## 5 | 6 | class MyBeautifulGril(object): 7 | """我的漂亮女神""" 8 | __instance = None 9 | __isFirstInit = False 10 | 11 | def __new__(cls, name): 12 | if not cls.__instance: 13 | MyBeautifulGril.__instance = super().__new__(cls) 14 | return cls.__instance 15 | 16 | def __init__(self, name): 17 | if not self.__isFirstInit: 18 | self.__name = name 19 | print("遇见" + name + ",我一见钟情!") 20 | MyBeautifulGril.__isFirstInit = True 21 | else: 22 | print("遇见" + name + ",我置若罔闻!") 23 | 24 | def showMyHeart(self): 25 | print(self.__name + "就我心中的唯一!") 26 | 27 | 28 | # 各种singleton实现方式 29 | ######################################################################################################################## 30 | # class Singleton1(object): 31 | # """单例实现方式一""" 32 | # __instance = None 33 | # __isFirstInit = False 34 | # 35 | # def __new__(cls, name): 36 | # if not cls.__instance: 37 | # Singleton1.__instance = super().__new__(cls) 38 | # return cls.__instance 39 | # 40 | # def __init__(self, name): 41 | # if not self.__isFirstInit: 42 | # self.__name = name 43 | # Singleton1.__isFirstInit = True 44 | # 45 | # def getName(self): 46 | # return self.__name 47 | # 48 | # # Test 49 | # tony = Singleton1("Tony") 50 | # karry = Singleton1("Karry") 51 | # print(tony.getName(), karry.getName()) 52 | # print("id(tony):", id(tony), "id(karry):", id(karry)) 53 | # print("tony == karry:", tony == karry) 54 | 55 | 56 | # 方式二 57 | #======================================================================================== 58 | # class Singleton2(type): 59 | # """单例实现方式二""" 60 | # 61 | # def __init__(cls, what, bases=None, dict=None): 62 | # super().__init__(what, bases, dict) 63 | # cls._instance = None # 初始化全局变量cls._instance为None 64 | # 65 | # def __call__(cls, *args, **kwargs): 66 | # # 控制对象的创建过程,如果cls._instance为None则创建,否则直接返回 67 | # if cls._instance is None: 68 | # cls._instance = super().__call__(*args, **kwargs) 69 | # return cls._instance 70 | # 71 | # class CustomClass(metaclass=Singleton2): 72 | # """用户自定义的类""" 73 | # 74 | # def __init__(self, name): 75 | # self.__name = name 76 | # 77 | # def getName(self): 78 | # return self.__name 79 | # 80 | # 81 | # tony = CustomClass("Tony") 82 | # karry = CustomClass("Karry") 83 | # print(tony.getName(), karry.getName()) 84 | # print("id(tony):", id(tony), "id(karry):", id(karry)) 85 | # print("tony == karry:", tony == karry) 86 | 87 | 88 | # 方式三 89 | #======================================================================================== 90 | def singletonDecorator(cls, *args, **kwargs): 91 | """定义一个单例装饰器""" 92 | instance = {} 93 | 94 | def wrapperSingleton(*args, **kwargs): 95 | if cls not in instance: 96 | instance[cls] = cls(*args, **kwargs) 97 | return instance[cls] 98 | 99 | return wrapperSingleton 100 | 101 | 102 | @singletonDecorator 103 | class Singleton3: 104 | """使用单例装饰器修饰一个类""" 105 | 106 | def __init__(self, name): 107 | self.__name = name 108 | 109 | def getName(self): 110 | return self.__name 111 | 112 | 113 | # tony = Singleton3("Tony") 114 | # karry = Singleton3("Karry") 115 | # print(tony.getName(), karry.getName()) 116 | # print("id(tony):", id(tony), "id(karry):", id(karry)) 117 | # print("tony == karry:", tony == karry) 118 | 119 | 120 | # Version 2.0 121 | ######################################################################################################################## 122 | @singletonDecorator 123 | class MyBeautifulGril(object): 124 | """我的漂亮女神""" 125 | 126 | def __init__(self, name): 127 | self.__name = name 128 | if self.__name == name: 129 | print("遇见" + name + ",我一见钟情!") 130 | else: 131 | print("遇见" + name + ",我置若罔闻!") 132 | 133 | def showMyHeart(self): 134 | print(self.__name + "就我心中的唯一!") 135 | 136 | 137 | # Test 138 | ######################################################################################################################## 139 | def TestLove(): 140 | jenny = MyBeautifulGril("Jenny") 141 | jenny.showMyHeart() 142 | kimi = MyBeautifulGril("Kimi") 143 | kimi.showMyHeart() 144 | print("id(jenny):", id(jenny), " id(kimi):", id(kimi)) 145 | 146 | 147 | TestLove() 148 | 149 | -------------------------------------------------------------------------------- /pattern/State.py: -------------------------------------------------------------------------------- 1 | ##!/usr/bin/python 2 | 3 | # Version 1.0 4 | ######################################################################################################################## 5 | # from abc import ABCMeta, abstractmethod 6 | # # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 7 | # 8 | # class Water: 9 | # """水(H2O)""" 10 | # 11 | # def __init__(self, state): 12 | # self.__temperature = 25 # 默认25℃常温 13 | # self.__state = state 14 | # 15 | # def setState(self, state): 16 | # self.__state = state 17 | # 18 | # def changeState(self, state): 19 | # if (self.__state): 20 | # print("由", self.__state.getName(), "变为", state.getName()) 21 | # else: 22 | # print("初始化为", state.getName()) 23 | # self.__state = state 24 | # 25 | # def getTemperature(self): 26 | # return self.__temperature 27 | # 28 | # def setTemperature(self, temperature): 29 | # self.__temperature = temperature 30 | # if (self.__temperature <= 0): 31 | # self.changeState(SolidState("固态")) 32 | # elif (self.__temperature <= 100): 33 | # self.changeState(LiquidState("液态")) 34 | # else: 35 | # self.changeState(GaseousState("气态")) 36 | # 37 | # def riseTemperature(self, step): 38 | # self.setTemperature(self.__temperature + step) 39 | # 40 | # def reduceTemperature(self, step): 41 | # self.setTemperature(self.__temperature - step) 42 | # 43 | # def behavior(self): 44 | # self.__state.behavior(self) 45 | # 46 | # 47 | # class State(metaclass=ABCMeta): 48 | # """状态类""" 49 | # 50 | # def __init__(self, name): 51 | # self.__name = name 52 | # 53 | # def getName(self): 54 | # return self.__name 55 | # 56 | # @abstractmethod 57 | # def behavior(self, water): 58 | # """不同状态下的行为""" 59 | # pass 60 | # 61 | # 62 | # class SolidState(State): 63 | # """固态""" 64 | # 65 | # def __init__(self, name): 66 | # super().__init__(name) 67 | # 68 | # def behavior(self, water): 69 | # print("我性格高冷,当前体温" + str(water.getTemperature()) + 70 | # "℃,我坚如钢铁,仿如一冷血动物,请用我砸人,嘿嘿……") 71 | # 72 | # 73 | # class LiquidState(State): 74 | # """液态""" 75 | # 76 | # def __init__(self, name): 77 | # super().__init__(name) 78 | # 79 | # def behavior(self, water): 80 | # print("我性格温和,当前体温" + str(water.getTemperature()) + 81 | # "℃,我可滋润万物,饮用我可让你活力倍增……") 82 | # 83 | # 84 | # class GaseousState(State): 85 | # """气态""" 86 | # 87 | # def __init__(self, name): 88 | # super().__init__(name) 89 | # 90 | # def behavior(self, water): 91 | # print("我性格热烈,当前体温" + str(water.getTemperature()) + 92 | # "℃,飞向天空是我毕生的梦想,在这你将看不到我的存在,我将达到无我的境界……") 93 | 94 | 95 | # Version 2.0 96 | ######################################################################################################################## 97 | from abc import ABCMeta, abstractmethod 98 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 99 | 100 | class Context(metaclass=ABCMeta): 101 | """状态模式的上下文环境类""" 102 | 103 | def __init__(self): 104 | self.__states = [] 105 | self.__curState = None 106 | # 状态发生变化依赖的属性, 当这一变量由多个变量共同决定时可以将其单独定义成一个类 107 | self.__stateInfo = 0 108 | 109 | def addState(self, state): 110 | if (state not in self.__states): 111 | self.__states.append(state) 112 | 113 | def changeState(self, state): 114 | if (state is None): 115 | return False 116 | if (self.__curState is None): 117 | print("初始化为", state.getName()) 118 | else: 119 | print("由", self.__curState.getName(), "变为", state.getName()) 120 | self.__curState = state 121 | self.addState(state) 122 | return True 123 | 124 | def getState(self): 125 | return self.__curState 126 | 127 | def _setStateInfo(self, stateInfo): 128 | self.__stateInfo = stateInfo 129 | for state in self.__states: 130 | if( state.isMatch(stateInfo) ): 131 | self.changeState(state) 132 | 133 | def _getStateInfo(self): 134 | return self.__stateInfo 135 | 136 | 137 | class State: 138 | """状态的基类""" 139 | 140 | def __init__(self, name): 141 | self.__name = name 142 | 143 | def getName(self): 144 | return self.__name 145 | 146 | def isMatch(self, stateInfo): 147 | "状态的属性stateInfo是否在当前的状态范围内" 148 | return False 149 | 150 | @abstractmethod 151 | def behavior(self, context): 152 | pass 153 | 154 | 155 | 156 | # Demo 实现 157 | 158 | class Water(Context): 159 | """水(H2O)""" 160 | 161 | def __init__(self): 162 | super().__init__() 163 | self.addState(SolidState("固态")) 164 | self.addState(LiquidState("液态")) 165 | self.addState(GaseousState("气态")) 166 | self.setTemperature(25) 167 | 168 | def getTemperature(self): 169 | return self._getStateInfo() 170 | 171 | def setTemperature(self, temperature): 172 | self._setStateInfo(temperature) 173 | 174 | def riseTemperature(self, step): 175 | self.setTemperature(self.getTemperature() + step) 176 | 177 | def reduceTemperature(self, step): 178 | self.setTemperature(self.getTemperature() - step) 179 | 180 | def behavior(self): 181 | state = self.getState() 182 | if(isinstance(state, State)): 183 | state.behavior(self) 184 | 185 | 186 | # 单例的装饰器 187 | def singleton(cls, *args, **kwargs): 188 | "构造一个单例的装饰器" 189 | instance = {} 190 | 191 | def __singleton(*args, **kwargs): 192 | if cls not in instance: 193 | instance[cls] = cls(*args, **kwargs) 194 | return instance[cls] 195 | 196 | return __singleton 197 | 198 | 199 | @singleton 200 | class SolidState(State): 201 | """固态""" 202 | 203 | def __init__(self, name): 204 | super().__init__(name) 205 | 206 | def isMatch(self, stateInfo): 207 | return stateInfo < 0 208 | 209 | def behavior(self, context): 210 | print("我性格高冷,当前体温", context._getStateInfo(), 211 | "℃,我坚如钢铁,仿如一冷血动物,请用我砸人,嘿嘿……") 212 | 213 | 214 | @singleton 215 | class LiquidState(State): 216 | """液态""" 217 | 218 | def __init__(self, name): 219 | super().__init__(name) 220 | 221 | def isMatch(self, stateInfo): 222 | return (stateInfo >= 0 and stateInfo < 100) 223 | 224 | def behavior(self, context): 225 | print("我性格温和,当前体温", context._getStateInfo(), 226 | "℃,我可滋润万物,饮用我可让你活力倍增……") 227 | 228 | @singleton 229 | class GaseousState(State): 230 | """气态""" 231 | 232 | def __init__(self, name): 233 | super().__init__(name) 234 | 235 | def isMatch(self, stateInfo): 236 | return stateInfo >= 100 237 | 238 | def behavior(self, context): 239 | print("我性格热烈,当前体温", context._getStateInfo(), 240 | "℃,飞向天空是我毕生的梦想,在这你将看不到我的存在,我将达到无我的境界……") 241 | 242 | 243 | # Test 244 | ######################################################################################################################## 245 | def testState(): 246 | # water = Water(LiquidState("液态")) 247 | water = Water() 248 | water.behavior() 249 | water.setTemperature(-4) 250 | water.behavior() 251 | water.riseTemperature(18) 252 | water.behavior() 253 | water.riseTemperature(110) 254 | water.behavior() 255 | 256 | 257 | testState() 258 | 259 | 260 | # t1 = State("State1") 261 | # t2 = State("State2") 262 | # t3 = SolidState("State3") 263 | # t4 = SolidState("State4") 264 | # print(t1.getName(), t2.getName(), t3.getName(), t4.getName()) 265 | # print(id(t1), id(t2), id(t3), id(t4)) 266 | # print(t1 == t2) 267 | # print(t3 == t4) 268 | 269 | 270 | -------------------------------------------------------------------------------- /pattern/Strategy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 5/1/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class IVehicle(metaclass=ABCMeta): 11 | """交通工具的抽象类""" 12 | 13 | @abstractmethod 14 | def running(self): 15 | pass 16 | 17 | 18 | class SharedBicycle(IVehicle): 19 | """共享单车""" 20 | 21 | def running(self): 22 | print("骑共享单车(轻快便捷)", end='') 23 | 24 | 25 | class ExpressBus(IVehicle): 26 | """快速公交""" 27 | 28 | def running(self): 29 | print("坐快速公交(经济绿色)", end='') 30 | 31 | class Express(IVehicle): 32 | """快车""" 33 | 34 | def running(self): 35 | print("打快车(快速方便)", end='') 36 | 37 | 38 | class Subway(IVehicle): 39 | """地铁""" 40 | 41 | def running(self): 42 | print("坐地铁(高效安全)", end='') 43 | 44 | 45 | class Classmate: 46 | """参加聚餐的同学""" 47 | 48 | def __init__(self, name, vechicle): 49 | self.__name = name 50 | self.__vechicle = vechicle 51 | 52 | def attendTheDinner(self): 53 | print(self.__name + " ", end='') 54 | self.__vechicle.running() 55 | print(" 来参加聚餐!") 56 | 57 | 58 | # Version 2.0 59 | #======================================================================================================================= 60 | # 代码框架 61 | #============================== 62 | from abc import ABCMeta, abstractmethod 63 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 64 | 65 | class Person: 66 | """人类""" 67 | 68 | def __init__(self, name, age, weight, height): 69 | self.name = name 70 | self.age = age 71 | self.weight = weight 72 | self.height = height 73 | 74 | def showMysef(self): 75 | print("%s 年龄:%d岁,体重:%0.2fkg,身高:%0.2fm" % (self.name, self.age, self.weight, self.height) ) 76 | 77 | 78 | class ICompare(metaclass=ABCMeta): 79 | """比较算法""" 80 | 81 | @abstractmethod 82 | def comparable(self, person1, person2): 83 | "person1 > person2 返回值>0,person1 == person2 返回0, person1 < person2 返回值小于0" 84 | pass 85 | 86 | 87 | class CompareByAge(ICompare): 88 | """通过年龄排序""" 89 | 90 | def comparable(self, person1, person2): 91 | return person1.age - person2.age 92 | 93 | 94 | class CompareByHeight(ICompare): 95 | """通过身高进行排序""" 96 | 97 | def comparable(self, person1, person2): 98 | return person1.height - person2.height 99 | 100 | 101 | class CompareByHeightAndWeight(ICompare): 102 | """根据身高和体重的综合情况来排序 103 | (身高和体重的权重分别是0.6和0.4)""" 104 | 105 | def comparable(self, person1, person2): 106 | value1 = person1.height * 0.6 + person1.weight * 0.4 107 | value2 = person2.height * 0.6 + person2.weight * 0.4 108 | return value1 - value2 109 | 110 | 111 | class SortPerson: 112 | "Person的排序类" 113 | 114 | def __init__(self, compare): 115 | self.__compare = compare 116 | 117 | def sort(self, personList): 118 | """排序算法 119 | 这里采用最简单的冒泡排序""" 120 | n = len(personList) 121 | for i in range(0, n-1): 122 | for j in range(0, n-i-1): 123 | if(self.__compare.comparable(personList[j], personList[j+1]) > 0): 124 | tmp = personList[j] 125 | personList[j] = personList[j+1] 126 | personList[j+1] = tmp 127 | j += 1 128 | i += 1 129 | 130 | 131 | # 基于框架的实现 132 | #============================== 133 | 134 | 135 | # Test 136 | #======================================================================================================================= 137 | 138 | def testTheDinner(): 139 | sharedBicycle = SharedBicycle() 140 | joe = Classmate("Joe", sharedBicycle) 141 | joe.attendTheDinner() 142 | helen = Classmate("Helen", Subway()) 143 | helen.attendTheDinner() 144 | henry = Classmate("Henry", ExpressBus()) 145 | henry.attendTheDinner() 146 | ruby = Classmate("Ruby", Express()) 147 | ruby.attendTheDinner() 148 | 149 | 150 | 151 | def testSortPerson(): 152 | personList = [ 153 | Person("Tony", 2, 54.5, 0.82), 154 | Person("Jack", 31, 74.5, 1.80), 155 | Person("Nick", 54, 44.5, 1.59), 156 | Person("Eric", 23, 62.0, 1.78), 157 | Person("Helen", 16, 45.7, 1.60) 158 | ] 159 | ageSorter = SortPerson(CompareByAge()) 160 | ageSorter.sort(personList) 161 | print("根据年龄进行排序后的结果:") 162 | for person in personList: 163 | person.showMysef() 164 | print() 165 | 166 | heightSorter = SortPerson(CompareByHeight()) 167 | heightSorter.sort(personList) 168 | print("根据身高进行排序后的结果:") 169 | for person in personList: 170 | person.showMysef() 171 | print() 172 | 173 | # heightWeightSorter = SortPerson(CompareByHeightAndWeight()) 174 | # heightWeightSorter.sort(personList) 175 | # print("根据身高和体重进行排序后的结果:") 176 | # for person in personList: 177 | # person.showMysef() 178 | 179 | 180 | 181 | from operator import itemgetter,attrgetter 182 | 183 | def testPersonListInPython(): 184 | "用Python的方式对Person进行排序" 185 | 186 | personList = [ 187 | Person("Tony", 2, 54.5, 0.82), 188 | Person("Jack", 31, 74.5, 1.80), 189 | Person("Nick", 54, 44.5, 1.59), 190 | Person("Eric", 23, 62.0, 1.78), 191 | Person("Helen", 16, 45.7, 1.60) 192 | ] 193 | 194 | # 使用operator模块根据年龄、身高进行排序 195 | sortedPerons = sorted(personList, key = attrgetter('age')) 196 | sortedPerons1 = sorted(personList, key=attrgetter('height')) 197 | 198 | print("根据年龄进行排序后的结果:") 199 | for person in sortedPerons: 200 | person.showMysef() 201 | print() 202 | print("根据身高进行排序后的结果:") 203 | for person in sortedPerons1: 204 | person.showMysef() 205 | 206 | 207 | # print("根据身高和体重的综合情况来排序:") 208 | # sortedPerons1 = sorted(personList, key=attrgetter("height" + "weight")) 209 | # for person in sortedPerons1: 210 | # person.showMysef() 211 | 212 | 213 | 214 | # testTheDinner() 215 | # testSortPerson() 216 | testPersonListInPython() 217 | 218 | 219 | # testArray() -------------------------------------------------------------------------------- /pattern/Template.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 7/8/2018 4 | 5 | # Version 1.0 代码框架 6 | #======================================================================================================================= 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class Template(metaclass=ABCMeta): 11 | """模板类(抽象类)""" 12 | 13 | @abstractmethod 14 | def stepOne(self): 15 | pass 16 | 17 | @abstractmethod 18 | def stepTwo(self): 19 | pass 20 | 21 | @abstractmethod 22 | def stepThree(self): 23 | pass 24 | 25 | def templateMethold(self): 26 | """模板方法""" 27 | self.stepOne() 28 | self.stepTwo() 29 | self.stepThree() 30 | 31 | 32 | class TemplateImplA(Template): 33 | """模板实现类A""" 34 | 35 | def stepOne(self): 36 | print("步骤一") 37 | 38 | def stepTwo(self): 39 | print("步骤二") 40 | 41 | def stepThree(self): 42 | print("步骤三") 43 | 44 | 45 | class TemplateImplB(Template): 46 | """模板实现类B""" 47 | 48 | def stepOne(self): 49 | print("Step one") 50 | 51 | def stepTwo(self): 52 | print("Step two") 53 | 54 | def stepThree(self): 55 | print("Step three") 56 | 57 | 58 | # Version 2.0 阅读器视图 59 | #======================================================================================================================= 60 | from abc import ABCMeta, abstractmethod 61 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 62 | 63 | class ReaderView(metaclass=ABCMeta): 64 | """阅读器视图""" 65 | 66 | def __init__(self): 67 | self.__curPageNum = 1 68 | 69 | def getPage(self, pageNum): 70 | self.__curPageNum = pageNum 71 | return "第" + str(pageNum) + "的内容" 72 | 73 | def prePage(self): 74 | """模板方法,往前翻一页""" 75 | content = self.getPage(self.__curPageNum - 1) 76 | self._displayPage(content) 77 | 78 | def nextPage(self): 79 | """模板方法,往后翻一页""" 80 | content = self.getPage(self.__curPageNum + 1) 81 | self._displayPage(content) 82 | 83 | @abstractmethod 84 | def _displayPage(self, content): 85 | """翻页效果""" 86 | pass 87 | 88 | 89 | class SmoothView(ReaderView): 90 | """左右平滑的视图""" 91 | 92 | def _displayPage(self, content): 93 | print("左右平滑:" + content) 94 | 95 | 96 | class SimulationView(ReaderView): 97 | """仿真翻页的视图""" 98 | 99 | def _displayPage(self, content): 100 | print("仿真翻页:" + content) 101 | 102 | 103 | # Test 104 | #======================================================================================================================= 105 | def testReader(): 106 | smoothView = SmoothView() 107 | smoothView.nextPage() 108 | smoothView.prePage() 109 | 110 | simulationView = SimulationView() 111 | simulationView.nextPage() 112 | simulationView.prePage() 113 | 114 | def testTemplate(): 115 | templateA = TemplateImplA() 116 | templateA.templateMethold() 117 | templateB = TemplateImplB() 118 | templateB.templateMethold() 119 | 120 | 121 | testReader() 122 | # testTemplate() -------------------------------------------------------------------------------- /pattern/Visitor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 6/30/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | # from abc import ABCMeta, abstractmethod 8 | # # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | # 10 | # class DesignPatternBook: 11 | # """《从生活的角度解读设计模式》一书""" 12 | # def getName(self): 13 | # return "《从生活的角度解读设计模式》" 14 | # 15 | # 16 | # class Reader(metaclass=ABCMeta): 17 | # """访问者,也就是读者""" 18 | # 19 | # @abstractmethod 20 | # def read(self, book): 21 | # pass 22 | # 23 | # class Engineer(Reader): 24 | # """工程师""" 25 | # 26 | # def read(self, book): 27 | # print("技术狗读%s一书后的感受:能抓住模式的核心思想,深入浅出,很有见地!" % book.getName()) 28 | # 29 | # 30 | # class ProductManager(Reader): 31 | # """产品经理""" 32 | # 33 | # def read(self, book): 34 | # print("产品经理读%s一书后的感受:配图非常有趣,文章很有层次感!" % book.getName()) 35 | # 36 | # class OtherFriend(Reader): 37 | # """IT圈外的朋友""" 38 | # 39 | # def read(self, book): 40 | # print("IT圈外的朋友读%s一书后的感受:技术的内容一脸懵逼,但故事很精彩,像是看小说或是故事集!" 41 | # % book.getName()) 42 | 43 | # Version 2.0 44 | #======================================================================================================================= 45 | # 代码框架 46 | #============================== 47 | from abc import ABCMeta, abstractmethod 48 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 49 | 50 | class DataNode(metaclass=ABCMeta): 51 | """数据结构类""" 52 | 53 | def accept(self, visitor): 54 | """接受访问者的访问""" 55 | visitor.visit(self) 56 | 57 | class Visitor(metaclass=ABCMeta): 58 | """访问者""" 59 | 60 | @abstractmethod 61 | def visit(self, data): 62 | """对数据对象的访问操作""" 63 | pass 64 | 65 | 66 | class ObjectStructure: 67 | """数据结构的管理类,也是数据对象的一个容器,可遍历容器内的所有元素""" 68 | 69 | def __init__(self): 70 | self.__datas = [] 71 | 72 | def add(self, dataElement): 73 | self.__datas.append(dataElement) 74 | 75 | def action(self, visitor): 76 | """进行数据访问的操作""" 77 | for data in self.__datas: 78 | data.accept(visitor) 79 | 80 | 81 | # 基于框架的实现 82 | #============================== 83 | class DesignPatternBook(DataNode): 84 | """《从生活的角度解读设计模式》一书""" 85 | 86 | def getName(self): 87 | return "《从生活的角度解读设计模式》" 88 | 89 | 90 | class Engineer(Visitor): 91 | """工程师""" 92 | 93 | def visit(self, book): 94 | print("技术狗读%s一书后的感受:能抓住模式的核心思想,深入浅出,很有见地!" % book.getName()) 95 | 96 | 97 | class ProductManager(Visitor): 98 | """产品经理""" 99 | 100 | def visit(self, book): 101 | print("产品经理读%s一书后的感受:配图非常有趣,文章很有层次感!" % book.getName()) 102 | 103 | 104 | class OtherFriend(Visitor): 105 | """IT圈外的朋友""" 106 | 107 | def visit(self, book): 108 | print("IT圈外的朋友读%s一书后的感受:技术的内容一脸懵逼,但故事很精彩,像是看小说或是故事集!" 109 | % book.getName()) 110 | 111 | 112 | # 实战 113 | # ======================================================================================================================= 114 | class Animal(DataNode): 115 | """动物类""" 116 | 117 | def __init__(self, name, isMale, age, weight): 118 | self.__name = name 119 | self.__isMale = isMale 120 | self.__age = age 121 | self.__weight = weight 122 | 123 | def getName(self): 124 | return self.__name 125 | 126 | def isMale(self): 127 | return self.__isMale 128 | 129 | def getAge(self): 130 | return self.__age 131 | 132 | def getWeight(self): 133 | return self.__weight 134 | 135 | class Cat(Animal): 136 | """猫""" 137 | 138 | def __init__(self, name, isMale, age, weight): 139 | super().__init__(name, isMale, age, weight) 140 | 141 | def speak(self): 142 | print("miao~") 143 | 144 | 145 | class Dog(Animal): 146 | """狗""" 147 | 148 | def __init__(self, name, isMale, age, weight): 149 | super().__init__( name, isMale, age, weight) 150 | 151 | def speak(self): 152 | print("wang~") 153 | 154 | 155 | class GenderCounter(Visitor): 156 | """性别统计""" 157 | 158 | def __init__(self): 159 | self.__maleCat = 0 160 | self.__femaleCat = 0 161 | self.__maleDog = 0 162 | self.__femalDog = 0 163 | 164 | def visit(self, data): 165 | if isinstance(data, Cat): 166 | if data.isMale(): 167 | self.__maleCat += 1 168 | else: 169 | self.__femaleCat += 1 170 | elif isinstance(data, Dog): 171 | if data.isMale(): 172 | self.__maleDog += 1 173 | else: 174 | self.__femalDog += 1 175 | else: 176 | print("Not support this type") 177 | 178 | def getInfo(self): 179 | print("%d只雄猫,%d只雌猫,%d只雄狗,%d只雌狗。" 180 | % (self.__maleCat, self.__femaleCat, self.__maleDog, self.__femalDog) ) 181 | 182 | 183 | class WeightCounter(Visitor): 184 | """体重的统计""" 185 | 186 | def __init__(self): 187 | self.__catNum = 0 188 | self.__catWeight = 0 189 | self.__dogNum = 0 190 | self.__dogWeight = 0 191 | 192 | def visit(self, data): 193 | if isinstance(data, Cat): 194 | self.__catNum +=1 195 | self.__catWeight += data.getWeight() 196 | elif isinstance(data, Dog): 197 | self.__dogNum += 1 198 | self.__dogWeight += data.getWeight() 199 | else: 200 | print("Not support this type") 201 | 202 | def getInfo(self): 203 | print("猫的平均体重是:%0.2fkg, 狗的平均体重是:%0.2fkg" % 204 | ((self.__catWeight / self.__catNum),(self.__dogWeight / self.__dogNum))) 205 | 206 | 207 | class AgeCounter(Visitor): 208 | """年龄统计""" 209 | 210 | def __init__(self): 211 | self.__catMaxAge = 0 212 | self.__dogMaxAge = 0 213 | 214 | def visit(self, data): 215 | if isinstance(data, Cat): 216 | if self.__catMaxAge < data.getAge(): 217 | self.__catMaxAge = data.getAge() 218 | elif isinstance(data, Dog): 219 | if self.__dogMaxAge < data.getAge(): 220 | self.__dogMaxAge = data.getAge() 221 | else: 222 | print("Not support this type") 223 | 224 | def getInfo(self): 225 | print("猫的最大年龄是:%s,狗的最大年龄是:%s" % (self.__catMaxAge, self.__dogMaxAge) ) 226 | 227 | # Test 228 | #======================================================================================================================= 229 | 230 | def testBook(): 231 | book = DesignPatternBook() 232 | fans = [Engineer(), ProductManager(), OtherFriend()]; 233 | for fan in fans: 234 | fan.read(book) 235 | 236 | def testVisitBook(): 237 | book = DesignPatternBook() 238 | objMgr = ObjectStructure() 239 | objMgr.add(book) 240 | objMgr.action(Engineer()) 241 | objMgr.action(ProductManager()) 242 | objMgr.action(OtherFriend()) 243 | 244 | 245 | def testAnimal(): 246 | animals = ObjectStructure() 247 | animals.add(Cat("Cat1", True, 1, 5)) 248 | animals.add(Cat("Cat2", False, 0.5, 3)) 249 | animals.add(Cat("Cat3", False, 1.2, 4.2)) 250 | animals.add(Dog("Dog1", True, 0.5, 8)) 251 | animals.add(Dog("Dog2", True, 3, 52)) 252 | animals.add(Dog("Dog3", False, 1, 21)) 253 | animals.add(Dog("Dog4", False, 2, 25)) 254 | genderCounter = GenderCounter() 255 | animals.action(genderCounter) 256 | genderCounter.getInfo() 257 | print() 258 | 259 | weightCounter = WeightCounter() 260 | animals.action(weightCounter) 261 | weightCounter.getInfo() 262 | print() 263 | 264 | ageCounter = AgeCounter() 265 | animals.action(ageCounter) 266 | ageCounter.getInfo() 267 | 268 | 269 | # testBook() 270 | # testVisitBook() 271 | testAnimal() -------------------------------------------------------------------------------- /principle/DIP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 8/7/2018 4 | 5 | # Dependence Inversion Principle, 简称DIP 6 | 7 | from abc import ABCMeta, abstractmethod 8 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 9 | 10 | class Animal(metaclass=ABCMeta): 11 | """动物""" 12 | 13 | def __init__(self, name): 14 | self._name = name 15 | 16 | def eat(self, food): 17 | if(self.checkFood(food)): 18 | print(self._name + "进食" + food.getName()) 19 | else: 20 | print(self._name + "不吃" + food.getName()) 21 | 22 | @abstractmethod 23 | def checkFood(self, food): 24 | """检查哪种食物能吃""" 25 | pass 26 | 27 | 28 | class Dog(Animal): 29 | """狗""" 30 | 31 | def __init__(self): 32 | super().__init__("狗") 33 | 34 | def checkFood(self, food): 35 | return food.category() == "肉类" 36 | 37 | 38 | class Swallow(Animal): 39 | """燕子""" 40 | 41 | def __init__(self): 42 | super().__init__("燕子") 43 | 44 | def checkFood(self, food): 45 | return food.category() == "昆虫" 46 | 47 | 48 | class Food(metaclass=ABCMeta): 49 | """食物""" 50 | 51 | def __init__(self, name): 52 | self._name = name 53 | 54 | def getName(self): 55 | return self._name 56 | 57 | @abstractmethod 58 | def category(self): 59 | """食物类别""" 60 | pass 61 | 62 | @abstractmethod 63 | def nutrient(self): 64 | """营养成分""" 65 | pass 66 | 67 | 68 | class Meat(Food): 69 | """肉""" 70 | 71 | def __init__(self): 72 | super().__init__("肉") 73 | 74 | def category(self): 75 | return "肉类" 76 | 77 | def nutrient(self): 78 | return "蛋白质、脂肪" 79 | 80 | 81 | class Worm(Food): 82 | """虫子""" 83 | 84 | def __init__(self): 85 | super().__init__("虫子") 86 | 87 | def category(self): 88 | return "昆虫" 89 | 90 | def nutrient(self): 91 | return "蛋白质含、微量元素" 92 | 93 | 94 | def testFood(): 95 | dog = Dog() 96 | swallow = Swallow() 97 | meat = Meat() 98 | worm = Worm() 99 | dog.eat(meat) 100 | dog.eat(worm) 101 | swallow.eat(meat) 102 | swallow.eat(worm) 103 | 104 | 105 | testFood() -------------------------------------------------------------------------------- /principle/DRY.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 8/11/2018 4 | 5 | # import os 6 | # # 导入os库,用于文件、路径相关的解析 7 | 8 | # def getPath(basePath, fileName): 9 | # extName = os.path.splitext(fileName)[1] 10 | # filePath = basePath 11 | # if(extName.lower() == ".txt"): 12 | # filePath += "/txt/" 13 | # elif(extName.lower() == ".pdf"): 14 | # filePath += "/pdf/" 15 | # else: 16 | # filePath += "/other/" 17 | # 18 | # # 如果目录不存在,则创建新目录 19 | # if (not os.path.exists(filePath)): 20 | # os.makedirs(filePath) 21 | # 22 | # filePath += fileName 23 | # return filePath 24 | 25 | 26 | import os 27 | # 导入os库,用于文件、路径相关的解析 28 | 29 | def getPath(basePath, fileName): 30 | extName = fileName.split(".")[1] 31 | filePath = basePath + "/" + extName + "/" 32 | 33 | # 如果目录不存在,则创建新目录 34 | if (not os.path.exists(filePath)): 35 | os.makedirs(filePath) 36 | 37 | filePath += fileName 38 | return filePath 39 | 40 | print(getPath("E:/upload", "TestFile.rar")) 41 | print(getPath("E:/upload", "Design Pattern for Python.pdf")) -------------------------------------------------------------------------------- /principle/ISP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 8/7/2018 4 | 5 | # Interface Segregation Principle(ISP) 6 | 7 | 8 | from abc import ABCMeta, abstractmethod 9 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 10 | 11 | class Animal(metaclass=ABCMeta): 12 | """(脊椎)动物""" 13 | 14 | def __init__(self, name): 15 | self._name = name 16 | 17 | def getName(self): 18 | return self._name 19 | 20 | @abstractmethod 21 | def feature(self): 22 | pass 23 | 24 | @abstractmethod 25 | def moving(self): 26 | pass 27 | 28 | 29 | class IRunnable(metaclass=ABCMeta): 30 | """奔跑的接口""" 31 | 32 | @abstractmethod 33 | def running(self): 34 | pass 35 | 36 | class IFlyable(metaclass=ABCMeta): 37 | """飞行的接口""" 38 | 39 | @abstractmethod 40 | def flying(self): 41 | pass 42 | 43 | class INatatory(metaclass=ABCMeta): 44 | """游泳的接口""" 45 | 46 | @abstractmethod 47 | def swimming(self): 48 | pass 49 | 50 | 51 | class MammalAnimal(Animal, IRunnable): 52 | """哺乳动物""" 53 | 54 | def __init__(self, name): 55 | super().__init__(name) 56 | 57 | def feature(self): 58 | print(self._name + "的生理特征:恒温,胎生,哺乳。") 59 | 60 | def running(self): 61 | print("在陆上跑...") 62 | 63 | def moving(self): 64 | print(self._name + "的活动方式:", end="") 65 | self.running() 66 | 67 | 68 | class BirdAnimal(Animal, IFlyable): 69 | """鸟类动物""" 70 | 71 | def __init__(self, name): 72 | super().__init__(name) 73 | 74 | def feature(self): 75 | print(self._name + "的生理特征:恒温,卵生,前肢成翅。") 76 | 77 | def flying(self): 78 | print("在天空飞...") 79 | 80 | def moving(self): 81 | print(self._name + "的活动方式:", end="") 82 | self.flying() 83 | 84 | class FishAnimal(Animal, INatatory): 85 | """鱼类动物""" 86 | 87 | def __init__(self, name): 88 | super().__init__(name) 89 | 90 | def feature(self): 91 | print(self._name + "的生理特征:流线型体形,用鳃呼吸。") 92 | 93 | def swimming(self): 94 | print("在水里游...") 95 | 96 | def moving(self): 97 | print(self._name + "的活动方式:", end="") 98 | self.swimming() 99 | 100 | 101 | class Bat(MammalAnimal, IFlyable): 102 | """蝙蝠""" 103 | 104 | def __init__(self, name): 105 | super().__init__(name) 106 | 107 | def running(self): 108 | print("行走功能已经退化。") 109 | 110 | def flying(self): 111 | print("在天空飞...", end="") 112 | 113 | def moving(self): 114 | print(self._name + "的活动方式:", end="") 115 | self.flying() 116 | self.running() 117 | 118 | class Swan(BirdAnimal, IRunnable, INatatory): 119 | """天鹅""" 120 | 121 | def __init__(self, name): 122 | super().__init__(name) 123 | 124 | def running(self): 125 | print("在陆上跑...", end="") 126 | 127 | def swimming(self): 128 | print("在水里游...", end="") 129 | 130 | def moving(self): 131 | print(self._name + "的活动方式:", end="") 132 | self.running() 133 | self.swimming() 134 | self.flying() 135 | 136 | class CrucianCarp(FishAnimal): 137 | """鲫鱼""" 138 | 139 | def __init__(self, name): 140 | super().__init__(name) 141 | 142 | 143 | def testAnimal(): 144 | bat = Bat("蝙蝠") 145 | bat.feature() 146 | bat.moving() 147 | swan = Swan("天鹅") 148 | swan.feature() 149 | swan.moving() 150 | crucianCarp = CrucianCarp("鲫鱼") 151 | crucianCarp.feature() 152 | crucianCarp.moving() 153 | 154 | 155 | testAnimal() -------------------------------------------------------------------------------- /principle/LSP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 8/7/2018 4 | 5 | 6 | # Liskov Substitution Principle, LSP 7 | 8 | from abc import ABCMeta, abstractmethod 9 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 10 | 11 | class Animal(metaclass=ABCMeta): 12 | """动物""" 13 | 14 | def __init__(self, name): 15 | self._name = name 16 | 17 | @abstractmethod 18 | def moving(self): 19 | pass 20 | 21 | class TerrestrialAnimal(Animal): 22 | """陆生生物""" 23 | 24 | def __init__(self, name): 25 | super().__init__(name) 26 | 27 | def moving(self): 28 | print(self._name + "在陆上跑...") 29 | 30 | 31 | class AquaticAnimal(Animal): 32 | """水生生物""" 33 | 34 | def __init__(self, name): 35 | super().__init__(name) 36 | 37 | def moving(self): 38 | print(self._name + "在水里游...") 39 | 40 | 41 | class BirdAnimal(Animal): 42 | """鸟类动物""" 43 | 44 | def __init__(self, name): 45 | super().__init__(name) 46 | 47 | def moving(self): 48 | print(self._name + "在天空飞...") 49 | 50 | 51 | class Monkey(TerrestrialAnimal): 52 | """猴子""" 53 | 54 | def __init__(self, name): 55 | super().__init__(name) 56 | 57 | def climbing(self): 58 | print(self._name + "在爬树,动作灵活轻盈...") 59 | 60 | 61 | # 修改Zoo类,增加climbing方法: 62 | class Zoo: 63 | """动物园""" 64 | 65 | def __init__(self): 66 | self.__animals =[] 67 | 68 | def addAnimal(self, animal): 69 | self.__animals.append(animal) 70 | 71 | def displayActivity(self): 72 | print("观察每一种动物的活动方式:") 73 | for animal in self.__animals: 74 | animal.moving() 75 | 76 | def monkeyClimbing(self, monkey): 77 | monkey.climbing() 78 | 79 | 80 | 81 | 82 | def testZoo(): 83 | zoo = Zoo() 84 | zoo.addAnimal(TerrestrialAnimal("狗")) 85 | zoo.addAnimal(AquaticAnimal("鱼")) 86 | zoo.addAnimal(BirdAnimal("鸟")) 87 | monkey = Monkey("猴子") 88 | zoo.addAnimal(monkey) 89 | zoo.displayActivity() 90 | print() 91 | print("观察猴子的爬树行为:") 92 | zoo.monkeyClimbing(monkey) 93 | 94 | testZoo() -------------------------------------------------------------------------------- /principle/LoD.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 8/7/2018 4 | 5 | # Version 1.0 6 | #======================================================================================================================= 7 | 8 | 9 | # Version 2.0 10 | #======================================================================================================================= 11 | # 代码框架 12 | #============================== 13 | 14 | 15 | # 基于框架的实现 16 | #============================== 17 | 18 | 19 | # Test 20 | #======================================================================================================================= 21 | 22 | -------------------------------------------------------------------------------- /principle/OCP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 8/7/2018 4 | 5 | # Open Close Principle,OCP 6 | 7 | 8 | 9 | # class Zoo: 10 | # """动物园""" 11 | # 12 | # def __init__(self): 13 | # self.__animals =[ 14 | # TerrestrialAnimal("狗"), 15 | # AquaticAnimal("鱼") 16 | # ] 17 | # 18 | # def displayActivity(self): 19 | # for animal in self.__animals: 20 | # if isinstance(animal, TerrestrialAnimal): 21 | # animal.running() 22 | # else: 23 | # animal.swimming() 24 | # 25 | # zoo = Zoo() 26 | # zoo.displayActivity() 27 | 28 | 29 | 30 | # def displayActivity(self): 31 | # for animal in self.__animals: 32 | # if isinstance(animal, TerrestrialAnimal): 33 | # animal.running() 34 | # elif isinstance(animal, BirdAnimal) 35 | # animal.flying() 36 | # else: 37 | # animal.swimming() 38 | 39 | 40 | 41 | from abc import ABCMeta, abstractmethod 42 | # 引入ABCMeta和abstractmethod来定义抽象类和抽象方法 43 | 44 | class Animal(metaclass=ABCMeta): 45 | """动物""" 46 | 47 | def __init__(self, name): 48 | self._name = name 49 | 50 | @abstractmethod 51 | def moving(self): 52 | pass 53 | 54 | class TerrestrialAnimal(Animal): 55 | """陆生生物""" 56 | 57 | def __init__(self, name): 58 | super().__init__(name) 59 | 60 | def moving(self): 61 | print(self._name + "在陆上跑...") 62 | 63 | 64 | class AquaticAnimal(Animal): 65 | """水生生物""" 66 | 67 | def __init__(self, name): 68 | super().__init__(name) 69 | 70 | def moving(self): 71 | print(self._name + "在水里游...") 72 | 73 | 74 | class BirdAnimal(Animal): 75 | """鸟类动物""" 76 | 77 | def __init__(self, name): 78 | super().__init__(name) 79 | 80 | def moving(self): 81 | print(self._name + "在天空飞...") 82 | 83 | 84 | class Zoo: 85 | """动物园""" 86 | 87 | def __init__(self): 88 | self.__animals =[] 89 | 90 | def addAnimal(self, animal): 91 | self.__animals.append(animal) 92 | 93 | def displayActivity(self): 94 | print("观察每一种动物的活动方式:") 95 | for animal in self.__animals: 96 | animal.moving() 97 | 98 | 99 | def testZoo(): 100 | zoo = Zoo() 101 | zoo.addAnimal(TerrestrialAnimal("狗")) 102 | zoo.addAnimal(AquaticAnimal("鱼")) 103 | zoo.addAnimal(BirdAnimal("鸟")) 104 | zoo.displayActivity() 105 | 106 | 107 | 108 | testZoo() -------------------------------------------------------------------------------- /principle/Principle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 6/30/2018 4 | 5 | 6 | # from . import SRP 7 | # from . import OCP 8 | # from . import LSP 9 | # from . import ISP 10 | # from . import DIP 11 | 12 | # from . import LoD 13 | from . import DRY 14 | 15 | # from . import Refactor 16 | -------------------------------------------------------------------------------- /principle/Refactor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 8/15/2018 4 | 5 | # 下面的例子改编自网上讨论比较火的几个案例 6 | 7 | # Demo1 8 | correct = False 9 | # 嗯,这是对呢?还是错呢? 10 | 11 | 12 | # Demo2 13 | from enum import Enum 14 | class Color(Enum): 15 | Green = 1 # 绿色 16 | Hong = 2 # 红色 17 | # 嗯,这哥们是红色(Red)的单词不会写呢,还是觉得绿色(Lv)的拼音太难看呢? 18 | 19 | 20 | # Demo3 21 | def dynamic(): 22 | pass 23 | # todo something 24 | # 你能想到这个函数是干嘛用的吗?其实是一个表示“活动”的函数。这英语是数学老师教的吗~ 25 | -------------------------------------------------------------------------------- /principle/SRP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Authoer: Spencer.Luo 3 | # Date: 8/7/2018 4 | 5 | # Single Responsibility Principle, SRP 6 | 7 | 8 | # class Animal: 9 | # """动物""" 10 | # 11 | # def __init__(self, name): 12 | # self.__name = name 13 | # 14 | # def running(self): 15 | # print(self.__name + "在跑...") 16 | # 17 | # 18 | # Animal("猫").running() 19 | # Animal("狗").running() 20 | 21 | 22 | # # First method 23 | # class Animal: 24 | # """动物""" 25 | # 26 | # def __init__(self, name, type): 27 | # self.__name = name 28 | # self.__type = type 29 | # 30 | # def running(self): 31 | # if(self.__type == "水生"): 32 | # print(self.__name + "在水里游...") 33 | # else: 34 | # print(self.__name + "在陆上跑...") 35 | # 36 | # 37 | # Animal("狗", "陆生").running() 38 | # Animal("鱼", "水生").running() 39 | 40 | 41 | # # Second method 42 | # class Animal: 43 | # """动物""" 44 | # 45 | # def __init__(self, name): 46 | # self.__name = name 47 | # 48 | # def running(self): 49 | # print(self.__name + "在陆上跑...") 50 | # 51 | # def swimming(self): 52 | # print(self.__name + "在水里游...") 53 | # 54 | # 55 | # Animal("狗").running() 56 | # Animal("鱼").swimming() 57 | 58 | 59 | 60 | # Third methold 61 | class TerrestrialAnimal(): 62 | """陆生生物""" 63 | 64 | def __init__(self, name): 65 | self.__name = name 66 | 67 | def running(self): 68 | print(self.__name + "在陆上跑...") 69 | 70 | 71 | class AquaticAnimal(): 72 | """水生生物""" 73 | 74 | def __init__(self, name): 75 | self.__name = name 76 | 77 | def swimming(self): 78 | print(self.__name + "在水里游...") 79 | 80 | 81 | TerrestrialAnimal("狗").running() 82 | AquaticAnimal("鱼").swimming() --------------------------------------------------------------------------------