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

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

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

抽象工厂模式
如果在工厂模式下,需要添加一种新的抽象产品,比如说除了pizza还要售卖Hotdog,工厂方法仍然避免如果完全新增一种抽象产品的修改。所以采用抽象工厂法
继承于同一个抽象产品的被称之为产品等级结构,由同一个抽象工厂生产的产品被称之为产品族。如果每个产品族只有一个产品,则退回到工厂方法
设计模式(总结)---创建型设计模式_第3张图片

原型模式
利用已经存在的对象创建新的对象
在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;
}

将如上代码汇之味类图为
设计模式(总结)---创建型设计模式_第4张图片

你可能感兴趣的:(设计模式(总结)---创建型设计模式)