设计模式学习笔记-创建型模式

设计模式学习笔记-创建型模式,第1张

设计模式学习笔记-创建型模式
  • Factory 模式
  • AbstactFactory 模式
  • Singleton 模式
  • Builder 模式
  • Prototype(原型) 模式

Factory 模式

Product.h

#pragma once
class Product
{
public:
	Product();
	~Product();
};

class ConcertProduct1 :public Product
{
public:
	ConcertProduct1();
	~ConcertProduct1();
};

class ConcertProduct2 :public Product
{
public:
	ConcertProduct2();
	~ConcertProduct2();
};

Product.cpp

#include "Product.h"
#include 
using namespace std;

Product::Product()
{
}


Product::~Product()
{
}

ConcertProduct1::ConcertProduct1()
{
	cout << "特别产品1" << endl;
}

ConcertProduct1::~ConcertProduct1()
{
}

ConcertProduct2::ConcertProduct2()
{
	cout << "特别产品2" << endl;
}

ConcertProduct2::~ConcertProduct2()
{
}

Factory.h

#pragma once

class Product;

class Factory
{
public:
	Factory();
	~Factory();

	virtual Product* CreateProduct1() = 0;
	virtual Product* CreateProduct2() = 0;
};

class ConcreteFactory :public Factory
{
public:
	ConcreteFactory();
	~ConcreteFactory();

	Product* CreateProduct1();
	Product* CreateProduct2();
};

Factory.cpp

#include "Factory.h"
#include "Product.h"
#include 
using namespace std;


Factory::Factory()
{
}


Factory::~Factory()
{
}

ConcreteFactory::ConcreteFactory()
{
	cout << "特殊工厂" << endl;
}

ConcreteFactory::~ConcreteFactory()
{
}

Product * ConcreteFactory::CreateProduct1()
{
	cout << "生产1:";
	return new ConcertProduct1();
}

Product * ConcreteFactory::CreateProduct2()
{
	cout << "生产2:";
	return new ConcertProduct2();;
}

main.cpp

#include 
#include 

#include "Factory.h"
#include "Product.h"

using namespace std;
int main(int argc,char* argv[])
{
	Factory* fac = new ConcreteFactory();

	Product* apro1 = fac->CreateProduct1();
	Product* apro2 = fac->CreateProduct2();

	Product* bpro1 = new ConcertProduct1();
	Product* bpro2 = new ConcertProduct2();
	/*new ×××;的两个问题
 		1)客户程序员必须知道实际子类的名称(当系统复杂后,命名将是一个很不好处理的问题,为了
 		处理可能的名字冲突,有的命名可能并不是具有很好的可读性和可记忆性,就姑且不论不同
 		程序员千奇百怪的个人偏好了。


) 2)程序的扩展性和维护变得越来越困难。


*/ system("pause"); return 0; }

特殊工厂
生产1:特别产品1
生产2:特别产品2
特别产品1
特别产品2
请按任意键继续. . .

通过“工厂”生产“产品”,避免自己new对象
Factory 模式的两个最重要的功能:
1)定义创建对象的接口,封装了对象的创建。



这样我们可以通过声明一个指向基类的指针来指向实际的子类实现,达到了多态的目的
2)使得具体化类的工作延迟到了子类中。



解决父类中并不知道具体要实例化哪一个具体的子类的问题

Factory 模式的问题
1)当新增加一种product时,就需要新添加一个方法,Factory 的接口永远就不能封闭(Close)。


当然我们可以通过重新创建一个 Factory 的子类来通过多态实现这一点(重新实现新product的生产方法),但是这也是以新建一个类作为代价的。



2)参数化工厂方法:传递一个参数用以决定是创建具体哪一个具体的 Product。



此方法可以避免1)中的子类创建子类
但局限于一类类(就是说 Product 必须是一类,有一个共同的基类)
如果我们要为不同类的类提供一个对象创建的接口,那就要用 AbstractFactory 了。


AbstactFactory 模式

AbstactProductA.h

#pragma once
class AbstactProductA
{
public:
	AbstactProductA();
	~AbstactProductA();
};

