设计模式小结

本文的主要内容是阅读OREILLY出版的《Head First设计模式》的笔记和Android 源码。OREILLY的《Head First设计模式》这本书非常不错,简单通透,比那些译书好了太多,如果想学习设计模式,建议购买一本。

面临的问题:

1.交互对象之间的耦合为后续的维护和扩展带来了不便
2.代码复用

OO基础:
  • 抽象
  • 封装
  • 多态
  • 继承
OO原则:
  • 将变化分离出来,封装变化
  • 多用组合(Has-a),少用继承(Is-a)
  • 针对接口编程,不针对实现编程
  • 减少交互对象之间的耦合
  • 类应该对扩展开放,对修改关闭
  • 依赖倒置原则:依赖抽象,不要依赖具体类
  • “最少知识原则”:只和密友交谈
  • 好莱坞原则:别找我,我会找你
  • 类应该只有一个改变的理由
1.策略模式(Strategy pattern)

把"行为"想成"算法"
策略模式: 定义算法族,分别封装起来,让他们之间可以相互替换(实现了共同的接口,接口变量可以指向不同的具体对象),此模式让算法的变化独立于使用算法的客户。

涉及到的OO原则:

  • 将变化分离出来,封装变化
  • 多用组合(Has-a),少用继承(Is-a)
  • 针对接口编程,不针对实现编程

策略模式 VS 代理模式
策略模式和代理模式在使用场景上很相似,都用于处理有多种实现方式或是有多种情况需要考虑的场景,而且都是抽象提取各个子类的行为。但是两者也有很多不同之处。

  • 代理模式有代理类,而策略模式没有。
  • 代理模式把对子类的选择封装在了代理类中,而且通过代理类来对外提供服务;而策略模式是通过动态注入的方式,让客户端选择需要的策略。
  • 策略模式更侧重于策略或算法的封装隔离;代理模式更侧重于通过代理类对外提供代理服务。
  • 两者的共同缺点就是,随着情况的增多,都会导致子类的增多。

[Android 源码实例]
ListView.java中的setAdapter(ListAdapter adapter)方法会为ListView的子类设置 实现了ListAdapter接口的实例对象。
比如ArrayAdapter,BaseAdapter等都继承了ListAdpater,而它们也各自有不同的实现。


2.观察者模式(Observer pattern)

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖着都会收到通知并自动更新。
观察者和可观察者之间是松耦合(没有细节的牵扯)的方式沟通状态。
观察者模式可分为 被观察者(push)和观察者(pull)两种类型。
JDK中也有观察者模式,"java.util.Observable"和"java.util.Observer"就是两个相关类。

[Android 源码实例]
观察者模式就太多了,到处都是listener;四大组件之一的,broadcast receiver也可以看做是观察者模式的一种。


3.装饰模式(Decorator pattern)

装饰者模式动态地将责任附加到对象上。
若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

运行时扩展远比编译时期继承强大, 组合(composition)和委托(delegation)是两种常用的方式。
开放-关闭原则: 类应该对扩展开放,对修改关闭。
遵循"开放-关闭"原则通常要花费更多的功夫,也会增加代码的复杂度,所以只需要在最可能改变的地方实现就可以。

装饰者模式的特点:

  • 装饰者和被装饰对象有相同的超类型。
  • 可以用一个或多个装饰者包装一个对象。
  • 既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合 ,可以用装饰过的对象代替它。
  • 装饰者可以在所委托被装饰对象的行为之前与/或之后,加上自己的行为,以达到特定的目的。
  • 对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用所需装饰者装饰对象。

装饰者模式利用继承获得 “类型匹配”,而不是利用继承获得 “行为”

装饰者模式的缺点
装饰者模式的设计常常造成大量的小类,对使用者造成困扰。

装饰模式 VS 代理模式

  • 装饰模式是以透明的方式对客户端扩展对象的功能;而代理模式是给对象提供一个代理对象,并由代理对象控制对原对象的访问。
  • 装饰模式应该为对象增加功能,代理模式应该为对象施加控制,但不对对象本身功能进行增强。

[Android 源码实例]
Android中的ContextWrapper就是装饰模式,包括了我们常用的Activity和Service。
在这里插入图片描述


