设计模式(总结)---创建型设计模式

来源:互联网 发布:青岛开创盛世网络 编辑:程序博客网 时间:2024/05/17 02:29

创建型设计模式:
简单工厂模式:
当代吗使用具体类时,一旦加入新的具体类,就必须要改变代码。我们希望在生成对象的时候,不使用new+具体类的名称,而是希望调用一个简单的方法,传递一个参数过去,就可以返回一个具体的对象。
简单例子的类图如下
这里写图片描述
如图所示,相比于原来,如果要提供四种pizza对象,用户需要知道内部四个类的名称进行创建,如果类的名称修改,客户的程序将无法运行正常。而采取简单工厂模式的耦合只有一个方法。

工厂方法模式:
又称之为虚拟构造器,父类负责定义创建类的公共接口,子类负责生成具体对象。
以上述例子为例,制作pizza对象只有simplypizzafactory负责。但是如果要实现制作pizza对象的的不同流程,就需要新增工厂。
假设用户在上面的例子中需要新加对象的产生流程,在不修改源代码的情况下,可以在原来的代码中添加新的工厂。这便是工厂方法模式。
这里写图片描述
注意,用户如果想要生成pizza对象,需要先生成工厂对象,再按照工厂对象所遵循的抽象接口生成pizza对象。所以耦合度为工厂的类的名称和工厂所遵循的抽象接口。

抽象工厂模式
如果在工厂模式下,需要添加一种新的抽象产品,比如说除了pizza还要售卖Hotdog,工厂方法仍然避免如果完全新增一种抽象产品的修改。所以采用抽象工厂法
继承于同一个抽象产品的被称之为产品等级结构,由同一个抽象工厂生产的产品被称之为产品族。如果每个产品族只有一个产品,则退回到工厂方法
这里写图片描述

原型模式
利用已经存在的对象创建新的对象
在java中,只有实现了cloneable的接口才可以被拷贝。
原型模式的好处式简化了对象的创建,实现了对对象的赋值粘贴。而且采用clone要比new的执行效率高。

class Prototype implements Cloneable {    public Prototype clone(){        Prototype prototype = null;        try{            prototype = (Prototype)super.clone();        }catch(CloneNotSupportedException e){            e.printStackTrace();        }        return prototype;     }}class ConcretePrototype extends Prototype{    public void show(){        System.out.println("原型模式实现类");    }}public class Client {    public static void main(String[] args){        ConcretePrototype cp = new ConcretePrototype();        for(int i=0; i< 10; i++){            ConcretePrototype clonecp = (ConcretePrototype)cp.clone();            clonecp.show();        }    }}

注意一些问题,首先,java的克隆是在object类中实现的,不会调用构造函数,值会自动克隆,也就是浅拷贝。如果要实现深拷贝,必须在上述例子中的clone函数手动添加。
由于clone函数在object中是protected,所以如果不使用重载将clone方法的权限改成public,将无法实现拷贝

单例模式
对于某些对象,我们只需要一个,如果产生多个会出现很多问题。
单例模式可以保证一个类只有一个实例而且便于访问。如果采用全局变量可以便于访问,但仍然无法避免该类只被创建一次
有如下三种实现方案:
(1)利用静态变量记录

public class Singleton {    //利用静态变量来记录Singleton的唯一实例    private static Singleton uniqueInstance;    /*     * 构造器私有化,只有Singleton类内才可以调用构造器     */    private Singleton(){    }    public static synchronized Singleton getInstance(){        if(uniqueInstance == null){            uniqueInstance = new Singleton();        }        return uniqueInstance;    }}

首先第一步,构造器必须被私有化。

(2)直接初始化静态变量
public class Singleton {
/*
* 利用静态变量来记录Singleton的唯一实例
* 直接初始化静态变量,这样就可以确保线程安全了(静态变量在第一次被加载时唯一被初始化)
*/
private static Singleton uniqueInstance = new Singleton();

/* * 构造器私有化,只有Singleton类内才可以调用构造器 */private Singleton(){}public static Singleton getInstance(){    return uniqueInstance;}

}
(3)双重加锁,使用同步

public class Singleton {    /*     * 利用静态变量来记录Singleton的唯一实例     * volatile 关键字确保:当uniqueInstance变量被初始化成Singleton实例时,     * 多个线程正确地处理uniqueInstance变量     *      */    private volatile static Singleton uniqueInstance;    /*     * 构造器私有化,只有Singleton类内才可以调用构造器     */    private Singleton(){    }    /*     *      * 检查实例,如果不存在,就进入同步区域     */    public static Singleton getInstance(){        if(uniqueInstance == null){            synchronized(Singleton.class){    //进入同步区域                if(uniqueInstance == null){     //在检查一次,如果为null,则创建                    uniqueInstance  = new Singleton();                }            }        }        return uniqueInstance;    }}

单例模式封装了唯一的实例,还可以添加代码更加唯一的控制客户如何进行访问。
缺点是单例模式可能会被滥用。

建造者模式
建造者模式将一个复杂对象的构建和他的表示分离。和工厂模式类似,只不过工厂说模式侧重于产生不同的产品,而建造者模式侧重于产生相同产品的不同流程。适用于创建对象时的算法复杂的情况。

#include <iostream>#include <vector>#include <string>using namespace std;//Product类class Product{    vector<string> parts;public:    void Add(const string part)    {        parts.push_back(part);    }    void Show()const    {        for(int i = 0 ; i < parts.size() ; i++)        {            cout<<parts[i]<<endl;        }    }};//抽象builder类class Builder{public:    virtual void BuildHead() = 0;    virtual void BuildBody() = 0;    virtual void BuildHand() = 0;    virtual void BuildFeet() = 0;    virtual Product GetResult() = 0; };//具体胖人创建类class FatPersonBuilder :public Builder{private:    Product product;public:    virtual void BuildHead()    {        product.Add("胖人头");//创建瘦人的头    }    virtual void BuildBody()    {        product.Add("胖人身体");//创建瘦人的身体    }    virtual void BuildHand()    {        product.Add("胖人手");//创建瘦人的手    }    virtual void BuildFeet()    {        product.Add("胖人脚");//创建瘦人的脚    }    virtual Product GetResult()    {        return product;    }};//具体瘦人人创建类class ThinPersonBuilder :public Builder{private:    Product product;public:    virtual void BuildHead()    {        product.Add("瘦人人头");//创建瘦人的头    }    virtual void BuildBody()    {        product.Add("瘦人身体");//创建瘦人的身体    }    virtual void BuildHand()    {        product.Add("瘦人手");//创建瘦人的手    }    virtual void BuildFeet()    {        product.Add("瘦人脚");//创建瘦人的脚    }    virtual Product GetResult()    {        return product;    }};//Director类class Director{public:    void Construct(Builder &builder)    {        builder.BuildHead();        builder.BuildBody();        builder.BuildHand();        builder.BuildFeet();    }};int main(){    Director *director = new Director();    Builder *b1 = new FatPersonBuilder();    Builder *b2 = new ThinPersonBuilder();    director->Construct(*b1);    Product p1 = b1->GetResult();    p1.Show();     return 0;}

将如上代码汇之味类图为
这里写图片描述

0 0
原创粉丝点击