class ProductA1 :public AbstactProductA
{
public:
	ProductA1();
	~ProductA1();
};

class ProductA2 :public AbstactProductA
{
public:
	ProductA2();
	~ProductA2();
};

AbstactProductA.cpp

#include "AbstactProductA.h"
#include 
using namespace std;


AbstactProductA::AbstactProductA()
{
}


AbstactProductA::~AbstactProductA()
{
}

ProductA1::ProductA1()
{
	cout << "丘丘人-低级" << endl;
}

ProductA1::~ProductA1()
{
}

ProductA2::ProductA2()
{
	cout << "丘丘人-高级" << endl;
}

ProductA2::~ProductA2()
{
}

AbstactProductB.h

#pragma once
class AbstactProductB
{
public:
	AbstactProductB();
	~AbstactProductB();
};

class ProductB1 :public AbstactProductB
{
public:
	ProductB1();
	~ProductB1();
};

class ProductB2 :public AbstactProductB
{
public:
	ProductB2();
	~ProductB2();
};

AbstactProductB.cpp

#include "AbstactProductB.h"
#include 
using namespace std;


AbstactProductB::AbstactProductB()
{
}


AbstactProductB::~AbstactProductB()
{
}

ProductB1::ProductB1()
{
	cout << "遗迹重机-低级" << endl;
}

ProductB1::~ProductB1()
{
}

ProductB2::ProductB2()
{
	cout << "遗迹重机-高级" << endl;
}

ProductB2::~ProductB2()
{
}

AbstactFactory.h

#pragma once

class AbstactProductA;
class AbstactProductB;

class AbstactFactory
{
public:
	AbstactFactory();
	~AbstactFactory();

	virtual AbstactProductA* CreateProductA() = 0;
	virtual AbstactProductB* CreateProductB() = 0;
};

class ConceateFactory1 :public AbstactFactory
{
public:
	ConceateFactory1();
	~ConceateFactory1();

	AbstactProductA* CreateProductA();
	AbstactProductB* CreateProductB();
};

class ConceateFactory2 :public AbstactFactory
{
public:
	ConceateFactory2();
	~ConceateFactory2();

	AbstactProductA* CreateProductA();
	AbstactProductB* CreateProductB();
};

AbstactFactory.cpp

#include "AbstactFactory.h"
#include "AbstactProductA.h"
#include "AbstactProductB.h"
#include 
using namespace std;


AbstactFactory::AbstactFactory()
{
}


AbstactFactory::~AbstactFactory()
{
}

ConceateFactory1::ConceateFactory1()
{
	cout << "低级:" << endl;
}

ConceateFactory1::~ConceateFactory1()
{
}

AbstactProductA * ConceateFactory1::CreateProductA()
{
	return new ProductA1();
}

AbstactProductB * ConceateFactory1::CreateProductB()
{
	return new ProductB1();
}

ConceateFactory2::ConceateFactory2()
{
	cout << "高级:" << endl;
}

ConceateFactory2::~ConceateFactory2()
{
}

AbstactProductA * ConceateFactory2::CreateProductA()
{
	return new ProductA2();
}

AbstactProductB * ConceateFactory2::CreateProductB()
{
	return new ProductB2();
}

main.cpp

#include 
using namespace std;

#include "AbstactFactory.h"
#include "AbstactProductA.h"
#include "AbstactProductB.h"

int main(int argc,char* argv[])
{
	AbstactFactory* fac1 = new ConceateFactory1();

	AbstactProductA* apro = fac1->CreateProductA();
	AbstactProductB* bpro = fac1->CreateProductB();

	fac1 = new ConceateFactory2();

	apro = fac1->CreateProductA();
	bpro = fac1->CreateProductB();
	
	system("pause");
	return 0;
}
低级:
丘丘人-低级
遗迹重机-低级
高级:
丘丘人-高级
遗迹重机-高级
请按任意键继续. . .

依然是通过“工厂”生产“产品”,但增加了“产品”的种类,例如原来工厂只生产各种各样的t恤,但现在的工厂还可以生产各种各样的牙刷。








同时也可以增加低级和高级工厂生产管理对应的低级和高级t恤和牙刷。



