├── README.md ├── protoType.lua ├── strategy.lua ├── singleton.lua ├── adapter.lua ├── LICENSE ├── decorator.lua ├── proxy.lua ├── facade.lua ├── responeChain.lua ├── template.lua ├── iterator.lua ├── component.lua ├── command.lua ├── simpleFactory.lua ├── mediator.lua ├── bridge.lua ├── observer.lua ├── flyweight.lua ├── factoryMethod.lua ├── memento.lua ├── state.lua ├── visitor.lua ├── abstractFactory.lua └── interpreter.lua /README.md: -------------------------------------------------------------------------------- 1 | # LuaDesignPattern 2 | 3 | [![LICENSE](https://img.shields.io/badge/license-Anti%20996-blue.svg)](https://github.com/996icu/996.ICU/blob/master/LICENSE) 4 | 5 | [![Badge](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu/#/zh_CN) 6 | 7 | 8 | lua design pattern example code 9 | -------------------------------------------------------------------------------- /protoType.lua: -------------------------------------------------------------------------------- 1 | -- 原形模式可分为深复制和浅复制,下面以浅复制为例 2 | 3 | Prototype = {} 4 | 5 | function Prototype:new(o) 6 | o = o or {} 7 | setmetatable(o, self) 8 | self.__index = self 9 | return o 10 | end 11 | 12 | function Prototype:Clone() 13 | return self 14 | end 15 | 16 | proto = Prototype:new() 17 | 18 | proto.val = 10 19 | 20 | cloneproto = proto:Clone() 21 | 22 | print(cloneproto.val) 23 | 24 | cloneproto.val = 123 25 | print(proto.val) -------------------------------------------------------------------------------- /strategy.lua: -------------------------------------------------------------------------------- 1 | Strategy = {} 2 | 3 | ConcreteStrategyA = {} 4 | ConcreteStrategyB = {} 5 | ConcreteStrategyC = {} 6 | 7 | Context = {strategy = nil} 8 | 9 | function Strategy:new(o) 10 | o = o or {} 11 | setmetatable(o,self) 12 | self.__index = self 13 | return o 14 | end 15 | 16 | function Strategy:AlgorithmInterface() 17 | print("逻辑接口") 18 | end 19 | 20 | 21 | ConcreteStrategyA = Strategy:new() 22 | function ConcreteStrategyA:AlgorithmInterface() 23 | print("具体策略 A") 24 | end 25 | 26 | function Context:new(o,s) 27 | o = o or {} 28 | setmetatable(o,self) 29 | self.__index = self 30 | if s ~= nil then 31 | o.strategy = s 32 | end 33 | return o 34 | end 35 | 36 | 37 | function Context:ContextInterface() 38 | self.strategy:AlgorithmInterface() 39 | end 40 | 41 | context = Context:new({},ConcreteStrategyA:new()) 42 | context:ContextInterface() -------------------------------------------------------------------------------- /singleton.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 优点 3 | 1 实例控制 4 | 单例模式会阻止其他对象实例化其自己的单例对象副本,从而确保所有对象都访问唯一实例 5 | 2 灵活性 6 | 因为类控制了实例化过程,所以类可以灵活更改实例化过程 7 | 8 | 缺点 9 | 1 开销 10 | 虽然数量很少,但如果每次对象请求引用时都要检查是否存在类实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题 11 | 2 可能的开发混淆 12 | 使用单例对象 尤其在类库中定义的对象 时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码, 13 | 因此应用程序开发人员可能会意外发现自己无法直接实例化此类。 14 | 3 对象生存周期 15 | 不能解决删除单个对象的问题,在提供内存管理语言中,只有单例类能够导致实例被取消分配,因为它包含对该实例私有引用。在某些 16 | 语言中,其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。 17 | ]] 18 | 19 | Singleton = {} 20 | 21 | function Singleton:new(o) 22 | o = o or {} 23 | setmetatable(o, self) 24 | self.__index = self 25 | return o 26 | end 27 | 28 | function Singleton:Instance() 29 | if self.instance == nil then 30 | self.instance = self:new() 31 | end 32 | return self.instance 33 | end 34 | 35 | s1 = Singleton:Instance() 36 | s2 = Singleton:Instance() 37 | 38 | if s1 == s2 then 39 | print("the same object.") 40 | end -------------------------------------------------------------------------------- /adapter.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能 3 | 一起工作的那些类可以一起工作 4 | 5 | 应用: 6 | 例如联合国开会,每个国家的领导说着自己国家的语言,但接收着却有不同国家的人, 7 | 因此国家领导人需要翻译,这个翻译就是适配器 8 | 9 | 例如我们玩游戏,特别玩以前不同平台的游戏,我们需要一个模拟器,这个模拟器就是适配器 10 | ]] 11 | 12 | Target = {} 13 | function Target:new(o) 14 | o = o or {} 15 | setmetatable(o, self) 16 | self.__index = self 17 | return o 18 | end 19 | 20 | function Target:Listen(content) 21 | print(content) 22 | end 23 | 24 | Adaptee = {} 25 | function Adaptee:new(o) 26 | o = o or {} 27 | setmetatable(o, self) 28 | self.__index = self 29 | return o 30 | end 31 | 32 | function Adaptee:Translate(content) 33 | return "are you happy" 34 | end 35 | 36 | Adapter = Target:new() 37 | function Adapter:new(o) 38 | o = o or {} 39 | setmetatable(o, self) 40 | self.__index = self 41 | o.adaptee = Adaptee:new() 42 | return o 43 | end 44 | 45 | function Adapter:Listen(content) 46 | print(self.adaptee:Translate(content)) 47 | end 48 | 49 | c = "aaaaaaa" 50 | aobama = Adapter:new() 51 | aobama:Listen(c) 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /decorator.lua: -------------------------------------------------------------------------------- 1 | Person = {} 2 | 3 | function Person:new(o) 4 | o = o or {} 5 | setmetatable(o,self) 6 | self.__index = self 7 | return o 8 | end 9 | 10 | function Person:Show() 11 | print("i am person") 12 | end 13 | 14 | Decorator = Person:new{component = nil} 15 | 16 | function Decorator:Decorate(com) 17 | self.component = com 18 | end 19 | 20 | function Decorator:Show() 21 | print("i am decorator") 22 | end 23 | 24 | Shirt = Decorator:new() 25 | function Shirt:Show() 26 | print("i am shirt") 27 | if self.component ~= nil then 28 | self.component:Show() 29 | end 30 | end 31 | 32 | Trouser = Decorator:new() 33 | 34 | function Trouser:Show() 35 | print("i am Trouser") 36 | if self.component ~= nil then 37 | self.component:Show() 38 | end 39 | end 40 | 41 | Shoe = Decorator:new() 42 | function Shoe:Show() 43 | print("i am Shoe") 44 | if self.component ~= nil then 45 | self.component:Show() 46 | end 47 | end 48 | 49 | person = Person:new() 50 | 51 | shirt = Shirt:new() 52 | shirt:Decorate(person) 53 | 54 | trouser = Trouser:new() 55 | trouser:Decorate(shirt) 56 | 57 | shoe = Shoe:new() 58 | shoe:Decorate(trouser) 59 | 60 | shoe:Show() 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /proxy.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 背景: 陈冠希想追张柏芝,但是无从下手,于是找来了谢婷风 3 | 陈冠希叫谢婷风帮他送洋娃娃,玫瑰花,巧克力。于是谢婷风就是代理人 4 | ]] 5 | 6 | GiveGift = {girlname = nil} 7 | 8 | function GiveGift:new(o) 9 | o = o or {} 10 | setmetatable(o, self) 11 | self.__index = self 12 | return o 13 | end 14 | 15 | 16 | Pursuit = GiveGift:new() 17 | function Pursuit:new(o, name) 18 | o = o or {} 19 | setmetatable(o, self) 20 | self.__index = self 21 | o.girlname = name 22 | return o 23 | end 24 | 25 | function Pursuit:GiveDolls() 26 | if self.girlname ~= nil then 27 | print("give" .. self.girlname .. "doll") 28 | end 29 | end 30 | 31 | function Pursuit:GiveFlowers() 32 | if self.girlname ~= nil then 33 | print("give" .. self.girlname .. "Flowers") 34 | end 35 | end 36 | 37 | function Pursuit:GiveChocolate() 38 | if self.girlname ~= nil then 39 | print("give" .. self.girlname .. "Chocolate") 40 | end 41 | end 42 | 43 | Proxy = GiveGift:new() 44 | 45 | function Proxy:new(o,name) 46 | o = o or {} 47 | setmetatable(o,self) 48 | self.__index = self 49 | o.pursuit = Pursuit:new({}, name) 50 | return o 51 | end 52 | 53 | function Proxy:GiveDolls() 54 | self.pursuit:GiveDolls() 55 | end 56 | 57 | function Proxy:GiveFlowers() 58 | self.pursuit:GiveFlowers() 59 | end 60 | 61 | function Proxy:GiveChocolate() 62 | self.pursuit:GiveChocolate() 63 | end 64 | 65 | XieTingFeng = Proxy:new({}, "ZhangBoZhi") 66 | XieTingFeng:GiveDolls() 67 | XieTingFeng:GiveFlowers() 68 | XieTingFeng:GiveChocolate() -------------------------------------------------------------------------------- /facade.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 优点:外观模式的目的不是给子系统添加新的功能接口, 3 | 而是为了让外部减少与子系统内多个模块的交互, 4 | 松散耦合,从而让外部能够更简单的使用子系统。 5 | 当然,这是一把双刃剑 6 | 7 | 缺点:不能很好的限制客户端直接使用子系统类, 8 | 如果对客户端访问子系统类做太多的限制则减少了 9 | 可变性和灵活性 10 | 下面外部只与Facade交互,而facade与system交互, 11 | 从而达到上述优点 12 | ]] 13 | 14 | System = {} 15 | function System:new(o) 16 | o = o or {} 17 | setmetatable(o, self) 18 | self.__index = self 19 | return o 20 | end 21 | 22 | SubSystemOne = System:new() 23 | 24 | function SubSystemOne:Method1() 25 | print("SubSystemOne:Method1") 26 | end 27 | 28 | function SubSystemOne:Method2() 29 | print("SubSystemOne:Method2") 30 | end 31 | 32 | function SubSystemOne:Method3() 33 | print("SubSystemOne:Method3") 34 | end 35 | 36 | SubSystemTwo = System:new() 37 | 38 | function SubSystemTwo:Method1() 39 | print("SubSystemTwo:Method1") 40 | end 41 | 42 | function SubSystemTwo:Method2() 43 | print("SubSystemTwo:Method2") 44 | end 45 | 46 | function SubSystemTwo:Method3() 47 | print("SubSystemTwo:Method3") 48 | end 49 | 50 | Facade = {} 51 | function Facade:new(o) 52 | o = o or {} 53 | setmetatable(o, self) 54 | self.__index = self 55 | o.one = SubSystemOne:new() 56 | o.two = SubSystemTwo:new() 57 | return o 58 | end 59 | 60 | function Facade:Method1() 61 | self.one:Method1() 62 | self.two:Method1() 63 | end 64 | 65 | function Facade:Method2() 66 | self.one:Method2() 67 | self.two:Method2() 68 | end 69 | 70 | function Facade:Method3() 71 | self.one:Method3() 72 | self.two:Method3() 73 | end 74 | 75 | facade = Facade:new() 76 | facade:Method1() -------------------------------------------------------------------------------- /responeChain.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 2. 职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关 3 | 系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 4 | 3. 应用: 5 | 4. 1、有多个对象处理请求,到底怎么处理在运行时确定。 6 | 5. 2、希望在不明确指定接收者的情况下,向多个对象中的一个提交请求。 7 | 6. 3、可处理一个请求的对象集合应该被动态指定。 8 | 7. ]]-- 9 | 10 | Handler = {} 11 | 12 | function Handler:new(o) 13 | o = o or {} 14 | setmetatable(o,self) 15 | self.__index = self 16 | return o; 17 | end 18 | 19 | function Handler:SetSuccessor(s) 20 | self.successor = s 21 | end 22 | 23 | ConcreteHandler1 = Handler:new() 24 | 25 | 26 | function ConcreteHandler1:HandleRequest(r) 27 | if r <= 10 then 28 | print("Handler1 处理了请求") 29 | elseif self.successor then 30 | self.successor:HandleRequest(r) 31 | end 32 | end 33 | 34 | ConcreteHandler2 = Handler:new() 35 | 36 | function ConcreteHandler2:HandleRequest(r) 37 | if r > 10 and r <= 20 then 38 | print("Handler2 处理了请求") 39 | elseif self.successor then 40 | self.successor:HandleRequest(r) 41 | end 42 | end 43 | 44 | ConcreteHandler3 = Handler:new() 45 | 46 | function ConcreteHandler3:HandleRequest(r) 47 | if r > 20 then 48 | print("Handler3 处理了请求") 49 | elseif self.successor then 50 | self.successor:HandleRequest(r) 51 | end 52 | end 53 | 54 | h1 = ConcreteHandler1:new() 55 | h2 = ConcreteHandler2:new() 56 | h3 = ConcreteHandler3:new() 57 | 58 | h1:SetSuccessor(h2) 59 | h2:SetSuccessor(h3) 60 | 61 | print("*********************实例一***********************") 62 | h1:HandleRequest(25) 63 | h2:HandleRequest(5) 64 | h3:HandleRequest(15) 65 | 66 | print("*********************实例二***********************") 67 | h1:HandleRequest(25) 68 | h1:HandleRequest(5) 69 | h1:HandleRequest(15) 70 | --[[ 71 | 71. PS: 72 | 72. 当时"弄懂"了职责链模式后,不禁心里大骂:尼玛,这不就是状态模式吗?! 73 | 73. 后来细心地发现了其中的不同: 74 | 74. 状态模式:后一个状态的处理对象早已在类的内部设定好了。 75 | 75. 职责链模式:后一个请求的处理对象由客户端来设定。 76 | 76. 77 | 77. ]]-- 78 | -------------------------------------------------------------------------------- /template.lua: -------------------------------------------------------------------------------- 1 | --模板方法模式是通过把不变行为搬移到基类,去除之类中的重复代码来体现它的优势。 2 | -- 下面以考试试卷为例,试题都是一样的,但是答案可能不一样 3 | 4 | TestPaper = {} 5 | 6 | function TestPaper:new(o) 7 | o = o or {} 8 | setmetatable(o,self) 9 | self.__index = self 10 | return o 11 | end 12 | 13 | function TestPaper:TestQuestion1() 14 | print("孙悟空的师弟是谁?") 15 | print("A 猪七戒 B 猪八戒 C 猪九戒") 16 | print("答案是:"..self:Answer1()) 17 | end 18 | 19 | function TestPaper:Answer1() 20 | return "" 21 | end 22 | 23 | function TestPaper:TestQuestion2() 24 | print("猪八戒的师弟是谁?") 25 | print("A 沙和尚 B 沙道士 C 沙井盖") 26 | print("答案是:"..self:Answer2()) 27 | end 28 | 29 | function TestPaper:Answer2() 30 | return "" 31 | end 32 | 33 | function TestPaper:TestQuestion3() 34 | print("沙和尚的大师兄是谁?") 35 | print("A 孙中山 B 孙权 C 孙悟空") 36 | print("答案是:"..self:Answer3()) 37 | end 38 | 39 | function TestPaper:Answer3() 40 | return "" 41 | end 42 | 43 | --小组 A 的试卷 44 | GroupATestPaper = TestPaper:new() 45 | 46 | function GroupATestPaper:Answer1() 47 | return "B" 48 | end 49 | 50 | function GroupATestPaper:Answer2() 51 | return "C" 52 | end 53 | 54 | function GroupATestPaper:Answer3() 55 | return "A" 56 | end 57 | 58 | --小组 B 的试卷 59 | GroupBTestPaper = TestPaper:new() 60 | 61 | function GroupBTestPaper:Answer1() 62 | return "A" 63 | end 64 | 65 | function GroupBTestPaper:Answer2() 66 | return "B" 67 | end 68 | 69 | function GroupBTestPaper:Answer3() 70 | return "C" 71 | end 72 | 73 | --小明是小组 A 的一员 74 | print("********小明的试卷*********") 75 | XiaoMingTestPaper = GroupATestPaper:new() 76 | XiaoMingTestPaper:TestQuestion1() 77 | XiaoMingTestPaper:TestQuestion2() 78 | XiaoMingTestPaper:TestQuestion3() 79 | 80 | --小红是小组 B 的一员 81 | print("********小红的试卷*********") 82 | XiaoHongTestPaper = GroupBTestPaper:new() 83 | XiaoHongTestPaper:TestQuestion1() 84 | XiaoHongTestPaper:TestQuestion2() 85 | XiaoHongTestPaper:TestQuestion3() -------------------------------------------------------------------------------- /iterator.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 2. 访问一个聚合对象的内容而无需暴露它的内部表示 3 | 3. 支持对聚合对象的多种遍历 4 | 4. 为遍历不同的聚合结构提供一个统一的接口 5 | 5. 6 | 6. 应用: 7 | 7. 最经典莫过于 C++ STL 了 8 | 8. ]]-- 9 | 10 | Iterator = {} 11 | 12 | function Iterator:new() 13 | o = o or {} 14 | setmetatable(o, self) 15 | self.__index = self 16 | return o 17 | end 18 | 19 | ConcreteIterator = Iterator:new() 20 | 21 | function ConcreteIterator:new(d) 22 | o = o or {} 23 | setmetatable(o, self) 24 | self.__index = self 25 | o.data = d 26 | o.index = 1 27 | o.size = table.getn(d) 28 | return o 29 | end 30 | 31 | function ConcreteIterator:Next() 32 | self.index = self.index + 1 33 | end 34 | 35 | function ConcreteIterator:IsDone() 36 | if self.index > self.size then 37 | return true 38 | end 39 | return false 40 | end 41 | 42 | function ConcreteIterator:GetItem() 43 | return self.data[self.index] 44 | end 45 | 46 | Aggregate = {} 47 | function Aggregate:new(o) 48 | o = o or {} 49 | setmetatable(o,self) 50 | self.__index = self 51 | return o; 52 | end 53 | 54 | ConcreteAggregate = Aggregate:new() 55 | function ConcreteAggregate:new(o) 56 | o = o or {} 57 | setmetatable(o,self) 58 | self.__index = self 59 | o.data = {} 60 | return o; 61 | end 62 | 63 | function ConcreteAggregate:CreateIterator() 64 | return ConcreteIterator:new(self.data) 65 | end 66 | 67 | function ConcreteAggregate:PushBack(d) 68 | table.insert(self.data,d) 69 | end 70 | 71 | function ConcreteAggregate:Remove(d) 72 | for k,v in pairs(self.data) do 73 | if v == d then 74 | table.remove(self.data,k) 75 | break 76 | end 77 | end 78 | end 79 | 80 | aggregate = ConcreteAggregate:new() 81 | 82 | aggregate:PushBack(true) 83 | aggregate:PushBack("QQ 群:") 84 | aggregate:PushBack(315249378) 85 | 86 | it = aggregate:CreateIterator() 87 | 88 | while it:IsDone() == false do 89 | print(it:GetItem()) 90 | it:Next() 91 | end -------------------------------------------------------------------------------- /component.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 组合模式使得用户对单个对象和组合对象的使用具有一致性 3 | 应用 4 | 1 你想表示对象的部分 整体层次结构 5 | 2 你希望用户忽略组合对象与单个对象的不同, 6 | 用户将统一使用组合结构中的所有对象 7 | 定义 8 | 1 component是组合中的对象声明接口,在适当的情况下 9 | 实现所有类共有接口的默认行为。声明一个接口用于访问和 10 | 管理component子部件。 11 | 2 leaf在组合中表示叶子节点对象,叶子节点没有子节点 12 | 3. composite定义有枝节点行为,用来存储子部件。 13 | 在component接口中实现与子部件有关操作,如增加 和 删除对象 14 | ]] 15 | 16 | Component = {} 17 | 18 | function Component:new(name) 19 | o = {} 20 | setmetatable(o, self) 21 | self.__index = self 22 | o.name = name 23 | return o 24 | end 25 | 26 | Composite = Component:new() 27 | 28 | function Composite:new(name) 29 | o = {} 30 | setmetatable(o, self) 31 | self.__index = self 32 | o.children = {} 33 | o.name = name 34 | return o 35 | end 36 | 37 | function Composite:Add(c) 38 | table.insert(self.children, c) 39 | end 40 | 41 | function Composite:Remove(c) 42 | for k, v in pairs(self.children) do 43 | if v == c then 44 | table.remove(self.children, k) 45 | end 46 | end 47 | end 48 | 49 | function Composite:Fuck() 50 | for _,v in pairs(self.children) do 51 | v:Fuck() 52 | end 53 | end 54 | 55 | function Composite:Announce() 56 | print(self.name) 57 | for _,v in pairs(self.children) do 58 | v:Announce() 59 | end 60 | end 61 | 62 | Leaf = Component:new() 63 | 64 | function Leaf:new(name) 65 | o = {} 66 | setmetatable(o, self) 67 | self.__index = self 68 | o.name = name 69 | return o 70 | end 71 | 72 | function Leaf:Fuck() 73 | print("fuck u," .. self.name) 74 | end 75 | 76 | function Leaf:Announce() 77 | print(self.name .. "hehehehehe.") 78 | end 79 | 80 | 81 | chengguanxi = Composite:new("称关系") 82 | first = Composite:new("第一批曝光") 83 | first:Add(Leaf:new("张柏芝")) 84 | first:Add(Leaf:new("钟欣桐")) 85 | chengguanxi:Add(first) 86 | 87 | second = Composite:new("第2批曝光") 88 | second:Add(Leaf:new("张柏芝2")) 89 | chengguanxi:Add(second) 90 | 91 | chengguanxi:Fuck() 92 | -------------------------------------------------------------------------------- /command.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 2. 优点: 3 | 3. 1.降低对象之间的耦合度。 4 | 4. 2.新的命令可以很容易地加入到系统中。 5 | 5. 3.可以比较容易地设计一个组合命令。 6 | 6. 4.调用同一方法实现不同的功能。 7 | 7. 缺点: 8 | 8. 使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一 9 | 个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。 10 | 9. 11 | 10. Command 类:是一个抽象类,类中对需要执行的命令进行声明,一般来说要对外公布一个 12 | execute 方法用来执行命令。 13 | 11. ConcreteCommand 类:Command 类的实现类,对抽象类中声明的方法进行实现。 14 | 12. Invoker 类:调用者,负责调用命令。 15 | 13. Receiver 类:接收者,负责接收命令并且执行命令。 16 | 14. ]]-- 17 | 18 | Command = {} 19 | 20 | function Command:new(r,o) 21 | o = o or {} 22 | setmetatable(o,self) 23 | self.__index = self 24 | o.receiver = r 25 | return o; 26 | end 27 | 28 | ConcreteCommand1 = Command:new() 29 | 30 | function ConcreteCommand1:Execute() 31 | self.receiver:Action1() 32 | end 33 | 34 | ConcreteCommand2 = Command:new() 35 | 36 | function ConcreteCommand2:Execute() 37 | self.receiver:Action2() 38 | end 39 | 40 | Receiver = {} 41 | function Receiver:new(o) 42 | o = o or {} 43 | setmetatable(o,self) 44 | self.__index = self 45 | return o; 46 | end 47 | 48 | function Receiver:Action1() 49 | print("来一条清蒸鱼") 50 | end 51 | 52 | function Receiver:Action2() 53 | print("来一个蛋糕") 54 | end 55 | 56 | Invoker = {} 57 | 58 | function Invoker:new(o) 59 | o = o or {} 60 | setmetatable(o,self) 61 | self.__index = self 62 | o.allcommand = {} 63 | return o; 64 | end 65 | 66 | function Invoker:SetCommand(c) 67 | table.insert(self.allcommand,c) 68 | end 69 | 70 | function Invoker:ExecuteCommand() 71 | for _,v in pairs(self.allcommand) do 72 | v:Execute() 73 | end 74 | end 75 | 76 | --厨师 是 Receiver 77 | chef = Receiver:new() 78 | --下面是两个菜(命令),执行者是 Receiver(chef) 79 | fish = ConcreteCommand1:new(chef) 80 | cake = ConcreteCommand2:new(chef) 81 | 82 | --调用者 是服务员 83 | waiter = Invoker:new() 84 | --服务员下达了两个菜(命令),执行者当然是 Receiver(chef) 85 | waiter:SetCommand(fish) 86 | waiter:SetCommand(cake) 87 | 88 | --看似服务员做了两个菜,实际是 Receiver 做,从而做了解耦;客人与厨师不用相互紧耦合 89 | waiter:ExecuteCommand() -------------------------------------------------------------------------------- /simpleFactory.lua: -------------------------------------------------------------------------------- 1 | OperationFactory = {} 2 | 3 | Operation = {} 4 | 5 | function Operation:new(o) 6 | o = o or {} 7 | setmetatable(o, self) 8 | self.__index = self 9 | o.numberA = 0 10 | o.numberB = 1 11 | return o 12 | end 13 | 14 | OperationAdd = Operation:new() 15 | 16 | OperationSub = Operation:new() 17 | 18 | OperationMul = Operation:new() 19 | 20 | OperationDiv = Operation:new() 21 | 22 | 23 | function OperationAdd:GetResult() 24 | if self.numberA and self.numberB then 25 | return self.numberA + self.numberB; 26 | else 27 | return "error" 28 | end 29 | end 30 | 31 | function OperationSub:GetResult() 32 | if self.numberA and self.numberB then 33 | return self.numberA - self.numberB; 34 | else 35 | return "error" 36 | end 37 | end 38 | 39 | function OperationMul:GetResult() 40 | if self.numberA and self.numberB then 41 | return self.numberA * self.numberB; 42 | else 43 | return "error" 44 | end 45 | end 46 | 47 | function OperationDiv:GetResult() 48 | if self.numberA and self.numberB then 49 | return self.numberA / self.numberB; 50 | else 51 | return "error" 52 | end 53 | end 54 | 55 | function OperationFactory:CreateOperation(oper) 56 | if oper == "+" then 57 | return OperationAdd:new() 58 | elseif oper == "-" then 59 | return OperationSub:new() 60 | elseif oper == "*" then 61 | return OperationMul:new() 62 | elseif oper == "/" then 63 | return OperationDiv:new() 64 | else 65 | end 66 | end 67 | 68 | Oper1 = OperationFactory:CreateOperation("+") 69 | Oper1.numberA = 10 70 | Oper1.numberB = 5 71 | print(Oper1:GetResult()) 72 | 73 | Oper2 = OperationFactory:CreateOperation("-") 74 | Oper2.numberA = 10 75 | Oper2.numberB = 5 76 | print(Oper2:GetResult()) 77 | 78 | Oper3 = OperationFactory:CreateOperation("*") 79 | Oper3.numberA = 10 80 | Oper3.numberB = 5 81 | print(Oper3:GetResult()) 82 | 83 | Oper4 = OperationFactory:CreateOperation("/") 84 | Oper4.numberA = 10 85 | Oper4.numberB = 5 86 | print(Oper4:GetResult()) -------------------------------------------------------------------------------- /mediator.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Colleage 抽象同事类。 3 | ConcreteColleage 是具体同事类,每个具体同事只知道自己的行为,而不了解其他同事类 4 | 的情况,但它们却都认识中介者对象。 5 | 4. Mediator 是抽象中介者,定义了同事对象到中介者对象的接口。 6 | 5. ConcreteMediator 是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类, 7 | 并从具体同事接受消息,向具体同事对象发出命令。 8 | 6. 9 | 7. 优点是: 10 | 8. 各个 Colleague 减少了耦合。 11 | 9. 12 | 10. 缺点是: 13 | 11. 由于 Mediator 控制了集中化,于是就把 Colleague 之间的交互复杂性变为了中介者的 14 | 复杂性,也就是中介者会变的比任何一个 Colleague 都复杂。 15 | ]] 16 | 17 | 18 | Mediator = {} 19 | 20 | function Mediator:new(o) 21 | o = o or {} 22 | setmetatable(o, self) 23 | self.__index = self 24 | o.colleagues = {} 25 | return o 26 | end 27 | 28 | function Mediator:Send(c,message) 29 | for _,v in pairs(self.colleagues) do 30 | if v ~= c then 31 | v:GetMessage(message) 32 | end 33 | end 34 | end 35 | 36 | ConcreteMediator = Mediator:new() 37 | 38 | Colleague = {} 39 | 40 | function Colleague:new(n,m,o) 41 | o = o or {} 42 | setmetatable(o,self) 43 | self.__index = self 44 | o.mediator = m 45 | o.name = n 46 | return o 47 | end 48 | 49 | function Colleague:Send(message) 50 | print(self.name.."说:"..message) 51 | self.mediator:Send(self,message) 52 | end 53 | 54 | function Colleague:GetMessage(message) 55 | print(self.name.."收到:"..message) 56 | end 57 | 58 | China = Colleague:new() 59 | America = Colleague:new() 60 | Russia = Colleague:new() 61 | Japan = Colleague:new() 62 | SouthKorea = Colleague:new() 63 | NorthKorea = Colleague:new() 64 | 65 | liufang = ConcreteMediator:new() 66 | 67 | xijinping = China:new("习近萍",liufang) 68 | aobama = America:new("奥爸妈",liufang) 69 | pujing = Russia:new("普惊",liufang) 70 | anbeijinsan = Japan:new("俺被进三",liufang) 71 | piaojinhui = SouthKorea:new("扑僅慧",liufang) 72 | jinzhengen = NorthKorea:new("金正嗯",liufang) 73 | 74 | 75 | table.insert(liufang.colleagues,xijinping) 76 | table.insert(liufang.colleagues,aobama) 77 | table.insert(liufang.colleagues,pujing) 78 | table.insert(liufang.colleagues,anbeijinsan) 79 | table.insert(liufang.colleagues,piaojinhui) 80 | table.insert(liufang.colleagues,jinzhengen) 81 | 82 | xijinping:Send("为了地区安全,我方支持半岛无核化") 83 | print("---------------") 84 | jinzhengen:Send("如果我们放弃核武,我们就会被欺负") 85 | print("---------------") 86 | aobama:Send("如果朝鲜继续发展核武,我国不排除武力去核") -------------------------------------------------------------------------------- /bridge.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 桥接模式:将抽象部分与他的实现部分分离,使他们都可以独立的变化 3 | 其实桥接模式在开发应用中使用的非常广泛,甚至即使我们没有 4 | 学过桥接模式,也可能会潜意识的使用到 5 | 6 | 例如 在游戏开发中,玩家类 合成了背包,在背包类中, 7 | 又合成的物品,其实这种合成就是桥接模式中的桥。注意的是 8 | 这里是合成不是继承 9 | ]] 10 | 11 | System = {} 12 | 13 | function System:new(n) 14 | o = { } 15 | setmetatable(o, self) 16 | self.__index = self 17 | o.phonename = n 18 | return o 19 | end 20 | 21 | function System:GetSystem() 22 | if self.phonename == "Iphone5s" then 23 | return "IOS 7" 24 | elseif self.phonename == "Lumia1020" then 25 | return "WP 8" 26 | end 27 | end 28 | 29 | CPU = {} 30 | function CPU:new(n) 31 | o = {} 32 | setmetatable(o, self) 33 | self.__index = self 34 | o.phonename = n 35 | return o 36 | end 37 | 38 | function CPU:GetCPU() 39 | if self.phonename == "Iphone5s" then 40 | return "苹果 A7/M7 协处理器" 41 | elseif self.phonename == "Lumia1020" then 42 | return "高通 Adreno 225" 43 | end 44 | end 45 | 46 | Memory = {} 47 | function Memory:new(n) 48 | o = {} 49 | setmetatable(o, self) 50 | self.__index = self 51 | o.phonename = n 52 | return o 53 | end 54 | 55 | function Memory:GetMemory() 56 | if self.phonename == "Iphone5s" then 57 | return "RAM 容量:1GB " 58 | elseif self.phonename == "Lumia1020" then 59 | return "RAM 容量:2GB" 60 | end 61 | end 62 | 63 | 64 | Cellphone = {} 65 | 66 | function Cellphone:new(n,o) 67 | o = o or {} 68 | setmetatable(o,self) 69 | self.__index = self 70 | self.system = System:new(n) 71 | self.cpu = CPU:new(n) 72 | self.memory = Memory:new(n) 73 | self.phonename = n 74 | return o; 75 | end 76 | 77 | function Cellphone:ShowDetail() 78 | print(self.phonename) 79 | print(self.system:GetSystem()) 80 | print(self.cpu:GetCPU()) 81 | print(self.memory:GetMemory()) 82 | end 83 | 84 | Iphone5s = Cellphone:new() 85 | 86 | function Iphone5s:Description() 87 | print("就三个字,'土豪金'") 88 | end 89 | 90 | Lumia1020 = Cellphone:new() 91 | 92 | function Lumia1020:Description() 93 | print("最好的相机手机,诺基亚,质量的保证") 94 | end 95 | 96 | phone = Iphone5s:new("Iphone5s") 97 | phone:Description() 98 | phone:ShowDetail() 99 | 100 | phone = Lumia1020:new("Lumia1020") 101 | phone:Description() 102 | phone:ShowDetail() -------------------------------------------------------------------------------- /observer.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 2. 抽象主题(Subject)角色:主题角色把所有对观察考对象的引用保存在一个聚集里, 3 | 3. 每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对 4 | 4. 象,主题角色又叫做抽象被观察者(Observable)角色,一般用一个抽象类或者一个接口 5 | 5. 实现。 6 | 6. 抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通 7 | 7. 知时更新自己。这个接口叫做更新接口。抽象观察者角色一般用一个抽象类或者一个接口 8 | 8. 实现。在这个示意性的实现中,更新接口只包含一个方法(即 Update()方法),这个方法 9 | 9. 叫做更新方法。 10 | 11 | 具体主题(ConcreteSubject)角色:将有关状态存入具体现察者对象;在具体主题 12 | 11. 的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者 13 | 12. 角色(Concrete Observable)。具体主题角色通常用一个具体子类实现。 14 | 13. 具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体现察者 15 | 14. 角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如 16 | 15. 果需要,具体现察者角色可以保存一个指向具体主题对象的引用。具体观察者角色通常用 17 | 16. 一个具体子类实现。 18 | 17. ]]-- 19 | 20 | Subject = {} 21 | 22 | function Subject:new(o) 23 | o = o or {} 24 | setmetatable(o,self) 25 | self.__index = self 26 | return o 27 | end 28 | 29 | ConcreteSubject = Subject:new() 30 | 31 | function ConcreteSubject:Attach(theconcreteobserver) 32 | if self.observers == nil then 33 | self.observers = {} 34 | end 35 | table.insert(self.observers,theconcreteobserver) 36 | end 37 | 38 | function ConcreteSubject:Detach(theconcreteobserver) 39 | for k, v in pairs(self.observers) do 40 | if v == theconcreteobserver then 41 | table.remove(self.observers,k) 42 | break 43 | end 44 | end 45 | end 46 | 47 | function ConcreteSubject:Notify() 48 | for _, v in pairs(self.observers) do 49 | v:Update() 50 | end 51 | end 52 | 53 | Observer = {} 54 | 55 | function Observer:new(o) 56 | o = o or {} 57 | setmetatable(o,self) 58 | self.__index = self 59 | return o 60 | end 61 | 62 | ConcreteObserver = Observer:new() 63 | 64 | function ConcreteObserver:new(s,n) 65 | o = {} 66 | setmetatable(o,self) 67 | self.__index = self 68 | o.subject = s 69 | o.observername = n 70 | return o 71 | end 72 | 73 | function ConcreteObserver:Update() 74 | print("陈冠稀大喊:"..self.observername.."!!"..self.subject.subjectstate) 75 | end 76 | 77 | s = ConcreteSubject:new() 78 | 79 | s:Attach(ConcreteObserver:new(s,"张伯芝")) 80 | zhongxintong = ConcreteObserver:new(s,"钟欣同") 81 | chenwenyuan = ConcreteObserver:new(s,"陈文援") 82 | 83 | s:Attach(zhongxintong) 84 | s:Attach(chenwenyuan) 85 | s.subjectstate = "谢霆疯来了,快躲起来!!" 86 | s:Notify() 87 | s:Detach(zhongxintong) 88 | s:Detach(chenwenyuan) 89 | s.subjectstate = "谢霆疯走了,快回家!!" 90 | s:Notify() 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /flyweight.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 2. 设计模式中的享元模式,避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一 3 | 个类(元类). 4 | 3. 它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合 5 | 用于当大量物件只是重复因而导致无法令人接受的使用大量内存。 6 | 4. 抽象享元(Flyweight)角色:此角色是所有的具体享元类的超类,为这些类规定出需要实现 7 | 的公共接口。那些需要外蕴状态(External State)的操作可以通过调用商业方法以参数形式传入。 8 | 5. 9 | 6. 具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定的接口。如果有内蕴状态的 10 | 话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得 11 | 享元对象可以在系统内共享的。 12 | 7. 13 | 8. 享元工厂(FlyweightFactory)角色:本角色负责创建和管理享元角色。本角色必须保证享 14 | 元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中 15 | 是否已经有一个复合要求的享元对象。如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如 16 | 果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个合适的享元对象。 17 | 9. 18 | 10. ]] 19 | 20 | FlyweightFactory = {} 21 | 22 | function FlyweightFactory:new(o) 23 | o = o or {} 24 | setmetatable(o,self) 25 | self.__index = self 26 | o.flyweight = {} 27 | o.flyweight["male"] = ConcreteFlyweight1:new() 28 | o.flyweight["female"] = ConcreteFlyweight2:new() 29 | return o; 30 | end 31 | 32 | function FlyweightFactory:GetFlyweight(key) 33 | if key ~= nil then 34 | return self.flyweight[key] 35 | end 36 | end 37 | 38 | Flyweight = {} 39 | 40 | function Flyweight:new(o) 41 | o = o or {} 42 | setmetatable(o,self) 43 | self.__index = self 44 | return o 45 | end 46 | 47 | function Flyweight:Operation() 48 | print("base operation") 49 | end 50 | 51 | function Flyweight:SetName(n) 52 | self.name = n 53 | return self 54 | end 55 | 56 | ConcreteFlyweight1 = Flyweight:new() 57 | 58 | function ConcreteFlyweight1:Operation(state) 59 | print(self.name.." 追求 "..state.name) 60 | end 61 | 62 | ConcreteFlyweight2 = Flyweight:new() 63 | 64 | function ConcreteFlyweight2:Operation(state) 65 | print(self.name.." 喜欢 "..state.name) 66 | end 67 | 68 | UnsharedConcreteFlyweight = Flyweight:new() 69 | function UnsharedConcreteFlyweight:Operation(state) 70 | --这里是不需要共享的操作 71 | print(state) 72 | end 73 | 74 | print("月老牵红线......") 75 | 76 | f = FlyweightFactory:new() 77 | xietingfeng = f:GetFlyweight("male"):SetName("谢霆疯") 78 | zhangbozhi = f:GetFlyweight("female"):SetName("张伯芝") 79 | xietingfeng:Operation(zhangbozhi) 80 | zhangbozhi:Operation(xietingfeng) 81 | 82 | zhubajie = f:GetFlyweight("male"):SetName("猪八戒") 83 | change = f:GetFlyweight("female"):SetName("嫦娥") 84 | zhubajie:Operation(change) 85 | change:Operation(zhubajie) 86 | 87 | xietingfeng = UnsharedConcreteFlyweight:new() 88 | xietingfeng:Operation("谢霆疯:我后悔了") 89 | 90 | zhubajie = UnsharedConcreteFlyweight:new() 91 | zhubajie:Operation("猪八戒:感谢月老") -------------------------------------------------------------------------------- /factoryMethod.lua: -------------------------------------------------------------------------------- 1 | Factory = {} 2 | Operation = {} 3 | 4 | function Factory:new(o) 5 | o = o or {} 6 | setmetatable(o, self) 7 | self.__index = self 8 | return o 9 | end 10 | 11 | function Operation:new(o) 12 | o = o or {} 13 | setmetatable(o,self) 14 | self.__index = self 15 | return o 16 | end 17 | 18 | OperationAdd = Operation:new() 19 | 20 | function OperationAdd:GetResult() 21 | if self.numberA and self.numberB then 22 | return self.numberA + self.numberB 23 | else 24 | return "error" 25 | end 26 | end 27 | 28 | FactoryAdd = Factory:new() 29 | 30 | function FactoryAdd:CreateOperation() 31 | return OperationAdd:new() 32 | end 33 | 34 | OperationSub = Operation:new() 35 | 36 | function OperationSub:GetResult() 37 | if self.numberA and self.numberB then 38 | return self.numberA - self.numberB 39 | else 40 | return "error" 41 | end 42 | end 43 | 44 | FactorySub = Factory:new() 45 | 46 | function FactorySub:CreateOperation() 47 | return OperationSub:new() 48 | end 49 | 50 | OperationMul = Operation:new() 51 | 52 | function OperationMul:GetResult() 53 | if self.numberA and self.numberB then 54 | return self.numberA * self.numberB 55 | else 56 | return "error" 57 | end 58 | end 59 | 60 | FactoryMul = Factory:new() 61 | 62 | function FactoryMul:CreateOperation() 63 | return OperationMul:new() 64 | end 65 | 66 | OperationDiv = Operation:new() 67 | 68 | function OperationDiv:GetResult() 69 | if self.numberA and self.numberB then 70 | return self.numberA / self.numberB 71 | else 72 | return "error" 73 | end 74 | end 75 | 76 | FactoryDiv = Factory:new() 77 | 78 | function FactoryDiv:CreateOperation() 79 | return OperationDiv:new() 80 | end 81 | 82 | 83 | operAddFactory = FactoryAdd:new() 84 | operAdd = operAddFactory:CreateOperation() 85 | operAdd.numberA = 10 86 | operAdd.numberB = 5 87 | print(operAdd:GetResult()) 88 | 89 | operSubFactory = FactorySub:new() 90 | operSub = operSubFactory:CreateOperation() 91 | operSub.numberA = 10 92 | operSub.numberB = 5 93 | print(operSub:GetResult()) 94 | 95 | operMulFactory = FactoryMul:new() 96 | operMul = operMulFactory:CreateOperation() 97 | operMul.numberA = 10 98 | operMul.numberB = 5 99 | print(operMul:GetResult()) 100 | 101 | operDivFactory = FactoryDiv:new() 102 | operDiv = operDivFactory:CreateOperation() 103 | operDiv.numberA = 10 104 | operDiv.numberB = 5 105 | print(operDiv:GetResult()) 106 | -------------------------------------------------------------------------------- /memento.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 2. 优点: 3 | 3. 1、有时一些发起人对象的内部信息必须保存在发起人对象以外的地方,但是必须要由发起 4 | 人对象自己读取,这时,使用备忘录模式可以把复杂的发起人内部信息对其他的对象屏蔽起来,从而可以 5 | 恰当地保持封装的边界。 6 | 4. 2、本模式简化了发起人类。发起人不再需要管理和保存其内部状态的一个个版本,客户端 7 | 可以自行管理他们所需要的这些状态的版本。 8 | 5. 3、当发起人角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起 9 | 来的备忘录将状态复原。 10 | 6. 11 | 7. 缺点: 12 | 8. 1、如果发起人角色的状态需要完整地存储到备忘录对象中,那么在资源消耗上面备忘录对 13 | 象会很昂贵。 14 | 9. 2、当负责人角色将一个备忘录 存储起来的时候,负责人可能并不知道这个状态会占用多大 15 | 的存储空间,从而无法提醒用户一个操作是否很昂贵。 16 | 10. 3、当发起人角色的状态改变的时候,有可能这个协议无效。如果状态改变的成功率不高的 17 | 话,不如采取“假如”协议模式。 18 | 11. 19 | 12. ]]-- 20 | 21 | Originator = {} 22 | 23 | function Originator:new(o) 24 | o = o or {} 25 | setmetatable(o,self) 26 | self.__index = self 27 | o.state = {} 28 | return o; 29 | end 30 | 31 | function Originator:SetState(k,s) 32 | if self.state == nil then 33 | self.state = {} 34 | end 35 | self.state[k] = s 36 | end 37 | 38 | function Originator:ShowState() 39 | for _, v in pairs(self.state) do 40 | print(v) 41 | end 42 | end 43 | 44 | function table_copy_table(ori_tab) 45 | if (type(ori_tab) ~= "table") then 46 | return nil 47 | end 48 | local new_tab = {} 49 | for i,v in pairs(ori_tab) do 50 | local vtyp = type(v) 51 | if (vtyp == "table") then 52 | new_tab[i] = table_copy_table(v) 53 | else 54 | new_tab[i] = v 55 | end 56 | end 57 | return new_tab 58 | end 59 | 60 | function Originator:CreateMemento() 61 | o = Memento:new() 62 | o.state = table_copy_table(self.state) 63 | return o 64 | end 65 | 66 | function Originator:SetMemento(o) 67 | self.state = o.state 68 | end 69 | 70 | Memento = {} 71 | function Memento:new(o) 72 | o = o or {} 73 | setmetatable(o,self) 74 | self.__index = self 75 | return o; 76 | end 77 | 78 | Caretaker = {} 79 | function Caretaker:new(o) 80 | o = o or {} 81 | setmetatable(o,self) 82 | self.__index = self 83 | o.memento = nil 84 | return o; 85 | end 86 | 87 | print("陈冠稀 和 张伯芝激战前") 88 | originator = Originator:new() 89 | originator:SetState("clothes","衣衫整齐") 90 | originator:SetState("face","春光满面") 91 | originator:SetState("hair","头发飘飞") 92 | originator:ShowState() 93 | caretaker = Caretaker:new() 94 | caretaker.memento = originator:CreateMemento() 95 | 96 | print("高潮中......") 97 | originator:SetState("clothes","衣衫褴褛") 98 | originator:SetState("face","累容满面") 99 | originator:SetState("hair","头发凌乱") 100 | originator:ShowState() 101 | 102 | print("激战后......") 103 | originator:SetMemento(caretaker.memento) 104 | originator:ShowState() 105 | 106 | print("张伯芝回家") -------------------------------------------------------------------------------- /state.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 2. 状态模式(State Pattern)是设计模式的一种,属于行为模式。 3 | 3. 适用场景: 4 | 4. 1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。 5 | 5. 2.一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。 6 | 6. 7 | 7. ]] 8 | 9 | Work = {} 10 | 11 | function Work:new(o,s) 12 | o = o or {} 13 | setmetatable(o, self) 14 | self.__index = self 15 | o.hour = 0 16 | o.currentstate = s 17 | return o 18 | end 19 | 20 | function Work:SetTime(h) 21 | self.hour = h 22 | end 23 | 24 | function Work:GetTime() 25 | return self.hour 26 | end 27 | 28 | function Work:SetState(s) 29 | self.currentstate = s 30 | end 31 | 32 | function Work:WriteProgram() 33 | self.currentstate:WriteProgram(self) 34 | end 35 | 36 | State = {} 37 | 38 | function State:new(o) 39 | o = o or {} 40 | setmetatable(o,self) 41 | self.__index = self 42 | return o; 43 | end 44 | 45 | MorningState = State:new() 46 | 47 | function MorningState:WriteProgram(w) 48 | if w.hour < 12 and w.hour >= 9 then 49 | print("早上写代码,精神百倍") 50 | else 51 | w:SetState(NoonState:new()) 52 | w:WriteProgram() 53 | end 54 | end 55 | 56 | NoonState = State:new() 57 | 58 | function NoonState:WriteProgram(w) 59 | if w.hour < 14 and w.hour >= 12 then 60 | print("中午写代码,犯困了,先小睡一下再说") 61 | else 62 | w:SetState(AfternoonState:new()) 63 | w:WriteProgram() 64 | end 65 | end 66 | 67 | AfternoonState = State:new() 68 | 69 | function AfternoonState:WriteProgram(w) 70 | if w.hour < 17 and w.hour >= 14 then 71 | print("下午写代码, 精神充足") 72 | else 73 | w:SetState(EveningState:new()) 74 | w:WriteProgram() 75 | end 76 | end 77 | 78 | EveningState = State:new() 79 | function EveningState:WriteProgram(w) 80 | if w.hour < 20 and w.hour >=17 then 81 | print("傍晚写代码,有点累,但还是继续") 82 | else 83 | w:SetState(NightState:new()) 84 | w:WriteProgram() 85 | end 86 | end 87 | 88 | NightState = State:new() 89 | 90 | 91 | function NightState:WriteProgram(w) 92 | if w.hour < 22 and w.hour >= 20 then 93 | print("晚上写代码,苦逼啊") 94 | else 95 | w:SetState(MidnightState:new()) 96 | w:WriteProgram() 97 | end 98 | end 99 | 100 | 101 | MidnightState = State:new() 102 | 103 | function MidnightState:WriteProgram(w) 104 | if w.hour < 9 or w.hour >= 22 then 105 | print("深夜写代码,尼玛,先睡醒了再说") 106 | else 107 | w:SetState(MorningState:new()) 108 | w:WriteProgram() 109 | end 110 | end 111 | 112 | w = Work:new(nil,MorningState:new()) 113 | w:SetTime(21) 114 | w:WriteProgram() 115 | 116 | w:SetTime(18) 117 | w:WriteProgram() 118 | 119 | w:SetTime(10) 120 | w:WriteProgram() 121 | 122 | w:SetTime(13) 123 | w:WriteProgram() 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /visitor.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 2. 1.Visitor 抽象访问者角色,为该对象结构中具体元素角色声明一个访问操作接口。该操 3 | 作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角 4 | 色的特定接口直接访问它。 5 | 3. 2.ConcreteVisitor.具体访问者角色,实现 Visitor 声明的接口。 6 | 4. 3.Element 定义一个接受访问操作(accept()),它以一个访问者(Visitor)作为参数。 7 | 5. 4.ConcreteElement 具体元素,实现了抽象元素(Element)所定义的接受操作接口。 8 | 6. 5.ObjectStructure 结构对象角色,这是使用访问者模式必备的角色。它具备以下特性: 9 | 能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对 10 | 象或者一个聚集(如一个列表或无序集合)。 11 | 7. 访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增 12 | 加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。 13 | 8. ]] 14 | 15 | Visitor = {} 16 | 17 | function Visitor:new(n,o) 18 | o = o or {} 19 | setmetatable(o,self) 20 | self.__index = self 21 | self.name = n 22 | return o; 23 | end 24 | 25 | ConcreteVisitor1 = Visitor:new() 26 | 27 | function ConcreteVisitor1:VisitConcreteElementA(c) 28 | print(c.name.." 被 "..self.name.."访问") 29 | end 30 | 31 | function ConcreteVisitor1:VisitConcreteElementB(c) 32 | print(c.name.." 被 "..self.name.."访问") 33 | end 34 | 35 | ConcreteVisitor2 = Visitor:new() 36 | 37 | function ConcreteVisitor2:VisitConcreteElementA(c) 38 | print(c.name.." 被 "..self.name.."访问") 39 | end 40 | 41 | function ConcreteVisitor2:VisitConcreteElementB(c) 42 | print(c.name.." 被 "..self.name.."访问") 43 | end 44 | 45 | Element = {} 46 | 47 | function Element:new(n,o) 48 | o = o or {} 49 | setmetatable(o,self) 50 | self.__index = self 51 | self.name = n 52 | return o; 53 | end 54 | 55 | ConcreteElementA = Element:new() 56 | 57 | function ConcreteElementA:Accept(v) 58 | v:VisitConcreteElementA(self) 59 | end 60 | 61 | ConcreteElementB = Element:new() 62 | 63 | function ConcreteElementB:Accept(v) 64 | v:VisitConcreteElementB(self) 65 | end 66 | 67 | ObjectStructure = {} 68 | 69 | function ObjectStructure:new(o) 70 | o = o or {} 71 | setmetatable(o,self) 72 | self.__index = self 73 | o.elements = {} 74 | return o 75 | end 76 | 77 | function ObjectStructure:Attach(e) 78 | table.insert(self.elements,e) 79 | end 80 | 81 | function ObjectStructure:Detach(e) 82 | for k, v in pairs(self.elements) do 83 | if v == theconcreteobserver then 84 | table.remove(self.elements,k) 85 | break 86 | end 87 | end 88 | end 89 | 90 | function ObjectStructure:Accept(v) 91 | for _,e in ipairs(self.elements) do 92 | e:Accept(v) 93 | end 94 | end 95 | 96 | obj = ObjectStructure:new() 97 | obj:Attach(ConcreteElementA:new("XX 博物馆")) 98 | obj:Attach(ConcreteElementB:new("XX 动物园")) 99 | 100 | xiaoming = ConcreteVisitor1:new("小明") 101 | xiaohong = ConcreteVisitor2:new("小红") 102 | 103 | obj:Accept(xiaoming) 104 | obj:Accept(xiaohong) -------------------------------------------------------------------------------- /abstractFactory.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 工厂方法模式: 3 | 一个抽象产品类,可以派生出多个具体产品类 4 | 一个抽象工厂类,可以派生出多个具体工厂类 5 | 每个具体工厂类只能创建一个具体产品类的实例 6 | 7 | 抽象工厂模式: 8 | 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类 9 | 一个抽象工厂类,可以派生出多个具体工厂类 10 | 每个具体工厂类可以创建多个具体产品类的实例 11 | 12 | 简单工厂:一个工厂生产所有部件 13 | 工厂方法:一个工厂生产一种部件 14 | 抽象工厂:一个工厂生产几种部件 15 | 16 | ]] 17 | 18 | IUser = {} 19 | 20 | function IUser:new(o) 21 | o = o or {} 22 | setmetatable(o, self) 23 | self.__index = self 24 | return o 25 | end 26 | 27 | SqlServerUser = IUser:new() 28 | 29 | function SqlServerUser:Insert() 30 | print("在 SQL Server 中给USer表增加一条记录") 31 | end 32 | 33 | function SqlServerUser:GetUserRecord() 34 | print("在 SQL Server 中User表获取一条记录") 35 | end 36 | 37 | AccessUser = IUser:new() 38 | 39 | function AccessUser:Insert() 40 | print("在Access中给User表增加一条记录") 41 | end 42 | 43 | function AccessUser:GetUserRecord() 44 | print("在Access中User表获取一条记录") 45 | end 46 | 47 | IDepartment = {} 48 | 49 | function IDepartment:new(o) 50 | o = o or {} 51 | setmetatable(o, self) 52 | self.__index = self 53 | return o 54 | end 55 | 56 | SqlServerDepartment = IDepartment:new() 57 | 58 | function SqlServerDepartment:Insert() 59 | print("在 SQL Server 中给Department表增加一条记录") 60 | end 61 | 62 | function SqlServerDepartment:GetDepartmentRecord() 63 | print("在 SQL Server中Department表获取一条记录") 64 | end 65 | 66 | AccessDepartment = IDepartment:new() 67 | 68 | function AccessDepartment:Insert() 69 | print("在 Access 中给Department表增加一条记录") 70 | end 71 | 72 | function AccessDepartment:GetDepartmentRecord() 73 | print("在 Access 中Department表获取一条记录") 74 | end 75 | 76 | IFactory = {} 77 | 78 | function IFactory:new(o) 79 | o = o or {} 80 | setmetatable(o, self) 81 | self.__index = self 82 | return o 83 | end 84 | 85 | SqlFactory = IFactory:new() 86 | 87 | function SqlFactory:GetUser() 88 | return SqlServerUser:new() 89 | end 90 | 91 | function SqlFactory:GetDepartment() 92 | return SqlServerDepartment:new() 93 | end 94 | 95 | AccessFactory = IFactory:new() 96 | 97 | function AccessFactory:GetUser() 98 | return AccessUser:new() 99 | end 100 | 101 | function AccessFactory:GetDepartment() 102 | return AccessDepartment:new() 103 | end 104 | 105 | choice = io.read() 106 | factory = nil 107 | if choice == "s" then 108 | factory = SqlFactory:new() 109 | elseif choice == "a" then 110 | factory = AccessFactory:new() 111 | end 112 | 113 | factory = SqlFactory:new() 114 | 115 | if factory ~= nil then 116 | user = factory:GetUser() 117 | department = factory:GetDepartment() 118 | 119 | user:Insert() 120 | user:GetUserRecord() 121 | 122 | department:Insert() 123 | department:GetDepartmentRecord() 124 | end -------------------------------------------------------------------------------- /interpreter.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 2. 解释器模式(Interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释 3 | 器,用这个解释器使用该表示来解释语言中句子。 4 | 3. 解释器模式需要解决的是,如果一种特定类型的问题发生的频率足够高,那么可能就值得将 5 | 该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句 6 | 子来解决该问题。 7 | 4. AbstractExpression 抽象解释器:具体的解释任务由各个实现类完成,具体的解释器分别 8 | 由 TerminalExpression 和 NonterminalExpression 完成。 9 | 5. 10 | 6. TerminalExpression 终结符表达式:实现与文法中的元素相关联的解释操作,通常一个解 11 | 释器模式中只有一个终结符表达式,但有多个实例,对应不同的终结符。具体到我们例子就是 12 | VarExpression 类,表达式中的每个终结符都在堆栈中产生了一个 VarExpression 对象。 13 | 7. 14 | 8. NonterminalExpression 非终结符表达式:文法中的每条规则对应于一个非终结表达式, 15 | 具体到我们的例子就是加减法规则分别对应到 AddExpression 和 SubExpression 两个类。非终结符表达 16 | 式根据逻辑的复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。 17 | 9. 18 | 10. Context 环境角色:包含解释之外的一些全局信息。 19 | 11. 20 | 12. ]]-- 21 | 22 | Context = {} 23 | 24 | function Context:Sort(e) 25 | local index = 1 26 | local last = 1 27 | local sub = "" 28 | local num = 1 29 | local top = 1 30 | local stack = {} 31 | while 1 do 32 | last = string.find(e," ",index) 33 | if last == nil or last <= 0 then 34 | break 35 | end 36 | sub = string.sub(e,index,last) 37 | num = tonumber(sub) 38 | if num == nil then 39 | stack[top] = sub 40 | else 41 | stack[top] = num 42 | end 43 | top = top + 1 44 | index = last + 1 45 | end 46 | --table.foreach(stack,print) 47 | return stack 48 | end 49 | 50 | function Context:new(e,o) 51 | o = o or {} 52 | setmetatable(o,self) 53 | self.__index = self 54 | o.stack = {} 55 | o.top = 1 --顶指针 56 | o.expression = self:Sort(e) 57 | return o 58 | end 59 | 60 | function Context:Calculate() 61 | self.top = 1 62 | local i = 1 63 | while 1 do 64 | if i >= #self.expression then 65 | break 66 | end 67 | if string.find(self.expression[i],"+") then 68 | self.stack[self.top - 1] = AddExpression:new(self.stack[self.top],VarExpression:new(self.expression[i + 1])) 69 | i = i + 2 70 | elseif string.find(self.expression[i],"-") then 71 | self.stack[self.top - 1] = SubExpression:new(self.stack[self.top],VarExpression:new(self.expression[i + 1])) 72 | i = i + 2 73 | else 74 | self.stack[self.top] = VarExpression:new(self.expression[i]) 75 | i = i + 1 76 | self.top = self.top + 1 77 | end 78 | end 79 | 80 | for i = 1,self.top - 1,1 do 81 | print(self.stack[i]:Interpret()) 82 | end 83 | end 84 | 85 | AbstractExpression = {} 86 | 87 | function AbstractExpression:new(o) 88 | o = o or {} 89 | setmetatable(o,self) 90 | self.__index = self 91 | return o 92 | end 93 | 94 | TerminalExpression = AbstractExpression:new() 95 | 96 | function TerminalExpression:new(v,o) 97 | o = o or {} 98 | setmetatable(o,self) 99 | self.__index = self 100 | o.val = v 101 | return o 102 | end 103 | 104 | function TerminalExpression:Interpret() 105 | return self.val 106 | end 107 | 108 | VarExpression = TerminalExpression:new() 109 | 110 | NonterminalExpression = AbstractExpression:new() 111 | 112 | function NonterminalExpression:new(l,r,o) 113 | o = o or {} 114 | setmetatable(o,self) 115 | self.__index = self 116 | o.left = l 117 | o.right = r 118 | return o 119 | end 120 | 121 | AddExpression = NonterminalExpression:new() 122 | 123 | function AddExpression:Interpret(c) 124 | return self.left:Interpret() + self.right:Interpret() 125 | end 126 | 127 | SubExpression = NonterminalExpression:new() 128 | 129 | function SubExpression:Interpret(c) 130 | return self.left:Interpret() - self.right:Interpret() 131 | end 132 | 133 | 134 | c = Context:new("1+9-3+5") 135 | c:Calculate() --------------------------------------------------------------------------------