PHP设计模式


走进设计模式

什么是模式?

设计模式这个术语是由Erich Gamma等人在1990年代从建筑设计领域引入到计算机科学的。它是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。

什么是PHP设计模式?

什么是UML?UML怎样表示类和类的相互关系?

统一建模语言(UML,英语:Unified Modeling Language)是非专利的第三代建模和规约语言。UML是一种开放的方法,用于说明、可视化、构建和编写一个正在开发的、面向对象的、软件密集系统的制品的开放方法。UML展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。


设计原则

设计模式通常遵循的原则有哪些?

  1. 单一职责原则(Single Responsibility Principle)
    不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。
  2. 里氏替换原则(Liskov Substitution Principle)
    所有引用基类的地方必须能透明地使用其子类的对象。
  3. 依赖倒置原则(Dependence Inversion Principle)
    高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
  4. 接口隔离原则(Interface Segregation Principle)
    客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
  5. 迪米特法则(Law Of Demeter)
    一个对象应该对其他对象保持最少的了解。迪米特法则又叫最少知道原则,最早是在1987年由美国Northeastern University的Ian Holland提出。
  6. 开放-关闭原则
    一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。

为什么说组合优于继承?

组 合 关 系 继 承 关 系
优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立 缺点:破坏封装,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性
优点:具有较好的可扩展性 缺点:支持扩展,但是往往以增加系统结构的复杂度为代价
优点:支持动态组合。在运行时,整体对象可以选择不同类型的局部对象 缺点:不支持动态继承。在运行时,子类无法选择不同的父类
优点:整体类可以对局部类进行包装,封装局部类的接口,提供新的接口 缺点:子类不能改变父类的接口
缺点:整体类不能自动获得和局部类同样的接口 优点:子类能自动继承父类的接口
缺点:创建整体类的对象时,需要创建所有局部类的对象 优点:创建子类的对象时

具体情况具体分析,避免过度设计。

什么叫解耦?怎样实现解耦?

对于软件架构设计中模块间的解耦或者说松耦合,则需要包括两个层面的含义,拿A,B两个模块来举例。第一个层面的解耦是指A不用了解到B模块内部的细节,B模块内部细节的变化不会影响到A模块对B模块能力和服务的消费;第二个层面则是A模块的完整运行不受到B模块任何状态变化的影响,即使是B模块完全失效也不至于影响到A模块本身的业务。对于第一个层面重点是模块本身的高内聚,松耦合划分,服务层的设计,通过服务层来完成模块间的解耦;对于第二个层面则重点是消息中间件,异步和事件驱动机制。所以在进行组件化架构和解耦的设计时候一定要关注到我们真正关注的目标。

如何理解针对接口编程而不是针对实现编程?

接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离。 接口的本身反映了系统设计人员对系统的抽象理解。 接口应有两类:
第一类是对一个体的抽象,它可对应为一个抽象体(abstract class);
第二类是对一个体某一方面的抽象,即形成一个抽象面(interface);

什么叫单一职责?

所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。

什么叫开放-封闭原则?

对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。

什么叫依赖倒置原则?

所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

面向对象编程还应该遵循哪些原则?

面向对象的S.O.L.I.D 原则


常见设计模式

什么是单例模式?

单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。

通常单例模式在Java语言中,有两种构建方式:

单例模式适用于什么场景?

  1. 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
  2. 当这个唯一实例应该是通过子类化可扩展的。并且用户应该无需更改代码就能使用一个扩展的实例时。

什么是工厂模式?PHP怎么样实现工厂模式?

工厂模式 是一种类,它具有为您创建对象的某些方法。

什么是原型模式?原型模式的核心概念是什么?

原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例。

什么是外观模式?PHP怎样实现外观模式?

外观模式(Facade pattern),是软件工程中常用的一种软件设计模式,它为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用。

外观模式适用于何种场景?

什么是组合模式?日常生活中有哪些类似组合模式的例子?

(GoF《设计模式》):将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

组合模式的核心概念是什么?

装饰模式有什么优点?

修饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。

PHP怎样实现装饰模式?

##适配器模式中的适配器是什么意思?

在设计模式中,适配器模式(英语:adapter pattern)有时候也称包装样式或者包装。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类别自己的接口包裹在一个已存在的类中。

PHP怎样实现适配器模式?

PHP怎样实现迭代器模式?

迭代器模式是一种设计模式,是一种最简单也最常见的设计模式。它可以让使用者透过特定的接口巡访容器中的每一个元素而不用了解底层的实作。此面,也可以实作特定目的版本的迭代器。

观察者模式适用于什么场景?

观察者模式(有时又被称为发布-订阅Subscribe>模式、模型-视图View>模式、源-收听者Listener>模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

  1. 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。
  2. 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少个对象待改变。
  3. 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换句话说,你不希望这些对象是紧密耦合的。

怎样快速方便地实现观察者模式?

观察者模式有什么点?

观察者模式的优点:

  1. 观察者和主题之间的耦合度较小;
  2. 支持广播通信;

观察者模式的缺点:

  1. 由于观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知。这可能会引起意外的更新。

什么是中介者模式?

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

访问者模式有什么优点?

在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

优点: 1、符合单一职责原则。 2、优秀的扩展性。 3、灵活性。

缺点: 1、具体元素对访问者公布细节,违反了迪米特原则。 2、具体元素变更比较困难。 3、违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

使用场景: 1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。 2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作”污染”这些对象的类,也不希望在增加新操作时修改这些类。

什么是策略模式?策略模式的典型使用场景有哪些?

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

什么是命令模式?

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

有哪些地方使用了命令模式?

认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令。 2、模拟 CMD。

什么是责任链模式?责任链模式有哪些具体的应用?

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。

JS 中的事件冒泡。

链式调用模式的使用场景有哪些?

使用场景: 1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。


怎样使用设计模式?

什么情况下应该使用设计模式?

敏捷开发人员不会对一个庞大的预先设计应用那些原则和模式。相反,这些原则和模式被应用在一次次的迭代中,力图使代码以及代码所表达的设计保持干净。

使用设计模式有什么好处?

是否应该尽可能多的使用设计模式?

避免过度使用设计模式 易维护的程序首先要易理解,这一点远甚于其他。在易理解的代码上才好维护。过分地使用设计模式会增加程序的复杂性和晦涩性,让程序不易理解,从而降低了程序的易维护性。

你还使用或发现哪些设计模式?

什么是反模式?你见过哪些反模式?

反模式(英文:Anti-patterns或pitfalls), 是指用来解决问题的带有共同性的不良方法。它们已经经过研究并分类,以防止日后重蹈覆辙,并能在研发尚未投产的系统时辨认出来。软件开发中公认的反模式


参考

设计模式六大原则
面向对象思想的头脑风暴(二)—— 详解继承与组合的优缺点
组合未必优于继承
设计模式真的有使用的必要吗?
一些软件设计的原则
反面模式
设计模式

Yan Peipan 11 January 2015