抽象工厂模式相较于工厂模式(抽象工厂模式是对工厂模式的扩展)
AbstractFactory 模式通常都是使用 Factory 模式实现
AbstractFactory 模式是为创建一组(有多类)相关或依赖的对象提供创建接口
Factory 模式是为一类对象提供创建接口或延迟对象的创建到子类中实现

Singleton 模式

Singleton.h

#pragma once
class Singleton
{
public:
	static Singleton* Instance();

	~Singleton();

	void DoSomething();
private:
	Singleton();

private:
	static Singleton* _instance;
};

Singleton.cpp

#include "Singleton.h"
#include 
using namespace std;

Singleton* Singleton::_instance = 0;

Singleton * Singleton::Instance()
{
	if (_instance==0)
	{
		_instance = new Singleton();
	}
	return _instance;
}

Singleton::Singleton()
{
	cout << "单例被创建" << endl;
}


Singleton::~Singleton()
{
}

void Singleton::DoSomething()
{
	cout << "单例作用" << endl;
}

main.cpp

#include 
using namespace std;

#include "Singleton.h"

int main(int argc,char* argv[])
{
	Singleton* agn = Singleton::Instance();

	Singleton::Instance()->DoSomething();
	/*需要说明的是,Singleton 不可以被实例化,因此
		我们将其构造函数声明为 protected 或者直接声明为 private。


*/ system("pause"); return 0; }

单例被创建
单例作用
请按任意键继续. . .

单例模式生产的“产品”是全局唯一的,适合实现一些全局数据存取,比如配置信息等
当我们在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。



单例模式也分饿汉式和懒汉式两种,
懒汉式 是在真正需要使用对象时才去创建该单例类对象
饿汉式 是在类加载时已经创建好该单例对象,等待被程序使用
在这里实现的是没有考虑线程安全的懒汉式单例模式,推荐使用饿汉式。



饿汉式
Singleton.h

#pragma once
class Singleton
{
public:
	static Singleton getInstance() {
        return singleton;
    }

	~Singleton();

	void DoSomething();
private:
	Singleton();

private:
	static final Singleton instance = new Singleton();
};
Builder 模式

Product.h

#pragma once
class Product
{
public:
	Product();
	~Product();

	void ProductPart();
};

class ProductPart
{
public:
	ProductPart();
	~ProductPart();

	ProductPart* BuildPart();
};

Product.cpp

#include "Product.h"



Product::Product()
{
}


Product::~Product()
{
}

void Product::ProductPart()
{
}

ProductPart::ProductPart()
{
}

ProductPart::~ProductPart()
{
}

ProductPart * ProductPart::BuildPart()
{
	return nullptr;
}

Builder.h

#pragma once

#include "Product.h"
#include 
using namespace std;

class Product;

class Builder
{
public:
	Builder();
	~Builder();

	virtual void BuildPartA(const string& buildPara) = 0;
	virtual void BuildPartB(const string& buildPara) = 0;
	virtual void BuildPartC(const string& buildPara) = 0;

	virtual Product* GetProduct() = 0;
};

class ConcreteBuilder :public Builder
{
public:
	ConcreteBuilder();
	~ConcreteBuilder();
	void BuildPartA(const string& buildPara);
	void BuildPartB(const string& buildPara);
	void BuildPartC(const string& buildPara);
	Product* GetProduct();
};

Builder.cpp

#include "Builder.h"
#include "Product.h"
#include 
using namespace std;

Builder::Builder()
{
}


Builder::~Builder()
{
}

ConcreteBuilder::ConcreteBuilder()
{
}

ConcreteBuilder::~ConcreteBuilder()
{
}

void ConcreteBuilder::BuildPartA(const string & buildPara)
{
	cout << "Step1:Build PartA..." << buildPara << endl;
}

void ConcreteBuilder::BuildPartB(const string & buildPara)
{
	cout << "Step1:Build PartB..." << buildPara << endl;
}

void ConcreteBuilder::BuildPartC(const string & buildPara)
{
	cout << "Step1:Build PartC..." << buildPara << endl;
}

Product * ConcreteBuilder::GetProduct()
{
	BuildPartA("pre-defined");
	BuildPartB("pre-defined");
	BuildPartC("pre-defined");
	return new Product();
}