4.工厂模式(Factory pattern)

4.1 简单工厂模式(Simple factory): 将创建对象的工作放到一个类中,使用者通过这个类的对象或者静态方法创建对象。
简单工厂其实不是一个设计模式,反而比较像是一种编程习惯。
[Android 源码实例]
PhoneFactory.java就是简单工厂模式,负责创建GsmCdmaPhone对象。

4.2 工厂方法模式(Factory method): 定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。
工厂方法让类把实例化推迟到了子类,通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。

简单工厂模式 VS 工厂方法模式

  • 简单工厂把全部的事情在一个地方都处理完了。
  • 工厂方法是创建了一个框架,让子类决定如何实现。

"工厂"的优点
将创建对象的代码集中在一个对象或方法中,可以避免代码的重复,而且方便以后的维护;
另外,如果使用了工厂方法,客户在实例化对象时,只会依赖接口,而不是依赖具体类。

直接初始化一个对象时,就是在依赖它的具体类。

依赖倒置原则: 要依赖抽象,不要依赖具体。这个原则说明:不能让高层组件依赖底层组件,而且不管是高层组件还是底层组件都应该依赖于抽象。遵循依赖倒置原则的方法技巧很多,工厂方法模式只是一种。

遵循"依赖倒置原则"要注意以下几点:

  • 变量不可持有具体类的引用
  • 不要让类派生自具体类
  • 不要覆盖基类中已实现的方法; 如果覆盖基类中已实现的方法,那么说明基类就不是一个真正适合被继承的抽象。基类中已实现的方法,应该由所有的子类共享。(这条太严格了)

[Android/java 源码实例]

Iterable是Factory
Iterator是product(接口)
ArrayList是concrete factory
Itr是concrete product(Android P代码)。

4.3 抽象工厂模式(Abstract factory pattern)
抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而无需明确指定具体类。

抽象工厂模式的任务是定义一个负责创建一组产品的接口,这个接口内的每个方法负责创建一个具体的产品。

当需要创建产品家族和想让制造的相关产品集合起来时,可以使用抽象工厂模式。

工厂方法模式 VS 抽象工厂模式

  • 虽然两者都负责创建对象,但工厂方法是通过继承,而抽象工厂是通过对象的组合。

[Android 源码实例]
这种模式使用比较少,没在Android源码中找到例子。


5.单例模式/单件模式 (Singleton pattern)

单件模式: 确保一个类只有一个实例,并提供一个全局访问点。

单件模式常常用来管理共享资源。
单件模式的构造器是声明为私有的。

5.1 有问题的单件模式代码(不适用多线程)

public class Singleton{
    private static Singleton uniqueInstance;
    
    private Singleton(){}
    
