创建型模式隐藏了实例的创建过程,整个系统 对于对象所知道的仅仅只有抽象类所定义的接口。
在 创建了什么,谁创建的,怎么被创建之中,提供了很大的灵活性。
一共有5种,分别为:
1.抽象工厂 AbstractFactory
2.建造者 Builder
3.工厂方法 FactoryMethod
4.原型模式 Prototype
5.单例模式 SingleTon
其中较为优秀的有 Builder FactoryMethod 和SingleTon,其他两种本文不作重点。
1,Builder,将一个复杂对象得构建与它的表示分离[这只是创建型模式的通性]
使得:同样的构建过程 可以创建不同的表示 时,可以使用Builder模式
关键字: 分离, 构建过程,不同结果
分离 指的是创建和结果分离
应用在软件开发中,常提倡为 高内聚,松耦合,即:
1,谈内聚性和耦合性,
内聚性 描述的是一个类内部各方法之间的关联紧密程度,
耦合性 是描述一个类和其他类之间的联系的紧密程度,
软件开发的目标是 高内聚,松耦合。
松的意思 就是小巧,直接,可见,灵活。
2,如何实现松耦合:
将一个复杂对象的创建 与它的表示 分离
这样就很容易改变一个产品的内部表示
构造代码和表示代码分块,对于客户,可以使用同样的构建过程创建不同的产品给用户,
1)在什么情况下适用:
a. 当创建复杂对象的算法 应该 独立于该对象的组成部分 以及
他们的装配方式;
b. 当构造过程必须允许构造的对象有不同的表示;
2)读大话设计模式的时候,Builder模式反复阅读实践四遍有余,心中一直有个疑问,Builder模式就是创建复杂对象的模板吗?
网上一搜,确实有相同疑惑的,且慢慢解惑:
且看《大话设计模式》中Builder模式UML图
如果把Builder当作一个创建复杂对象的模板,则基本上可以断定,Builder模式被误用了。
Builder模式的类图结构中,装配复杂对象的组成部分,是用BuilderPart()方法来定义,如果我们把这个装配操作视为一个操作行为,是不是意味着这种情况下的Builder模式就是一个Template Method了呢?
我认为答案是否定的。Builder模式与Template Method模式有着天壤之别,
二者毫不相干;前者偏重于通过聚合来组装对象,后者偏重于通过继承来重写对象的行为。
这里提出了两者的区别,Builder模式通过聚合方式 组装对象,而不是为了写一套模板去继承,造一个 小人出来,这就是 《大话涉及模式》之Builder章节给我的困惑,作者深入浅出举的例子强调于 建造小人 过程的稳定性,而没有去阐述 整个Builder过程中,可能不同的组装方式,比如两个脑袋,三条手臂的人 这种组装方式, 对吧? Builder的核心 是组装,而不是 建造的稳定,这是作者所失误的地方,让我困惑许久。
总结:Builder模式的核心是“聚合”。作者在UML上失误的地方 在于,没有重点阐述Director中的不同组装情况,这才是聚合,这才是Builder的核心。
改进版的Builder UML图
来自@Silent Void 的:http://happyhippy.cnblogs.com/ 感谢他的分析。
这里的Builder 强调于组装的不同情况, 具体在代码中,体现为 在PersonDirector中有3个算法可以组装产生3种不同的结果,这就是Builder模式 的核心 “组装”思想。
而不是简单的稳定的流程,继承实现,神似Builder 具有director和builder和不同的结果product,但其实是模板方法的变种而已。这里再一次提醒自己:Builder的的核心是 Director的组装算法!
2.工厂模式,仅仅讲工厂方法模式
1)工厂方法是什么
答:定义一个用于创建对象的接口,让子类决定创建那个类。Factory Method使一个类的实例化延迟到其子类中
关键字: 子类决定创建,而不是父类或者父接口决定 实例化 放到客户端去创建【延迟】
2)应用:工厂方法主要应用于工具包和框架中
3)设计原则:要依赖抽象,不要依赖具体类-依赖倒置原则
4)工厂方法优缺点:
优点:
1.支持OCP原则,开闭原则,把创建产品的细节隐藏起来,对上层类的调用时透明的
2.工厂方法可以带来一个灵活性,当产品发生改变的时候,它的工厂不需要修改,只需要添加就行了
工厂方法 UML图
如上图所示:如果需要添加海信电视的时候,只需要添加一个海信工厂和一个海信电视类
而,如果使用简单工厂的话,需要修改电视工厂,违反了开闭原则:可以添加不可以修改,因为修改就要停止程序,并且需要再次调试,
而添加不需要,并且不影响其他的类,修改了工厂类,就会影响其他的
工厂方法的缺点:
1.只能创建单一系列的产品,如果添加一个冰箱就不行了
//电视接口
public interface TV {
//打开
public void turnOn();
public void turnOff();
}
//长虹电视
public class ChangHongTV implements TV public void turnOn() {
System.out.println("ChangHong.turnOn()");
}
public void turnOff() {
System.out.println("ChangHong.turnOff()");
}
}
//海尔电视
public class HaiErTV implements TV {
public void turnOn() {
System.out.println("HaiErTV.turnOn()");
}
public void turnOff() {
System.out.println("HaiErTV.turnOff()");
}
}
//工厂接口
public interface TVFactory {
public TV createTV();
}
//长虹工厂
public class TVFactory_ChangHong implements TVFactory {
public TV createTV(){
//构造长虹电视
return new ChangHongTV();
}
}
//海尔工厂
public class TVFactory_HaiEr implements TVFactory {
public TV createTV() {
// TODO Auto-generated method stub
//构造海尔电视
return new HaiErTV();
}
}
//客户端
public class Client {
//依赖于抽象而不是实现
public static void main(String[] args) {
//现在客户端只认识一个抽象的TVFactory,其他的可以使用反射,动态的
//TVFactory factory = new TVFactory_HaiEr();
//TVFactory factory = new TVFactory_ChangHong();
//生产产品的时候,只需要修改这句话,下面的代码都不需要改变,因为依赖的是抽象
TVFactory factory = new TVFactory_HaiXin();
TV tv = factory.createTV();
tv.turnOn();
}
}
3.单例模式
优势:控制产生唯一的实例
单例模式 很简单,上代码,通俗易懂
//饿汉模式
public class Singleton_Simple {
private static final Singleton_Simple simple = new Singleton_Simple();
private Singleton_Simple(){}
public static Singleton_Simple getInstance(){
return simple;
}
}
//他的创建是在我们调用getInstance()静态方法之前
//懒汉模式
public class Singleton_lazy {
private static Singleton_lazy lazy = null;
private Singleton_lazy(){}
public static synchronized Singleton_lazy getInstance(){
if( lazy == null ){
lazy = new Singleton_lazy();
}
return lazy;
}
}
//,他的创建是在我们调用getInstance()静态方法之后,为了并没现象同步问题,我们在getInstance()方法上加了一个锁,这个方法每次只允许一个线程进来