使用装饰器模式来扩展一个日志记录器:interface LoggerInterface { public function log($message);}class FileLogger implements...然后我们使用 TimeStampLogger 对象来扩展 FileLogger 的功能,并将其存储在 $logger 变量中。...接着,我们使用 LogLevelLogger 对象来进一步扩展 $logger 的功能,并将其存储在 $logger 变量中。最后,我们调用 $logger 的 log 方法来执行装饰后的操作。...在这里,我们可以看到我们成功地使用装饰器模式来扩展了 FileLogger 的功能。...使用 TimeStampLogger 和 LogLevelLogger 装饰器类,我们可以将消息的时间戳和日志级别添加到日志消息前面,以增强日志记录器的功能。
设计模式(Design Pattern)是一套被反复使用、多数人知晓、分类编目、代码设计经验的总结。使用设计模式是为了提高代码的可复用性、可扩充性可维护性,让代码易于被他人理解且保证软件的可靠性。...毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编写真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。...设计模式这个术语是由Erich Gamma等人在20世纪90年代从建筑设计领域引入的,它是对软件设计领域普遍存在的各种问题所提出的解决方案,不涉及完成应用程序的具体的类或对象。...设计模式是前人实践经验的结晶,可以帮助我们优化程序设计。...设计模式的学习是一个艰苦漫长的过程,需要大量的实践、思考和总结,即便如此,我们首先要有这个学习的意识。
定义 在状态模式(State Pattern):允许一个对象在其内部状态改变时,改变它的行为。 适用场景 一个对象存在多个状态,不同状态下的行为会有不同,而且状态之间可以相互转换。...如果我们通过if else来判断对象的状态,那么代码中会包含大量与对象状态有关的条件语句,而且在添加,删除和更改这些状态的时候回比较麻烦;而如果使用状态模式。...将状态对象分散到不同的类中,则可以消除 if...else等条件选择语句。 现在我们清楚了状态模式的适用场景,下面看一下状态模式的成员和类图。...如果我们不使用状态模式,在切换状态的时候可能会写不少if-else判断,而且随着状态的增多,这些分支会变得更多,难以维护。...从上面的例子可以看出,使用状态模式不需要去写if-else,而且如果今后想添加一个状态,只需要再创建一个状态子类,并在新的状态子类添加好对所有状态的处理,并在之前的状态子类中添加上对新状态的处理即可。
定义 命令模式(Command Pattern):命令(或请求)被封装成对象。客户端将命令(或请求)对象先传递给调用对象。...由定义可以看出,在命令模式中,命令被封装成了对象,而发送命令的客户端与处理命令的接收者中间被调用对象隔开了,这种设计的原因或者适用的场景是什么样的呢?...使用调用者在客户端和请求处理者之间来做一个“拦截”,方便对请求对象做控制和管理。...命令模式类图 代码示例 场景概述 模拟一个使用遥控器开灯和关灯的例子。 场景分析 在这个例子中,使用遥控器的人就是客户端,TA发起开启或关闭灯的命令给遥控器(调用者)。...iOS SDK 和 JDK中的应用 在JDK中,java.lang.Runnable是使用命令模式的经典场景,Runnable接口可以作为抽象的命令,而实现了Runnable的线程即是具体的命令。
定义 外观模式(Facade Pattern):外观模式定义了一个高层接口,为子系统中的一组接口提供一个统一的接口。外观模式又称为门面模式,它是一种结构型设计模式模式。...适用场景 子系统随着业务复杂度的提升而变得越来越复杂,客户端需要某些子系统共同协作来完成某个任务。 在多层结构的系统中,使用外观对象可以作为每层的入口来简化层间的调用。...因此,这些设备可以看做是该智能家居系统的子系统;而这个遥控器则扮演的是外观类的角色。 下面我们用代码来看一下如何实现这些设计。...代码对应的类图 外观模式代码示例类图 从上面的UML类图中可以看出,该示例的子系统之间的耦合还是比较多的;而外观类HomeDeviceManager的接口大大简化了User对这些子系统的使用成本。...优点 实现了客户端与子系统间的解耦:客户端无需知道子系统的接口,简化了客户端调用子系统的调用过程,使得子系统使用起来更加容易。同时便于子系统的扩展和维护。
定义 代理模式(Proxy Pattern) :为某个对象提供一个代理,并由这个代理对象控制对原对象的访问。...定义解读:使用代理模式以后,客户端直接访问代理,代理在客户端和目标对象之间起到中介的作用。...而且中介还需要在真正交易前做其他的事情(收取中介费,帮买房者check房源的真实性等等),因此该场景比较适合使用代理模式。...代码对应的类图 代理模式代码示例类图 从UML类图中我们可以看出,在这里没有使用抽象主题对象,而是用一个接口来分别让中介和房东实现。...虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。 保护代理可以控制客户端对真实对象的使用权限。
其实我们可以定义一些独立的类来封装不同的解决方案,每一个类封装一个具体的方案,这些不同的方案就是我们所说的策略。而且我们可以用一个抽象的策略类来保证这些策略的一致性,这就是策略模式的设计方案。...成员与类图 成员 策略模式除了客户端之外共有三个成员: 环境类(Context):环境类内部持有一个具体策略类的实例,这个实例就是当前的策略,可以供客户端使用 抽象策略类(Strategy):抽象策略类声明具体策略类需要实现的接口...场景分析 在该场景中,传入的两个整数参数是不变的,但是对于这两个整数的具体操作可以灵活切换,那么我们可以使用策略模式:将每个操作(算法)封装起来,在需要替换的时候将Context类持有的具体策略实例更新即可...策略模式代码示例类图 优点 策略模式遵循开闭原则,用户可以在不修改原有系统的前提下选择和更换算法 避免使用多重条件判断 可以灵活地增加新的算法或行为 提高算法和策略的安全性:可以封装策略的具体实现,调用者只需要知道不同策略之间的区别就可以...iOS SDK 和 JDK中的应用 JDK中的Comparator是策略模式的实现,可以使用不同的子类,也就是具体策略来解决不同的需求。
传输对象模式是什么? 传输对象模式(Transfer Object Pattern)用于从客户端向服务器一次性传递带有多个属性的数据。传输对象也被称为数值对象。...服务器端的业务类通常从数据库读取数据,然后填充 POJO,并把它发送到客户端或按值传递它。对于客户端,传输对象是只读的。客户端可以创建自己的传输对象,并把它传递给服务器,以便一次性更新数据库中的数值。...以下是这种设计模式的实体。 角色: 业务对象(Business Object):为传输对象填充数据的业务服务。...; 传输对象模式可以干嘛?...主要起来不同层级的传输对象安全隔离。 个人理解: 类似于水通过不同的渠道有不同的管道来接,有些用塑料、铁的、其他的... 传输对象模式类图 ?
上文(设计模式-状态模式):设计模式-观察者模式 ---- 背景 一般情况在编写代码的时候判断为空需要通过null==来判断,而这样的写法很难看,一眼看下去几百行代码,密密麻麻都是这些判断,代码很不优雅...这个问题,java的空对象模式很不错的解决方案,可以做到优雅判断。 空对象模式是什么?...空对象模式(Null Object Pattern)提供一个给定类型的空对象代理,这个空对象不执行任何动作,对他的合作对象隐藏细节。...缺点: 暂时没有发现 个人理解: 如果要将该空对象比较现实中的电视台,找不到的电视台类似空对象,而有的就是具体的,而遥控器就类似于工厂转换,用户就是我们自己。 空对象模式类图 ?...,是一个比较简单又非常实用的,但是可能是该模式比较少人提起,可以说基本是被人家忘记了,也是极少人知道可能才导致的一种情况,不过空对象的思想还是很不错的。
定义 原型模式(Prototype Pattern): 使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。...下面通过类图来看一下各个成员之间的关系: 模式类图 原型模式类图 需要注意的是,这里面的clone()方法返回的是被复制出来的实例对象。...,学历对象中的信息是相同的,这时候如果需要大量生成这些毕业生的简历的话比较适合使用原型模式。...优点 可以利用原型模式简化对象的创建过程,尤其是对一些创建过程繁琐,包含对象层级比较多的对象来说,使用原型模式可以节约系统资源,提高对象生成的效率。...可以很方便得通过改变值来生成新的对象:有些对象之间的差别可能只在于某些值的不同;用原型模式可以快速复制出新的对象并手动修改值即可。
适用场景 有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。比如系统中有多于一个的产品族,而每次只使用其中某一产品族,属于同一个产品族的产品将在一起使用。...只需要知道自己需要的产品是属于哪个工厂的即可 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。...这两个接口都是获取的统一产品族的对象,比如MySql和PostgreSQL产品族,具体返回的是哪个产品族对象,取决于所连接的数据库类型。 OK,到现在三个工厂模式已经讲完了。...在继续讲解下面三个设计模式之前,先简单回顾一下上面讲解的三个工厂模式: 大体上看,简单工厂模式,工厂方法模式和抽象工厂模式的复杂程度是逐渐升高的。...简单工厂模式使用不同的入参来让同一个工厂生产出不同的产品。
定义 中介者模式(Mediator Pattern):用一个中介对象来封装一系列的对象交互,中介者使各对象之间不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。...耦合越多,修改的地方就会越多。 如果我们使用中介者对象,则可以将系统的网状结构变成以中介者为中心的星型结构。...中介者承担了中转作用和协调作用,简化了对象之间的交互,而且还可以给对象间的交互进行进一步的控制。 现在我们清楚了中介者模式的适用场景,下面看一下中介者模式的成员和类图。...因此在这种场景下,我们需要使用中介者模式,在所有人中间来做一个消息的多路转发:当A发出消息后,由中介者来发送给B和C: A sent message to Mediator ; Mediator sent...代码对应的类图 ? 中介者模式代码示例类图 优点 中介者使各对象不需要显式地相互引用,从而使其耦合松散。
继上一篇的面向对象设计的设计原则,本篇是面向对象设计系列的第二个部分:面向对象设计的设计模式。...介绍设计模式最著名的一本书莫属《设计模式 可复用面向对象软件的基础》这本书,书中共介绍了23个设计模式。而这些设计模式分为三大类,每个类别都包含几个设计模式: 创建型设计模式:侧重于对象的创建。...结构型设计模式:侧重于接口的设计和系统的结构。 行为型设计模式:侧重于类或对象的行为。 本系列对设计模式的讲解按照上面分类排列的顺序进行。...本篇是面向对象设计中面向对象设计的第一篇文章,讲解的是简单工厂模式。 注意:简单工厂模式不是 GoF总结出来的23种设计模式之一,不存在于《设计模式 可复用面向对象软件的基础》这本书中。...适用场景 如果我们希望将一些为数不多的类似的对象的创建和他们的创建细节分离开,也不需要知道对象的具体类型,可以使用简单工厂模式。
适用场景 系统有大量的相似对象,这些对象有一些外在状态。 应当在多次重复使用享元对象时才值得使用享元模式。...使用享元模式需要维护一个存储享元对象的享元池,而这需要耗费资源,因此, 成员与类图 成员 享元模式一共有三个成员: 享元工厂(FlyweightFactory): 享元工厂提供一个用于存储享元对象的享元池...模式类图 享元模式类图 代码示例 场景概述 这里我们使用《Objective-C 编程之道:iOS设计模式解析》里的第21章使用的例子:在一个页面展示数百个大小,位置不同的花的图片,然而这些花的样式只有...后面我们在用享元模式的时候可以不将内部属性暴露出来) 优点 使用享元模可以减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份,降低系统的使用内存,也可以提性能。...享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。 缺点 使用享元模式需要分离出内部状态和外部状态,这使得程序的逻辑复杂化。
定义 责任链模式(Chain of Responsibility Pattern):为请求创建了一个接收者对象的链,每个接收者都包含对另一个接收者的引用。...这时,相对于使用if-else来区分不同的条件和对应的解决策略,我们可以使用责任链模式,将不同条件和对应的解决策略封装到一个类中,即不同的处理者。...如果不使用责任链模式,我们可能会写一个do-while循环,在循环里面再根据纸币的面额在做if-else判断,不断去尝试直到将面额除尽(没有余数)。...但是如果使用责任链模式,我们将每个面值的纸币当做责任链中的一个处理者(节点,node),自成一类,单独做处理。...缺点 因为需要在责任链上传递责任,直到找到合适的对象来处理,所以可能会导致处理的延迟。因此在延迟不允许过高的场景下不适合使用责任链模式。
定义 装饰者模式(Decorator Pattern) :不改变原有对象的前提下,动态地给一个对象增加一些额外的功能。...场景分析 因为选择一个沙拉底之后,可以随意添加不同份数和种类的酱汁,也就是在原有的沙拉对象增加新的对象,所以比较适合用装饰者模式来设计:酱汁相当于装饰者,而沙拉底则是被装饰的构件。...按照装饰者设计模式类图,该类是继承于沙拉类的: //================== SauceDecorator.h ================== @interface SauceDecorator...下面我们看一下该代码实现对应的类图。 代码对应的类图 装饰者模式代码示例类图 优点 比继承更加灵活:不同于在编译期起作用的继承;装饰者模式可以在运行时扩展一个对象的功能。...用户可以根据需要增加新的装饰类,在使用时再对其进行组合,原有代码无须改变。 缺点 装饰者模式需要创建一些具体装饰类,会增加系统的复杂度。
在这种场景下,我们可以使用模板方法模式:定义好一个算法的框架,在父类实现可以复用的算法步骤,而将需要扩展和修改其他步骤的任务推迟给子类进行。...现在我们清楚了模板方法模式的适用场景,下面看一下这个模式的成员和类图。...下面通过类图来看一下命令模式各个成员之间的关系: 模式类图 ?...而第一步是相同的:准备热水。 根据上面对模板方法模式的介绍,像这样算法步骤相同,算法步骤里的实现可能相同或不同的场景我们可以使用模板方法模式。下面我们看一下如何用代码来模拟该场景。...在JDK中,java.lang.Runnable是使用JDK的经典场景:Runnable接口可以作为抽象的命令,而实现了Runnable的线程即是具体的命令。
定义解读:桥接模式的核心是两个抽象以组合的形式关联到一起,从而他们的实现就互不依赖了。 适用场景 如果一个系统存在两个独立变化的维度,而且这两个维度都需要进行扩展的时候比较适合使用桥接模式。...下面来看一下桥接模式的成员和类图。 成员与类图 成员 桥接模式一共只有三个成员: 抽象类(Abstraction):抽象类维护一个实现部分的对象的引用,并声明调用实现部分的对象的接口。...根据上面提到的桥接模式的成员: 抽象类就是图形的抽象类 扩展抽象类就是继承图形抽象类的子类:各种形状 实现类接口就是颜色接口 具体实现类就是继承颜色接口的类:各种颜色 下面我们用代码看一下该如何设计。...跟上面没有使用桥接模式的设计相比,使用桥接模式需要的类的总和是 m + n:当m或n的值很大的时候是远小于 m * n(没有使用桥接,而是使用继承的方式)的。...而且如果后面还要增加形状和颜色的话,使用桥接模式就可以很方便地将原有的形状和颜色和新的形状和颜色进行搭配了,新的类和旧的类互不干扰。
适用场景 系统只需要一个实例对象,客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。比较典型的例子是音乐播放器,日志系统类等等。...成员与类图 成员 单例模式只有一个成员,就是单例类。因为只有一个成员,所以该设计模式的类图比较简单: 模式类图 ?...单例模式类图 一般来说单例类会给外部提供一个获取单例对象的方法,内部会用静态对象的方式保存这个对象。 代码示例 场景概述 在这里我们创建一个简单的打印日至或上报日至的日至管理单例。...iOS SDK 和 JDK 中的应用 在Objective-C语言中使用单例模式的类有NSUserDefaults(key-value持久化)和UIApplication类(代表应用程序,可以处理一些点击事件等...在JDK中使用的单例模式的类有Runtime类(代表应用程序的运行环境,使应用程序能够与其运行的环境相连接);Desktop类(允许 Java 应用程序启动已在本机桌面上注册的关联应用程序) ----