设计模式总结篇一
设计模式被推崇至浪潮之巅应该是在GOF设计模式一书发布后,其实这里并不是说在此之前设计模式并不存在。在设计模式一书还没发布之前,好的代码已经在按照某种固定的模式进行实现,只是没有人进行系统地梳理成册,直到GOF四人组出现,才终于开创了设计模式这一概念。
1995年,有四位作者:Erich Gamma,Richard Helm,Ralph Johnson和John Vlissides发表了一本题为《设计模式 - 可复用的面向对象设计的基础》的图书,该书在软件开发中开创了设计模式的概念。
在书中有如下一段描述,应该可以很好地诠释他们的初衷。
本书中涉及的设计模式并不描述新的或未经证实的设计,我们只收录那些在不同系统中多次使用过的成功设计。这些设计的绝大部分以往并无文档记录,它们或是来源于面向对象设计者圈子里的非正式交流,或是来源于某些成功的面向对象系统的某些部分,但对设计新手来说,这些东西是很难学得到的。尽管这些设计不包括新的思路,但我们用一种新的、便于理解的方式将其展现给读者,即:具有统一格式的、已分类编目的若干组设计模式。
设计模式在软件开发中有两大主要用途:第一它提供了成体系的标准术语,第二它代表了有经验的面向对象软件开发人员使用的最佳实践。设计模式是在软件开发过程中面临的一般问题的解决方案。
虽然现在市面上有关设计模式的书籍很多,但是不可否认GOF所出的设计模式仍然是最经典的一部书,目前大家所熟知的设计模式,包括模式命名以及模式定义基本上直接或者间接源自GOF设计模式一书。
学习了23种设计模式,绝对不要理解为这23种设计模式就已经是设计模式的全部,如下一段是摘自GOF书中的描述:
尽管该书涉及较多的内容,但书中讨论的设计模式仅仅包含了一个设计行家所知道的部分。书中没有讨论与并发或分布式或实时程序设计有关的模式,也没有收录面向特定应用领域的模式。
从这里可以看出,23种设计模式只是设计模式的一个部分,设计模式还包括了许多其它不同领域的模式,平常所说的设计模式,它仅仅是可复用面向对象软件设计的基础。
设计模式划分
设计模式在粒度和抽象层次上各不相同。由于存在着多种设计模式,为了更快学习不同的设计模式,一般会将设计模式进行归类,在进行归类时基本上依据两条准则:目的准则和范围准则。
目的准则即是描述设计模式用来完成什么工作的。依据目的可以分为创建型、结构型和行为型三种。创建型与对象的创建有关;结构型处理类或者对象的组合;行为型模式是对类或者对象怎么样交互和怎么样分配职责进行描述。
范围准则描述模式是使用在类还是对象上。类模式处理类和子类之间的关系,这些关系通过继承建立,是静态的,在编译时刻便确定下来了。对象模式处理对象间的关系,这些关系在运行时刻是可以变化的,更具动态性。从某种意义上来说,几乎所有模式都使用继承机制,所以“类模式”只指那些集中于处理类间关系的模式,而大部分模式都属于对象模式的范畴。
创建型类模式将对象的部分创建工作延迟到了子类,而创建型对象模式是将对象的创建延时到另一个对象中。结构型类模式使用继承机制组合类,而结构型对象模式则是使用对象的组合方式完成。行为型类模式使用继承描述算法和控制流,而行为型对象模式则描述一组对象怎样协作完成单个对象所无法完成的任务。
创建型模式
单例模式(Singleton):一个类只有一个实例,并提供一个全局访问点。常用的单例模式有懒汉式、饿汉式以及静态内部类方式。
简单工厂(Simple Factory):有时又被成为静态工厂方法模式,是通过专门定义一个类来负责创建其它类的实例,被创建的实例通常都具有共同的父类。一般不把简单工厂模式归类到23种设计模式中,更多的是把它作为一种编程习惯。
工厂方法模式(Factory Method):定义一个创建对象的接口,让子类决定去实例化哪一个类。工厂方法模式使得一个类的实例化延迟到了子类。
抽象工厂模式(Abstract Factory):提供一个接口,用于创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类。
构建者模式(Builder):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
原型模式(Prototype):用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象
创建型模式即是创建对象的模式,它抽象化了实例的创建过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。
三种工厂模式,简单工厂模式在平常开发中也非常常见,它有点类似于一个工具类,将具有共同父类的实例创建过程抽象到了一个SimpleFactory类的创建方法中,有效减少if-else的使用,也可以降低代码重复率。工厂方法其实就是最常说的要面向抽象编程,在父类中定义一个可以返回对象类型的抽象方法,然后在不同的子类中实现对象的创建。抽象工厂模式则是创建一个产品系列,而不需要依赖它们具体的类。
工厂方法使用继承,把对象的创建委托给子类,子类实现工厂方法来创建对象。抽象工厂则是使用对象组合,对象的创建被实现在工厂方法暴露出来的方法中。
在《Head First设计模式》中有一个经典的示例,将创建披萨Pizza的过程设计成工厂方法模式,将创建披萨原材料的过程设计为抽象工厂模式,这样在工厂方法子类创建具体披萨时将原材料的抽象工厂传入,例如创建纽约的披萨时,将纽约口味的披萨原材料传入,芝加哥披萨传入芝加哥口味的原材料。
public abstract class PizzaStore { protected abstract Pizza createPizza(String item); public Pizza orderPizza(String type) { Pizza pizza = createPizza(type); // ... return pizza; } } public interface PizzaIngredientFactory { Cheese createCheese(); // ... } public class ChicagoPizzaStore extends PizzaStore { @Override protected Pizza createPizza(String item) { Pizza pizza = null; PizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory(); // ... pizza = new CheesePizza(ingredientFactory); } }
构建者模式(Builder)在开发中所遇到的使用场景中,Builder类的功能更倾向于一个JavaBean的功能,比如创建一个属性较多的实体类时,同时创建一个该实体类对应的Builder类,将所有实体类的属性再在Buidler类中声明一次,同时在Builder类中定义一个返回实体类的方法。构建者模式避免了在实体类的构造方法中传入过多的构造参数,当创建实体类时只需要传入一个Builder类型的对象,或者使用Buidler类链式调用。
原型模式更多是在创建复杂对象或者使用已存在对象的某些状态而又不想影响现有对象时使用,在支持clone的语言中,需要注意深克隆和浅克隆问题。