设计模式总概——未完待续…(持续更新)
创建型
-
单例:保证一个类仅有一个对象,并提供一个访问它的全局访问点。
- 标志:
instance()
方法 - 静态全局访问,无状态,一般为工具性质
- 标志:
-
工厂:定义一个用于创建对象的接口,让子类决定将哪一个类实例化,FactoryMethod使一个类的实例化延迟到其子类。
- 简单工厂:
- 传入想要对象的类型,配合switch或多个if-else语句选择返回一个合适的对象。
- 不好扩展,增加新类,需要重写方法。
- 普通工厂:一个超类工厂作为接口,后续每一个产品都要写一个工厂去实现该接口。(一个产品就是需要一个工厂)
- 简单工厂:
-
抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。
- 同一种产品可能有不同类型,不同规格,所以工厂限制好每个子工厂产品的共性——抽象出共性接口。
三个工厂模式:
简单工厂:一个工厂,造不同的东西。
|—普通工厂:一个产品自成一个工厂。
|—抽象工厂:规范各个工厂高度抽象的共性方法。
-
建造者:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
-
原型:用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。
- 简而言之:搭积木的思想,许许多多的完全一致的小单位组成不同大小的个体。
结构型
- 适配器:将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- 装饰:动态地给一个对象添加一些额外的职责。就扩展功能而言,Decorator模式比生成子类的方式更为灵活。
- 桥接:将抽象部分与它的实现部分分离,使他们都可以独立地变化。
- 组合:将对象组合成树形结构以表示“部分-整体”的层次结构。Composite 使得客户对单个对象和复合对象的使用具有一致性。
- 外观:为子系统中的一组接口提供一个一致的接口。Façade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
- 简而言之:“再封装”,把老旧的系统核心实现封装成一个类,暴露简单的几个接口进行业务实现。
- 享元:运用共享技术有效地支持大量细粒度的对象。
- 简而言之:“池”技术的实现根基。维护一个hashmap,想用某个实例,有就直接get出来给你用,没有就new一个放进去再拿出来给你用,用完不删,一直存着。
- 代理:为其他对象提供一个代理以控制对这个对象的访问。
行为型
- 模板:定义一个操作中的算法的骨架,而将一些步骤延迟到子类。TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
- 命令:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可取消的操作。
- 迭代器:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
- 观察者:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。
- 中介者:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
- 备忘录:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保持该状态,这样以后就可以将该对象恢复到保存的状态。
- 解释器:定义一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
- 状态模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。
- 策略模式:定义一系列的算法,把它们一个个封装起来,并且使他们可相互替换。本模式使得算法的变化可以独立于使用它的客户。
- 责任链:为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它。
- 访问者:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类别的前提下定义作用于这些元素的新操作。
个人QA
一、原型模式与享元模式
原型模式:减少类class的数量,用对象来代替类。 (这些对象内部属性一致)
享元模式:减少对象的数量
-
怎么理解原型模式呢?
坦克大战的地图资源中,钢墙有两种形态
单层钢墙和双层钢墙,一般情况下我们会想到设计两个类:单层钢墙类和双层钢墙类。但是利用原型模式设计,只需要使用一个类:单个钢块类。这样双层钢墙只需要复制4个即可实现,同理双层钢墙只需要复制2个。这就做到了**“减少类的数量,用对象来代替类”**。
-
怎么理解享元模式呢?
**关键代码:**用 HashMap 存储这些对象
**注意:**1、注意划分外部状态和内部状态,否则可能会引起线程安全问题。 2、这些类必须有一个工厂对象加以控制。
秉承“我哈希map里没有就创建一个放进去再给你用,有的话直接拿出来给你用”的思想。
二、回调这个好东西
C++中可以传函数指针,java里也可以,但没必要,java直接传对象。
待续…
三、外观模式
定义:为子系统中的一组接口提供一个一致的界面,用来访问子系统中的一群接口
1、设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式;
2、开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口;
3、维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。
其实就是,某个功能随着系统的越来越庞大,需要调用的接口也越来越多,一堆代码看起来难看,索性封装起来,让层次更清晰的一种解决方式。
优点:
- 1、实现了子系统与客户端之间的松耦合关系;
- 2、客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易。
缺点:
- 1、不符合开闭原则,如果要修改某一个子系统的功能,通常外观类也要一起修改;
- 2、没有办法直接阻止外部不通过外观类访问子系统的功能,因为子系统类中的功能必须是公开的(根据需要决定是否使用internal访问级别可解决这个缺点,但外观类需要和子系统类在同一个程序集内)。
伪代码举例:
class A{
public void methodA(){
System.out.println("这里实现文件读写");
}
}
class B{
public void methodB(){
System.out.println("这里实现权限认证");
}
}
class Facade{
A a;
B b;
public Facade(){
a = new A();
b = new B();
}
public void dealSomething(){
a.methodA();
b.methodB();
}
}
说明:向外暴露业务处理方法,如果不用外观类,会使得所有写这个业务的人都需要熟悉这个业务背后的支撑逻辑,然后揉在一起去实现该业务。如果使用了外观模式,只需要一个人去编写这个外观类,即可让其他人不需要关注其他的,直接调用即可。
四、组合模式
待续…
向外暴露业务处理方法,如果不用外观类,会使得所有写这个业务的人都需要熟悉这个业务背后的支撑逻辑,然后揉在一起去实现该业务。如果使用了外观模式,只需要一个人去编写这个外观类,即可让其他人不需要关注其他的,直接调用即可。
四、组合模式
待续…