关闭

设计模式学习笔记——创建模式

512人阅读 评论(0) 收藏 举报

1.简单工厂模式(静态工厂方法) Simple Factory:
 作用:将生产者和消费者分离,适用于对象创建时需要进行比较复杂处理的情况,即消费者符合开闭原则;
 详解:一个工厂生产所有产品,工厂得到要生产产品的订单号,然后生产出相应的产品(即在工厂类中有一个静态的生产方法,根据参数判断、创建并返回相应的对象,静态方法的返回值为产生对象的基类;消费者直接调用这个工厂类的生产方法即可得到想要的对象);
 缺陷:每增加一种产品类型,需要在生产方法里增加相应的判断逻辑和业务逻辑等,不符合开闭原则(对扩展开放,对修改关闭);
    所生产的产品可能有多层次树状结构,由单一工厂来生产负担过重。

2.工厂方法模式 Factory Method:
 作用:分担单一工厂生产的压力,使工厂类也符合开闭原则;
 详解:每个工厂只生产一种产品,由产品委员会指导各个工厂生产(即定义一个产品委员会接口,包含一个返回值为产品基类的非静态的生产方法,每个生产工厂类实现这个接口,各自实现具体的生产方法,用于生产继承了产品基类的不同对象;消费者需要调用指定的生产工厂类的生产方法得到想要的对象);
 缺陷:产品种类很多时,需要大量与之对应的工厂类;
    需要在客户程序中将具体工厂角色写死,往往只适合产生单个的实例;
    产品对象创建条件的改变必然会引起工厂角色的修改。

3.抽象工厂模式 Abstract Factory
 作用:给客户程序提供统一抽象类,可以创建多个不同类型的产品对象;
 详解:每个工厂都要生产多种不同种类的产品,此时标准委员会为每种类型的产品制订统一标准,各个工厂根据标准生产出各具特色的各个种类的产品(即定义一个标准委员会抽象基类,包含多个返回值为某种类型产品基类的抽象生产方法,每个生产工厂类继承标准委员会抽象基类,实现标准委员会定义的各个类型产品的生产方法,用于生产继承了某种类型产品基类的对象;消费者需要选择一个工厂类,然后可以得到该工厂类能生产出的所有类型的对象);
 缺陷:增加新的产品类型时,需要增加标准委员会基类中抽象方法,同时需要在工厂类中增加该方法实现。

4.原型模式 Prototype
 作用:增删产品类型时,可以通过统一管理器来维护,使扩展更加容易;
 详解:有一个产品档案管理处,当你要增加一个产品类型时,你必须先在产品档案管理处注册这个产品,之后要生产此种产品时,也必须先通过产品档案管理处查找到此产品方能生产(克隆)出此产品,当然,你也可以通过产品档案管理处注销此产品,使之不能再生产(即定义一个原型管理器类,此类拥有一个容器用于存放已经注册过的产品信息,同时此原型管理器类有至少三个方法:注册新产品、注销产品和生产指定产品,生产指定产品的方法用调用了克隆clone方法来从原有对象中抽取信息放到新的产品对象中);
 缺陷:每个产品类型的原型必须必须包含clone方法,在已有类的基础上来添加clone操作是比较困难的;
    当内部包含一些不支持copy或者循环引用的对象时,实现更加困难。

5.建造模式 builder
 作用:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示;
 详解:现在制造委员会和组装委员会各司其职,制造委员会负责指定制订制造和显示的标准,组装委员会负责组装过程的标准化,具体的制造者根据制造委员会的标准完成各个部件的制造,然后在组装委员会的指导下统一装配,最后完成想要的产品(即定义制造委员会接口,定义部件生产方法和产品的表示方法,具体每个制造者类实现此制造委员会接口,组装委员会类对制造委员会接口编程,并包含统一的装配方法;消费者将制造者类的实例传给组装委员会类,组装委员会类调用统一装配方法,之后由制造者类的表示方法得到想要的复杂产品对象);
 类比:建造模式着重于逐步将组件装配成一个成品并向外提供成品,而抽象工厂模式着重于得到产品族中相关的多个产品对象。

6.单例模式 Singleton
 作用:保证一个类仅有一个实例,并提供一个访问它的全局访问点;
 详解:单例模式可以分为有状态和无状态的,有状态的单例对象一般也是可变的单例对象,多个单例对象在一起就可以作为一个状态仓库一样向外提供服务,没有状态的单例对象也就是不变的单例对象,仅用做提供工具函数;
    普通的单例模式通常采用私有构造函数,或者构造静态实例(饿汉),或者采用静态工厂方法(懒汉),此种做法的使得该类不能被继承,从而失去多态性;亦有“高级”做法,采用受保护构造函数,而采用静态的注册对象容器存储已经生成对象实例,用静态工厂方法来限制对已经存在同样类名的实例则不再创建新的实例,仅返回原有实例,此种做法允许该类被继承;
 陷阱:在使用EJB、JINI、RMI技术的分布式系统中,由于中间件屏蔽掉了分布式系统在物理上的差异,想知道哪个虚拟机下运行了哪个单例对象是很困难的应该避免使用存在状态的单例模式;
    不同类加载器会使用不同命名空间来区分同一个类,单例类在多加载器的环境中会产生多个单例对象,在一般情况下不要使用存在状态的单例模式;
    采用静态工厂方法的单例模式中,如果同步处理不恰当,可能达不到得到单个对象的效果,还会引发死锁等错误;
    采用受保护的构造函数时,由于类的构造函数不再私有,可能会失去对对象的控制,只能通过良好的文档来规范;
    为使一个单例类可串行化,不仅要在声明中添加"implements Serializable",还要在单例类中添加readResolve方法(因为一个串行化的对象每次返串行化的时候,都会创建一个新的对象,而不仅仅是一个对原有对象的引用)。
 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:401402次
    • 积分:4195
    • 等级:
    • 排名:第7703名
    • 原创:35篇
    • 转载:242篇
    • 译文:2篇
    • 评论:70条
    最新评论