Director.h

#pragma once

class Builder;
class Director
{
public:
	Director(Builder* bld);
	~Director();

	void Construct();

private:
	Builder* _bld;
};

Director.cpp

#include "Director.h"
#include "Builder.h"

Director::Director(Builder * bld)
{
	_bld = bld;
}

Director::~Director()
{
}

void Director::Construct()
{
	_bld->BuildPartA("user-defined");//这里的user-defined实际可能由是在 Construct 方法中传入这 3 个参数
	_bld->BuildPartB("user-defined");
	_bld->BuildPartC("user-defined");

	/*Builder 模式的关键是其中的 Director 对象并不直接返回对象,而是通过一步步
	(BuildPartA,BuildPartB,BuildPartC)来一步步进行对象的创建。


当然这里 Director 可以提供一个默认的返回对象的接口 (返回通用的复杂对象的创建,即不指定或者特定唯一指 定 BuildPart 中的参数)。


*/ }

main.cpp

#include 
using namespace std;

#include "Builder.h" 
#include "Product.h" 
#include "Director.h"

int main(int argc,char* argv[])
{
	Director* d = new Director(new ConcreteBuilder());
	d->Construct();
	
	system("pause");
	return 0;
}
Step1:Build PartA...user-defined
Step1:Build PartB...user-defined
Step1:Build PartC...user-defined
请按任意键继续. . .

新建监督者对象,给他一个新建的建造者,让他监督建造者生产产品的各个步骤

Builder 模式要解决的问题:当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成(超出了构造函数所能包含的范围)),
我们要把复杂对象的创建过程和这个对象的表示(展示)分离开来,这样做的好处就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样
即将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。


比较 AbstractFactory 模式中对象是直接返回的,强调的是为创建多个相互依赖的对象提供一个统一的接口

优点
(1)良好的封装性, 使用建造者模式可以使客户端不必知道产品内部组成的细节;
(2)建造者独立,容易扩展;
(3)在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。


缺点
(1)会产生多余的Builder对象以及Director对象,消耗内存;
(2)对象的构建过程暴露。


Prototype(原型) 模式

Prototype.h

#pragma once
class Prototype
{
public:
	~Prototype();
	virtual Prototype* Clone() const = 0;

protected:
	Prototype();
};

class ConcretePrototype :public Prototype
{
public:
	ConcretePrototype();
	ConcretePrototype(const ConcretePrototype& cp);
	~ConcretePrototype();
	Prototype* Clone() const;
};

Prototype.cpp

#include "Prototype.h"
#include 
using namespace std;


Prototype::Prototype()
{
}


Prototype::~Prototype()
{
}

Prototype * Prototype::Clone() const
{
	return nullptr;
}

ConcretePrototype::ConcretePrototype()
{
}

ConcretePrototype::ConcretePrototype(const ConcretePrototype & cp)
{
	cout << "ConcretePrototype copy ..."<<endl;
}

ConcretePrototype::~ConcretePrototype()
{
}

Prototype * ConcretePrototype::Clone() const
{
	return new ConcretePrototype(*this);
}

main.cpp

#include 
using namespace std;

#include "Prototype.h"

int main(int argc,char* argv[])
{
	Prototype* p = new ConcretePrototype();
	Prototype* p1 = p->Clone();

	system("pause");
	return 0;
}
ConcretePrototype copy ...
请按任意键继续. . .

不根据类来生成实例,而是根据实例来生成新实例
通过复制原型(Prototype)而获得新对象创建的功能,这里 Prototype 本身就是“对象工厂”(因为能够生产对象)

实际上 Prototype 模式和 Builder 模式、AbstractFactory 模式都是通过一个类(对象实例)来专门负责对象的创建工作(工厂对象)
区别是:
Builder 模式重在复杂对象的一步步创建(并不直接返回对象),
AbstractFactory 模式重在产生多个相互依赖类的对象,
Prototype 模式重在从自身复制自己创建新类。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/563947.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-03
下一篇 2022-04-03

发表评论

登录后才能评论

评论列表(0条)

保存