《深入浅出设计模式》
Chap2
1。判断两个对象是否相等(C#,重写Equals)
Chap3 创建型设计模式
1. 简单工厂模式(Simple Factory Pattern)
专门定义一个类来负责创建其他类的实例。被创建的实例通常具有共同的父类。又称为静态工厂方法(Static Factory Method),属于类的创建型模式,通常根据自变量的不同返回不同的类的实例。
优势:
劣势:集中了所有实例的创建逻辑,违反高内聚责任分配原则。当系统中具体产品类不断增多时,可能会出现要求工厂类根据不同条件创建不同实例的需求。对系统的扩展和维护非常不利。
应用情境:
1.工厂类负责创建的对象比较少
2.客户只知道传入工厂类的参数,对于如何创建对象逻辑不关心。
2. 工厂方法模式(Factory Method Pattern)
又称多态工厂(polymorphic factory)模式,或者虚拟构造器模式(Virtual Constructor)。在这个模式中,父类负责定义创建对象的公共接口,子类负责生成具体对象,将实例化操作延迟到子类中完成,由子类决定应该实例化哪一个类。
优势:使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节就完全封装在具体工厂内部;在系统中加入新产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他具体工厂和具体产品,只需要添加一个具体工厂和具体产品就可以了。
劣势:再添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类。
应用情境:
1.类不知道自己要创建哪一个对象。
2.类用他的子类来制定创建哪个对象
3.客户需要清楚创建了哪一个对象。
3.抽象工厂模式(Abstract factory pattern)
提供一个创建一系列相关或相互依赖对象的接口。与工厂模式最大区别在于:工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则针对的是多个产品等级结构。抽象工厂模式经常会用到产品族这一概念,它指的是位于不同的产品等级结构中,并且功能相互关联的产品联系。
优势:隔离了具体类的生成,是客户不需要知道什么被创建了;更换一个工厂变得相对容易。最大好处是,当一个产品组中的多个对象被设计成一起工作的时候,能够保证客户端始终使用同一个产品组中的对象。
劣势:添加新产品对象时,难以扩展抽象工厂一边生产新种类的产品。
应用情境:
1.系统需要屏蔽有关对象如何创建、如何组织和如何表示
2.系统需要由多个关联的对象来构成。
3.有关联的多个对象需要一起应用并且它们的约束是强迫的。
4.提供一组对象而不显示他们的实现过程,只显示接口。
4.建造者模式(Builder Pattern)
将一个复杂对象的构建与她的表示分离,使得同样的构建过程可以创建不同的表示。用户不知道内部的具体构建细节。
与Abstract factory区别:Builder返回完整的一个产品,而factory返回一系列有关的产品。factory中,客户采用abstract factory创建自己要用的对象,builder中,客户知道builder类生成对象,侧重于一步步生成一个复杂对象,然后返回结果。
举例:快餐店中,收银员为Director,指导员工进行配餐,然后返回套餐给顾客。
优势:把构造过程放到Director中,把装配过程放到具体建造者类中。
劣势:如果产品差异很多,需要借助工厂模式。另外,如果产品内部变化复杂,builder每一个子类都需要应用到不同的产品区做构建的动作、方法,需要定义很多个具体建造类实现。
应用情境:
1.创建复杂对象的算法是独立于它的组成部件及装配过程。
2.构造的过程允许构造对象有不同的表现。
5.原型模式(Prototype Pattern)
指定创建对象的种类,并且通过拷贝这些原型创建新的对象。允许一个对象在创建另外一个可定制的对象,根本无须知道任何创建细节。
工作原理:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象,拷贝原型自己来实现创建过程。
举例:拷贝- 粘贴
优势:在创建对象成本较大的情况下(初始化需要时间长,占用CPU或I/O资源多的情况,例如Web Service或DCOM创建对象,或者创建对象要装载大文件),系统如果需要重复利用,新的对象可以通过原型模式对已有对象的属性进行复制并稍做修改来取得。另外,如果对象状态变化很小或本身占内存不大的时候,也可以用原型模式配合备忘录模式来应用。
劣势:如果对象状态变化很大,或者对象占用内存很大,则状态模式比原型模式更好。缺点是,实现深层复制时需要编写复杂代码
应用情境:
1.类的实例化是动态的。
2.需要避免使用分层次的工厂类创建分层次的对象。
3.类的实例对象只有一个或很少的几个组合状态。
6.shallow copy 与 deep copy
进行shallow copy的时候,如果父类包含的子引用对象发生改变,这个变化也会同样出现在shallow copy后的对象中;在deep copy中则不会。
当Obj1浅复制Obj2的时候,它包含的子对象没有被复制,发生深层复制的时候,对象包含的引用也会被复制。
浅复制:C#采用MemberwiseClone();JAVA实现Cloneable接口的super.clone()
深复制:自己写代码
7.单例模式(Singleton pattern)
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。它提供全局访问的方法。要点有3:1)某个类只能有一个实例;2)它必须自行创建这个实例;3)它必须自行向整个系统提供这个实例
举例:windows任务管理器
优势:为应用程序提供对象唯一的访问点,提供了共享的概念。
劣势:对派生子类有很多困难,只有在父类没有被实例化时才可以实现。
值得注意的是,有些对象不能做成singleton,例如.NET的Connection对象,整个程序共享一个Connection会造成连接池溢出。
另外,在.NET和java这些会自动回收垃圾的语言中,如果实例化对象长时间不被利用,有可能会被收回消灭,所以要注意其状态是否丢失。
应用情境:
1.系统只需要一个实例的对象
2.客户调用类的单个实例只允许使用一个公共访问点。
8. 双检锁(double check locking)
Double Check不可能在现有的JVM编译器中运行成功,因为JVM不支持。而.NET中支持。
C#代码1:
C#代码2:
JAVA实现多线程的Singleton模式时,系统最好初始化Singleton的实例。在第一次调用getInstance方法就返回初始化好的实例。