设计模式

面向对象之设计模式

Posted by JT on January 23, 2019

23种设计模式全面解析

设计原则

单一职责原则

就一个类而言,应该仅有一个引起它变化的原因。

软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。

###开放封闭原则

  • 对修改封闭,对扩展开放。

  • 开放封闭的精神是,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。

###里式替换原则

  • 子类型必须能够替换掉他们的父类型

###依赖倒转原则

  • 抽象不应该依赖细节,细节应该依赖抽象(面向接口编程,抽象类)

  • 高层模块不应该依赖底层模块,两个都应该依赖抽象,这样无论高层模块还是底层模块的替换不会影响其他

###接口隔离原则

###组合复用原则

###迪米特法则

设计模式

学习设计模式需要了解每种模式的使用场景和优缺点

设计模式按其目的分为三类:

  • 创建型,共六种:简单工厂、工厂方法、抽象工厂、单例、建造者、原型
  • 结构型,共七种:适配器(Adapter)、桥接(Bridge)、组合(Composite)、装饰器(Decorator)、外观(Facade)、享元(Flyweight)、代理(Proxy) [ABCDFFP]
  • 行为型,共十一种:策略、模板、观察者、迭代器、责任链、命令、备忘录、状态、访问者、中介者、解释器

创建型

软件设计的过程是循序渐进,一步步来的。在软件设计中对象的创建和使用时分开的,因为对象的创建会消耗掉系统很多资源,所以单独对对象的创建进行研究,从而能够高效地创建对象,这是创建型设计模式要探讨和解决的问题。

简单工厂模式

通过一个工厂,根据不同的要求生产不同的产品,根据生产的产品执行产品特性。

优点:增加产品只需要增加对应的产品类并修改工厂增加判断条件即可,去除了与具体产品的依赖;

缺点:增加产品需要修改工厂方法,违反了“开放-封闭”原则

工厂方法模式

只生产同级别的产品,例如电视机工厂只生产电视机

定义一个抽象方法的接口类,实现多个工厂方法,不同的方法中生产不同的产品,选择确定的工厂方法生产产品,根据生产的产品执行产品特性。

优点:解决了简单工厂违反“开放-封闭”原则的问题

缺点:每增加一个产品,就需要增加一个工厂

抽象工厂模式

抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。

使用抽象工厂模式一般要满足以下条件。 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

优点:可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。 当增加一个新的产品族时不需要修改原代码,满足开闭原则。

缺点:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。

单例模式

只有一个实例,需要注意:

  • 是否允许其他形式的创建实例
  • 多线程访问是否能够保证其唯一性

建造者模式,又称生成器模式

指挥者->建造者->建造过程

使用场景:用于创建一些复杂的对象,这些对象内部构建的顺序是稳定的,但会有复杂的变化

原型模式

原型模式就是从一个对象在创建另一个可定制对象,而且不需知道任何创建的细节。

对于ios来说就是实现对象的copy、mutablecopy协议。

注意点:深复制和浅复制

结构型

解决了对象创建问题后,一个对象的组成和多个对象间的依赖关系成了开发人员关注的焦点问题。因为,如何设计对象的结构、继承和依赖关系会影响到后续程序的维护性、代码健壮性及耦合性等。这是结构型模式的关注点。

代理(Proxy)

代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

代理模式的主要角色如下:

  • 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
  • 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
  • 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

代理模式的主要优点:

  • 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用; 代理对象可以扩展目标对象的功能;
  • 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;

其主要缺点是:

  • 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
  • 增加了系统的复杂度;

应用场景:

  • 远程代理,这种方式通常是为了隐藏目标对象存在于不同地址空间的事实,方便客户端访问。例如,用户申请某些网盘空间时,会在用户的文件系统中建立一个虚拟的硬盘,用户访问虚拟硬盘时实际访问的是网盘空间。
  • 虚拟代理,这种方式通常用于要创建的目标对象开销很大时。例如,下载一幅很大的图像需要很长时间,因某种计算比较复杂而短时间无法完成,这时可以先用小比例的虚拟代理替换真实的对象,消除用户对服务器慢的感觉。
  • 安全代理,这种方式通常用于控制不同种类客户对真实对象的访问权限。 智能指引,主要用于调用目标对象时,代理附加一些额外的处理功能。例如,增加计算真实对象的引用次数的功能,这样当该对象没有被引用时,就可以自动释放它。
  • 延迟加载,指为了提高系统的性能,延迟对目标的加载。例如,Hibernate 中就存在属性的延迟加载和关联表的延时加载。

装饰模式(Decorator)

一个装饰器继承要装饰的对象或要装饰的父类,将要装饰的对象赋给装饰器,装饰器进行前后装饰。

优点:采用装饰模式扩展对象的功能比采用继承方式更加灵活。 可以设计出多个不同的具体装饰类,创造出多个不同行为的组合。

缺点:装饰模式增加了许多子类,如果过度使用会使程序变得很复杂。

适配器(Adapter)

桥接(Bridge)

组合(Composite)

外观(Facade)

享元(Flyweight)

行为型

在对象的创建和对象的结构问题解决后,就剩下对象的行为问题。如果设计的好,对象的行为就会更清晰,对象之间的协作效率会提高。

策略

模板

观察者

迭代器

责任链

命令

备忘录

状态

访问者

中介者

解释器