六种创建型设计模式总结.docx
《六种创建型设计模式总结.docx》由会员分享,可在线阅读,更多相关《六种创建型设计模式总结.docx(14页珍藏版)》请在冰豆网上搜索。
![六种创建型设计模式总结.docx](https://file1.bdocx.com/fileroot1/2023-1/31/e3b31401-5780-4074-937e-251afd8b0e4b/e3b31401-5780-4074-937e-251afd8b0e4b1.gif)
六种创建型设计模式总结
创建型模式分为六种:
1、单例模式:
在系统中只能形成类的一个对象。
2、工厂方法模式:
按类型创建出一个笼统的对象。
3、抽象工厂模式:
按多级类型创建笼统的对象。
4、模板模式:
在抽象类中实现一部分代码,通过继承方式使子类共享,避免代码复制。
5、建造模式:
按顺序一步步创建出复杂对象。
6、原型模式:
利用克隆方法,快速创建出一模一样的对象。
以下为了节省篇幅,忽略了一些程序细节和严谨性,包括:
●忽略了部分getter和setter方法。
●忽略了必须的try…catch
●忽略了一些原本应该从接口实现或从抽象类集成的代码
(一)单例模式
确保在整个系统中仅有该类的一个对象,该对象对于整个系统来说时全局的。
//单例类
publicclassSingleton
{
//在类中自己初始化一个static且final的自己对象。
privatestaticfinalSingletonsingleton=newSingleton();
//将类的构造函数定义为私有的,以避免被其他类new出来一个对象。
privateSingleton(){}
//设置一个静态成员函数getInstance(),用于返回对象本身。
publicstaticSingletongetInstance()
{
returnsingleton;
}
publicstaticvoiddoSomething(){/*dosomething…*/}
}
//高层调用类
publicclassClient
{
publicstaticvoidmain(String[]args)
{
//不是通过new来的,而是通过Singleton.getInstance()来的
Singletonsingleton=Singleton.getInstance();
singleton.doSomething();
}
}
优点:
节省资源、可以做全局变量使用。
缺点:
没有实现接口扩展困难、可能会导致并发性问题。
注意:
单例对象不要实现Cloneable接口。
Spring框架中的每个Bean默认都是单例的,由Spring容器管理Bean生命期,并可以避免并发性问题。
(二)工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化的是哪一个接口实现类。
//抽象产品类
publicabstractclassAbstractProduct
{
publicabstractvoidmethod(){}
}
//具体产品1
publicclassProduct1extendsAbstractProduct
{
@override
publicvoidmethod(){System.out.println(“我是产品1”);}
}
//具体产品2
publicclassProduct2extendsAbstractProduct
{
@override
publicvoidmethod(){System.out.println(“我是产品2”);}
}
//抽象工厂类
publicabstractclassAbstractFactory
{
//可创建所有从AbstractProduct继承的产品
publicabstractTcreateProduct(Classc);
}
//具体工厂类
publicclassFactoryextendsAbstractFactory
{
@override
publicTcreateProduct(Classc)
{
//如果不用反射,也可向工厂方法传入参数,根据参数通过if来分别创建不同产品的对象
//但如果不用反射,则每增加一种具体产品,均需要修改具体工厂类
AbstractProductproduct=(AbstractProduct)Class.forName(c.getName).newInstance();
return(T)product;
}
}
//高层调用类
publicclassClient
{
publicstaticvoidmain(String[]args)
{
//不是通过new来的,而是通过Singleton.getInstance()来的
AbstractFactoryfactory=newFactory();
AbstractProductproduct1=factory.createProduct(Product1.class);
AbstractProductproduct2=factory.createProduct(Product2.class);
product1.method();
product2.method();
}
}
输出结果:
-----------------
我是产品1
我是产品2
-----------------
变化:
可将Factory扩展为Factory1和Factory2,内部只是简单的returnnewProduct1();和returnnewProduct2();。
就变成多工厂模式,每个工厂只创建一种具体类的对象,具体类的数量与工厂类的数量相等。
(三)抽象工厂模式
抽象工厂模式是对工厂方法模式的升级,每个工厂类中有多个工厂方法。
适用于“产品族→产品型号”的结构,有多少个产品族则工厂类中就有多少个工厂方法,有多少产品型号就有多少个具体工厂类。
//抽象产品族A
publicabstractclassAbstractProductA
{
publicabstractvoidmethod(){}
}
//产品族A的具体产品1
publicclassProductA1extendsAbstractProductA
{
@override
publicvoidmethod(){System.out.println(“我是产品A1”);}
}
//产品族A的具体产品2
publicclassProductA2extendsAbstractProductA
{
@override
publicvoidmethod(){System.out.println(“我是产品A2”);}
}
//产品族B及其具体产品类似,不再赘述。
。
。
//抽象工厂类,有几个产品族,就需要有几个工厂方法
publicabstractclassAbstractFactory
{
//创建产品族A的工厂方法
publicabstractAbstractProductAcreateProductA();
//创建产品族B的工厂方法
publicabstractAbstractProductBcreateProductB();
}
//有几个产品型号,就需要有几个具体工厂类
//具体工厂类1
publicclassFactory1extendsAbstractFactory
{
//创建产品族A的工厂方法
@override
publicAbstractProductAcreateProductA()
{
returnnewProductA1();
}
//创建产品族B的工厂方法
@override
publicAbstractProductBcreateProductB()
{
returnnewProductB1();
}
}
//具体工厂类2
publicclassFactory2extendsAbstractFactory
{
//创建产品族A的工厂方法
@override
publicAbstractProductAcreateProductA()
{
returnnewProductA2();
}
//创建产品族B的工厂方法
@override
publicAbstractProductBcreateProductB()
{
returnnewProductB2();
}
}
//高层调用类
publicclassClient
{
publicstaticvoidmain(String[]args)
{
//不是通过new来的,而是通过Singleton.getInstance()来的
AbstractFactoryfactory1=newFactory1();
AbstractFactoryfactory2=newFactory2();
AbstractProductAproductA1=factory1.createProductA;
AbstractProductAproductA2=factory1.createProductA;
AbstractProductBproductB1=factory1.createProductB;
AbstractProductBproductB2=factory1.createProductB;
productA1.method();
productA2.method();
productB2.method();
productB2.method();
}
}
输出结果:
-----------------
我是产品A1
我是产品A2
我是产品B1
我是产品B2
-----------------
优点:
产品型号扩展简单,只需要增加一个新的具体工厂实现类即可。
缺点:
产品族扩展困难,需要对抽象工厂和每个具体工厂实现类增加方法。
(四)模板模式
模板模式其实就是利用抽象类的继承。
由抽象类定义出方法行为接口,并通过抽象类中的具体方法将通用的行为顺序实现,避免在实现类中编写重复代码。
//抽象产品类,这是一个产品模板
publicabstractclassAbstractProduct
{
//产品的基本行为方法接口,由于并不提供给高层模块调用,因此使用protected类型
protectedabstractvoidmethod1();
protectedabstractvoidmethod2();
//产品模板的具体实现类,用于绑定相同的行为顺序,为了防止被覆盖,所以加上final
publicabstractfinalvoidmethod();
{
this.method1();
this.method2();
}
}
//具体产品实现类,只需要实现每种产品的基本行为方法,行为的执行顺序已由模板类提供
publicclassProdut1extendsAbstractProduct
{
@override
protectedvoidmethod1(){System.out.println(“产品1做行为1”);}
@override
protectedvoidmethod2(){System.out.println(“产品1做行为2”);}
}
publicclassProdut2extendsAbstractProduct
{
@override
protectedvoidmethod1(){System.out.println(“产品2做行为1”);}
@override
protectedvoidmethod2(){System.out.println(“产品2做行为2”);}
}
//高层调用类
publicclassClient
{
publicstaticvoidmain(String[]args)
{
//不是通过new来的,而是通过Singleton.getInstance()来的
AbstractProductproduct1=newProduct1();
AbstractProductproduct2=newProduct1();
System.out.println(“产品1开始做动作…”);
product1.method();//调用模板方法,按顺序执行行为
System.out.println(“产品2开始做动作…”);
product2.method();//调用模板方法,按顺序执行行为
}
}
输出结果:
-----------------
产品1开始做动作…
产品1做行为1
产品1做行为2
产品2开始做动作…
产品2做行为1
产品2做行为2
-----------------
优点:
把不变的算法封装到父类,避免代码拷贝,便于维护。
缺点:
行为顺序在父类中,不太好理解,且具体产品的行为顺序一旦改变,父类的模板方法将无法再使用,需要在子类中覆盖父类的方法,子类将变得“有个性”。
(五)建造模式
工厂模式只是简单返回一个类的对象,主要用于替代new。
相对于工厂模式来说,建造模式不但生成一个对象,同时对对象的细节按顺序进行装配,使之丰满。
//具体产品类,为省略篇幅,忽略了抽象产品类
publicclassProduct
{
privateStringpart1;
privateStringpart2;
/*成员变量的getter和setter方法略*/
}
//抽象建造者类
publicabstractclassAbstractBuilder
{
//对产品零件进行细节设置的方法,方法个数按需编写
publicabstractvoidsetPart1();
publicabstractvoidsetPart2();
//建造者将产品成品返回的方法
publicabstractProductgetProduct();
}
//具体建造者类
publicclassBuilderextendsAbstractBuilder
{
//生成一个空产品,此处用new,也可使用工厂方法
privateProductproduct=newProduct();
//对产品零件进行装配,使空产品变得丰满
@override
publicvoidsetPart1(StringpartName)
{
product.setPart1(partName);
System.out.println(“产品零件1本次使用的型号是:
”+partName);
}
@override
publicvoidsetPart1(StringpartName)
{
product.setPart1(partName);
System.out.println(“产品零件2本次使用的型号是:
”+partName);
}
//将成品返回
@override
publicProductgetProduct()
{
returnproduct;
}
}
//经理类(工头类,导演类),用于封装建造顺序,避免高层模块与建造者耦合打乱建造顺序
//高层模块相当于客户,经理类相当于项目经理,建造者相当于程序员,客户自然是不适合与程序员直接沟通的,需要项目经理充当对接通道
publicclassManager
{
//声明建造者,有了经理自然要给经理分配个小弟
privateAbstractBuilderbuilder=newBuilder();
//经理可以指导建造者建造两种型号的产品,具体型号数量可根据实际情况决定
publicProductgetProductA()
{
System.out.println(“开始建造产品A…”);
builder.setPart1(“主板A”);
builder.setPart2(“芯片A”);
returnbuilder.getProduct();
}
publicProductgetProductB()
{
System.out.println(“开始建造产品B…”);
builder.setPart1(“主板B”);
builder.setPart2(“芯片B”);
returnbuilder.getProduct();
}
}
//高层调用类(客户类)
publicclassClient
{
publicstaticvoidmain(String[]args)
{
//客户只需要与经理打交道
Managermanager=newManager();
//客户只要结果,并不知道经理的小弟是谁,也不知道是怎么建造的
ProductproductA=manager.getProductA();
ProductproductB=manager.getProductB();
}
}
输出结果:
-----------------
开始建造产品A…
产品零件1本次使用的型号是:
主板A
产品零件2本次使用的型号是:
芯片A
开始建造产品B…
产品零件1本次使用的型号是:
主板B
产品零件2本次使用的型号是:
芯片B
-----------------
优点:
适合建造复杂对象,却对高层模块屏蔽建造细节。
(六)原型模式
在java中,类实现Cloneable接口,并覆盖clone()方法,创建对象时即可通过拷贝的方式来创建,这就是原型模式。
//具体产品类,实现了Cloneable接口,为省略篇幅,忽略了抽象产品类
publicclassProductimplementsCloneable
{
//覆盖clone方法,使对象可以拷贝
@Override
publicProductclone()
{
Productproduct=(Product)super.clone();
returnproduct;
}
//产品的普通方法
publicvoidmethod(){System.out.println(“我被复制出来了!
”);}
}
//高层调用类
publicclassClient
{
publicstaticvoidmain(String[]args)
{
System.out.println(“先初始化原型产品…”);
//初始化一个原型产品
ProductproductProtoType=newProduct();
//通过原型产品克隆出5个产品
for(inti=0;i<5;++i)
{
System.out.print(“克隆出第”+i+“个产品:
”);
Productproduct=productProtoType.clone();
product.method();
}
}
}
输出结果:
-----------------
先初始化原型产品…
克隆出第1个产品:
我被复制出来了!
克隆出第2个产品:
我被复制出来了!
克隆出第3个产品:
我被复制出来了!
克隆出第4个产品:
我被复制出来了!
克隆出第5个产品:
我被复制出来了!
-----------------
优点:
对象生成性能比new来的快得多,不执行构造函数逃避约束。
注意:
浅拷贝和深拷贝的问题,并且类的成员变量不要加final,否则无法拷贝。
原型模式一般和工厂模式一起使用,在工厂方法内采用原型模式生成对象。