    public static Singleton getInstance(){
        if(uniqueInstance == null){
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

5.2 执行效率低的单件模式代码

public class Singleton{
    private static Singleton uniqueInstance;
    
    private Singleton(){}
    
    public static synchronized Singleton getInstance(){
        if(uniqueInstance == null){
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    }
}

上面代码的写法,可以排除多线程冲突的问题,两个线程不可能同时进入getInstance方法;但是只有第一次执行此方法时才真正需要同步,所以对以后的调用同步都是累赘,降低了执行效率。

5.3 "急切"的单件模式代码

public class Singleton{
    private static Singleton uniqueInstance = new Singleton();
    
    private Singleton(){}
    
    public static synchronized Singleton getInstance(){
        return uniqueInstance;
    }
}

5.4 "双重检查加锁"的单件模式代码

public class Singleton{
    private volatile static Singleton uniqueInstance;
    
    private Singleton(){}
    
    public static Singleton getInstance(){
        if(uniqueInstance == null){
            synchronized(Singleton.class){
                if(uniqueInstance == null){
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

上面这个方法可以保证执行效率。

5.5 借用类加载实现单例

Class MyMediaManager {
    private static class InstanceHolder {
        static final MyMediaManager INSTANCE = new MyMediaManager();
    }
    
    private MyMediaManager() {
    }
    
    public static MyMediaManager getInstance() {
        return InstanceHolder.INSTANCE;
    }
}

[Android 源码实例]
单例模式很常见,在OpenGrok上搜"getInstance"可以找到很多,不举例子了。


6. 命令模式(Command pattern)–封装调用

命令模式可以将 “动作的请求者”“动作的执行者” 对象中解耦。被解耦的两者之间是通过命令对象进行沟通的,命令对象封装了接受者和一个或一组动作。

命令模式 将 “请求” 封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。

[Android 源码实例]
线程池的应用,使用者调用ThreadPoolExecutor的execute方法时传入的都是Runnable类型的参数(command)。


7. 适配器模式(Adapter pattern)

适配器模式: 将一个类的接口,转换成客户期望的另一个接口。适配器模式让原本不兼容的类可以合作无间。

适配器模式充满着良好的OO设计原则:使用对象组合,以修改的接口包装被适配者;这种做法还有额外的优点,那就是,被适配者的任何子类,都可以搭着适配器使用。

适配器分为:对象适配器和类适配器。类适配器的实现需要多重继承,所以Java不适用。

对象适配器通过组合的方式将请求传递给被适配者,而类适配器通过继承被适配者和目标类

下面是两种适配器的类图对比:

  • 对象适配器
    在这里插入图片描述
  • 类适配器
    在这里插入图片描述

[Android 源码实例]
ListView中通过使用Adapter将多变的布局和数据结合起来。


8. 外观模式(Facade pattern)

外观模式 提供了一个统一的接口,用来访问子系统的一群接口。外观定义了一个高层接口,让子系统更容易使用。

外观模式不只是简化了接口,也将客户从组件的子系统中解耦。

要遵守“最少知识原则”,要只调用以下范围内的方法

  • 该对象本身
  • 被当作方法的参数而传递进来的对象
  • 此方法创建或实例化的任何对象
  • 对象的任何组件

“最少知识原则”的优点:减少了对象之间的依赖,减少了软件维护成本。
“最少知识原则”的缺点:采用这个原则会导致更多的“包装类”被制造出来,以处理和其他组件的沟通,这可能会导致复杂度和开发时间的增加,并降低程序运行时的性能。

装饰者模式 VS 适配器模式 VS 外观模式
这三个模式都有“包装类”,而且适配器模式和外观模式都有接口转换,但是三者的设计目的是不一样的,这是区分三者的关键。

模式目的
装饰者模式不改变接口,但加入责任/功能。
适配器模式将一个接口转成另一个接口
外观模式简化接口

[Android 源码实例]
开发中常用的Context.java中的startActivity(…)和startService(…)方法都是外观模式,开发者只要调用接口,其中的具体工作会有ActivityManagerService等类去完成; 这两个接口方法简化了相应的功能,对开发者来说,很方便。


9. 模板方法模式(Template method pattern)

之前已经封装了对象创建、方法调用和复杂接口,本章将封装算法。

模板方法模式: 在一个方法中定义算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类在不改变算法结构的情况下,重新定义算法中的某些步骤。

所谓模板就是一个方法,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的。
为防止子类修改模板方法,抽象类中可以将模板方法声明为final。
在这里插入图片描述
模板方法的抽象类可以定义抽象方法、具体方法和钩子方法。

钩子方法
钩子方法是一种被声明在抽象类中的方法,但是只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩; 要不要挂钩由子类决定。

钩子方法应用很广泛。

好莱坞原则
别调用(打电话给)我们,我们会调用(打电话给)你。

依赖倒置原则教我们尽量避免使用具体类,而多使用抽象。而好莱坞原则是用在创建框架或组件上的一种技巧,好让底层组件能够被挂钩进计算中,而且又不会让高层组件依赖底层组件。两者的目的都是在于解耦,但是依赖倒置原则更加注意如何在设计中避免依赖。

模式特点
模板模式子类决定如何实现算法中的步骤
策略模式封装可以互换的行为,然使用委托来决定要采用哪一个行为
工厂方法模式由子类决定要实例化哪个具体类

策略模式和模板方法模式都封装算法,但是一个使用组合,一个使用继承。

[Android源码实例]
AsyncTask定义了一套完整的算法框架:onPreExecute、doInBackground、onProgressUpdate、onPostExecute和onCancelled; 但是这些方法都由子类根据自己需求来选择性的实现。


10. 迭代器(Iterator)和组合(Composite)模式

迭代器模式: 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。
把游走的任务放在迭代器上,而不是聚合上; 这样简化了聚合的接口和实现,也让责任各得其所。
在这里插入图片描述
设计原则:一个类应该只有一个引起变化的原因。
内聚 用来衡量一个类或模块紧密地达到单一目的或责任。当一个类或模块被设计成之支持一组相关的功能时,我们说它具有高内聚; 反之,具有低内聚。

[Android源码实例]
我们常用的集合类ArrayList和HashMap的遍历就使用到了迭代器模式。

组合模式: 允许将对象组合成树结构来表现“整体/部分”层次结构。组合能让客户以一致的方式处理个别对象或对象组合。
在这里插入图片描述

组合模式以牺牲单一责任设计原则来换取透明性。所谓透明性,一个元素是组合还是叶节点对客户是透明的。

组合通常用树结构。

[Android 源码实例]
View和ViewGroup就是组合模式,子view以树的结构进行组合。


11. 状态模式(State pattern)

状态模式 允许对象在内部状态改变的时候改变行为; 对象看起来好像修改了它的类。
在这里插入图片描述
策略模式 VS 状态模式
策略模式:客户通常主动指定Context对象所要组合的策略对象。
状态模式:允许Context随着状态的改变而改变行为。

[Android 源码实例]
状态模式比较常见,Android源码中定义了StateMachine这个类,方便了状态模式的使用,同时从这个类的存在也可以看出状态模式使用之频繁。

  • 用于建立数据连接的DcConnection.java使用状态模式,切换数据连接建立过程中的不同状态。
  • 通话中用于Audio route切换和Audio mode切换的CallAudioRouteStateMachine.java和CallAudioModeStateMachine.java。

12.代理模式(Proxy pattern)

代理模式 为另外一个对象提供一个替身或占位符以控制对这个对象的访问。

代理模式要做的是控制和管理访问。
代理控制访问的几种方式:

  • 远程代理控制访问远程对象。
  • 虚拟代理控制访问创建开销大的资源。
  • 保护代理基于权限控制对资源的访问。

代理模式的类图如下:
在这里插入图片描述
代理模式有很多变种,比如缓存代理、同步代理、防火墙代理和写入时复制代理。

代理模式在结构上类似于装饰者模式,但是两者目的不同;代理模式控制对象访问,而装饰者模式为对象添加行为。

Java RMI(Remote method invocation)远程方法调用,RMI的好处在于不必亲自写任何网络或I/O的代码。

transient关键字可以防止字段被JVM序列化。

[Android 源码实例]
Binder机制使用了远程代理模式。


13.复合模式

复合模式: 在解决方案中结合两个或多个模式,以解决一般或重复发生的问题。
将某些模式结合使用,并不代表这些模式就可以称为复合模式; 复合模式必须够一般性,适合解决许多问题才行。

采用模式时必须考虑这么做是否有必要。

经典复合模式—MVC
MVC使用了观察者模式、策略模式和组合模式。

模型利用观察者让控制器和视图可以随最新的状态改变而更新。
模型负责维护所有的数据、状态和应用逻辑;所谓应用逻辑指的是管理与操纵模型中数据的代码。

视图和控制器实现了策略模式,控制器是视图的行为,如果希望有不同的行为,可以直接换一个控制器。视图只关心系统中的可视部分,对于任何界面行为,都委托给控制器处理。

视图内部使用组合模式来管理窗口、按钮以及其他显示组件。

MVC有很多变种,经典MVC的结构如下:

在这里插入图片描述


14.附录中的模式

对这几个附录模式理解都不到位,有时间还是要仔细揣摩,找些实际例子学习。

14.1 桥接模式

桥接模式通过将实现和抽象放在两个不同的类层次中,从而可以独立改变它们。
使用桥接模式不止改变实现,还可以改变抽象。

在这里插入图片描述
桥接模式的优点

  • 将实现解耦,让它和界面之间不再永久绑定。
  • 抽象和实现可以独立扩展,不再相互影响。
  • 对于“具体的抽象类”所做的改变,不会影响到客户。

桥接模式的用途和缺点

  • 适合使用在需要跨多个平台的图形和窗口系统上。
  • 当需要使用不同的方式改变接口和实现时,桥接模式很好用。
  • 桥接模式的缺点是增加了复杂度。

[Android 源码实例]

  • ContextWrapper和ContextImpl就属于桥接模式。
  • WindowManagerImpl和WindowManagerGlobal也属于桥接模式。
  • 应用层和Native层的交互也是桥接模式的例子。

14.2 生成器(Builder pattern)

使用生成器模式封装一个产品的构造过程,并允许按步骤构造。

生成器的优点

  • 将一个复杂对象的创建过程封装起来。
  • 允许对象通过多个步骤来创建,并且可以改变过程(这和只有一个步骤的工厂模式不同)。
  • 向客户隐藏产品的内部表现。
  • 产品的实现可以被替换,因为客户只看到一个抽象的接口。

生成器的用途和缺点

  • 经常别用来创建组合结构。
  • 与工厂模式相比,采用生成器模式创建对象的客户,需要具备更多的领域知识。

[Android 源码实例]
使用AlertDialog的静态内部类Builder创建AlertDialog,使用者可以通过Builder为AlertDialog设置Tittle、Icon和button等。类似的还有Notification和Uri对象的创建。


14.3 责任链(Chain of responsibility pattern)

当需要让一个以上的对象能够处理某个请求的时候,就使用责任链模式。
通过责任链模式,可以为某个请求创建一个对象链,每个对象依次检查此请求,并对其进行处理,或将请求传给链中的下一个对象。
在这里插入图片描述
责任链的优点

  • 将请求的发送者和接受者解耦。
  • 可以简化你的对象,因为它不需要知道链的结构。
  • 通过改变链内的成员或调动它们的次序,允许动态地新增或删除责任。

责任链的用途和缺点

  • 经常被使用在窗口系统中,处理鼠标和键盘之类的事件。
  • 并不保证请求一定会被执行; 如果没有任何对象处理它的话,它可能会落到链末端之外(这可以是优点也可以是缺点)。
  • 可能不容易观察运行时的特征,有碍于除错。

[Android 源码实例]
Touch/Key事件的分发使用的就是责任链模式。


14.4 蝇量模式(Flyweight pattern)

如果想让某个类的一个实例能用来提供许多“虚拟实例”,就使用蝇量模式。
在这里插入图片描述
蝇量模式的优点:

  • 减少运行时对象实例的个数,节省内存。
  • 将许多“虚拟”对象的状态集中管理。

蝇量的用途和缺点:

  • 当一个类有许多实例,而这些实例能被用一个方法控制的时候,我们就可以使用蝇量模式。
  • 蝇量模式的缺点在于,一旦实现了它,那么单个的逻辑实例将无法拥有独立而不同的行为。

[Android 源码实例]
没有找到例子。


14.5 解释器模式(Interpreter pattern)

使用解释器模式为语言创建解释器。
用途和缺点

  • 当需要实现一个简单的语言时,可以使用解释器。
  • 当有一个简单的语法,而且简单比效率更重要时,可以使用解释器。
  • 可以处理脚本语言和编程语言
  • 当语法规则的数目太大时,这个模式可能会变的非常复杂。在这种情况下,使用解释器/编译器的产生器可能会更合适。

[Android 源码实例]
AndroidMenifest.xml文件在PackagePaser中的解析,属于解释器模式。


14.6 中介者模式(Mediator pattern)

使用中介者来集中相关对象之间复杂的沟通和控制方式。
在这里插入图片描述
中介者的优点

  • 通过将对象彼此解耦,可以增加对象的复用性。
  • 通过将控制逻辑集中,可以简化系统维护。
  • 可以让对象之间所传递的消息变得简单而且大幅减少。

中介者的用途和缺点

  • 中介者常常被用来协调相关的GUI组件。
  • 中介者模式的缺点是,如果设计不当,中介者对象本身会变得过于复杂。

[Android 源码实例]
KeyguardViewMediator.java使用中介者模式来调解PowerManager、AlarmManager和AudioManager等多个Manager。


14.7备忘录模式(Memento pattern)

当需要让对象返回之前的状态时,就使用备忘录模式。
备忘录模式有两个目标:

  • 存储系统关键对象的重要状态。
  • 维护关键对象的封装。

备忘录的优点:

  • 将被存储的状态放在外面,不要和关键对象混在一起,这可以帮助维护内聚。
  • 保持关键对象的封装。
  • 提供了容易实现的恢复能力。

备忘录的用途和缺点

  • 备忘录用于存储状态
  • 使用备忘录的缺点:存储和恢复状态的过程可能相当耗时。
  • 在Java系统中,可以考虑使用序列化机制存储系统状态。

[Android 源码实例]
Activity中的onSaveInstanceState和onRestoreInstanceState使用的就是备忘录模式,来保存和恢复Activity异常结束前的状态。


14.8 原型(Prototype pattern)

原型模式通过复制现有的实例来创建新的实例。

当创建给定类实例的过程很复杂时,就使用原型模式。

原型的优点

  • 向客户隐藏制造新实例的复杂性。
  • 提供让客户能够产生未知类型对象的选项。
  • 在某些环境下,复制对象比创建对象更有效。

原型的用途和缺点

  • 在一个复杂的类层次中,当系统必须从其中的许多类型创建新对象时,可以考虑原型。
  • 使用原型的缺点:对象的复制有时相当复杂。

[Android 源码实例]

  • 在Java中clone()方法或者反序列化就是原型模式,ArrayList等都实现了clone()方法。
  • Android中的Intent也实现了clone()方法,不过还是通过new来创建新对象,因为创建新Intent对象比较简单,所以没必要通过clone来实现。

14.9 访问者(Visitor pattern)

当想要为一个对象的组合增加新的能力,且封装不重要时,就使用访问者模式。

访问者的优点

  • 允许对组合结构加入新的操作,而无需改变结构本身。
  • 想要加入新的操作,相对容易。
  • 访问者所进行的操作,其代码是集中在一起的。

访问者的用途和缺点

  • 当采用访问者模式的时候,就会打破组合类的封装。
  • 因为游走的功能牵涉其中,所以对组合结构的改变就更加困难。

[Android 源码实例]
没有找到例子。


总结
模式的一般描述

模式是在某情境(context)下,针对某问题的某种解决方案;这个描述是一般性的,很多模式描述都不止这些。描述中有三个关键词:问题情境解决方案

模式的分类

1. 根据模式的目标可以分成三类:创建型、行为型和结构型。

  • 创建型模式涉及到将对象实例化,这类模式都提供以后i个方法,将客户从需要实例化的对象中解耦。
    Singleton、Abstract factory、Factory method、Prototype和Builder都属于创建型模式。

  • 行为型模式,只要是行为型模式都涉及到类和对象如何交互及分配职责。
    Template method、Iterator、Command、Observer、State、Strategy、Mediator、Visitor、Interpreter、Chain of responsibility和Memento都属于行为模式。

  • 结构型模式可以把类或对象组合到更大的结构中;结构模式用来描述类和对象如何被组合以建立新的组合或功能。
    Decorator、Proxy、Composite、Facade、Adapter、Flyweight和Bridge都属于结构型模式。

2. 根据模式所处理的是类或对象进行分类

  • 类模式描述类之间的关系如何通过继承定义;类模式的关系是在编译时建立的。
    Template method、Factory method、Adapter和Interpreter都属于类模式。

  • 对象模式描述对象直接的关系,而且主要是利用组合定义;对象模式的关系通常在运行时建立,更动态、更有弹性。
    Composite、Decorator、Facade、Command、Observer、Prototype、Proxy、Strategy、State、Abstract factory、Singleton、Visitor、Chain of responsibility、Mediator、Flyweight、Bridge和Builder都属于对象模式。


Warning

过度使用涉及模式可能导致代码过度工程化。应该总是用最简单的解决方案完成工作,并在真正需要模式的地方才使用它。

反模式

反模式看起来总像是一个好的解决方案,但当它真正被采用后,就会带来麻烦。所以将反模式归档,可以帮助我们分辨出不好的模式。

模式相关网站

http://c2.com/cgi/wiki?WelcomVisitors
http://hillside.net/
https://www.jianshu.com/p/632d45c3b65d


结束!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值