[设计模式学习笔记二][创建型模式][工厂方法(Factory Method)]

本文是我学习刘伟技术博客的笔记,博客链接如下:

http://blog.csdn.net/lovelion/article/details/17517213

我做的这部分笔记,鉴于自身水平有限,我只是对上面博客内做进一步提炼和记录,方便自己查阅。同时,更多的是对设计模式的框架进行学习,大部分细节都将略去,让自己侧重对每个设计模式框架的理解。

我应该理解和掌握的:

1)能够画出这个设计模式的架构框图;

2)能够根据架构框图写出对应的伪代码;

3)这个模式的应用场景,主要优缺点。

1.简单工厂

(1)定义

简单工厂不属于GoF 23个经典设计模式,这里为了引入工厂方法,抽象工厂做准备。

简单工厂模式定义:给定一个工厂类,它将根据传进来的不同参数返回不同类的实例,被创建的实例通常有共同的父类。简单工厂模式中用于创建实例的方法是静态方法,故又称静态工厂方法。

下面是结构图,具体代码将不再贴出,由框架自己在联想代码怎么设计以及每个类的作用:

结构图的伪代码如下:
enum ProductId
{
	PRODUCTA,
	PRODUCTB,
	MAX,
};

class product //抽象产品类
{
public:
	virtual void display();
};

class ConcreteProductA:public product //具体产品类A
{
public:
	void display();
};
void ConcreteProductA::display()
{
	log("display ConcreteProductA");
}

class ConcreteProductB:public priduct  //具体产品类B
{
public:
	void display();
};
void ConcreteProductB::display()
{
	log("display ConcreteProductB");
}

class Factory //抽象工厂类
{
public:
	virtual product* Create(ProductId id); 
};

class ConcreteFactory:public Factory //具体工厂类
{
public:
	product* Create(ProductId id);
};
product* ConcreteFactory::Create(ProductId id)
{
	if(id == PRODUCTA)
	{
		return new ConcreteProductA();
	}
	else if(id == PRODUCTB)
	{
		return new ConcreteProductB();
	}
	else 
	{
		...
	}
}
//客户端如下
int main()
{
	Product pd = NULL;
	pd = ConcreteFactory.Create(PRODUCTB);//创建ConcreteProductB
	pd.display();
	return 0;
}

(2)总结

1)工厂类包含必要的逻辑判断,同时也表明承担的职责过重,违反单一原则;
2)系统扩展困难,一旦添加产品必须修改工厂类的逻辑,不利于扩展和维护。

(3)适用场景

1)工厂类负责创建的对象比较少;
2)客户端只知道传入工厂类的参数,不关心如何创建。

2.工厂方法

在简单工厂模式中,如要要增加一个产品类,则需要修改工厂类的创建方法,违背了开闭原则。在工厂方法中,不再提供一个统一的工厂类来创建所有的产品对象,针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级结构

(1)定义

工厂方法:定义一个用于创建产品的接口或基类,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法又称工厂模式。

它的结构图如下:


1)Product:定义工厂方法所创建的对象的接口;
2)ConcreteProduct:实现Product接口;
3)Fractory:声明工厂方法,返回一个Product类型对象;
4)ConcreteFactory:重定义工厂方法以返回一个ConcreteProduct对象。

以上架构框结构图的伪代码如下,Product部分和简单工厂代码一样:

class Factory //抽象工厂类
{
public:
	virtual product* Create(); 
};

class ConcreteFactoryA:public Factory //具体工厂类A
{
public:
	product* Create();
};
product* ConcreteFactoryA::Create()
{
	return new ConcreteProductA();
}

class ConcreteFactoryB:public Factory //具体工厂类B
{
public:
	product* Create();
};
product* ConcreteFactoryB::Create()
{
	return new ConcreteProductB();
}

//客户端如下
int main()
{
	Product pdA = NULL;
	pdA = ConcreteFactoryA.Create();//创建ConcreteProductA
	pdA.display();

	Product pdB = NULL;
	pdB = ConcreteFactoryB.Create();//创建ConcreteProductB
	pdB.display();
	return 0;
}

下面再来看一个工厂方法的隐藏,客户端无需调用工厂方法创建产品,直接通过工厂既可以使用所创建的对象中的业务方法:


结构图的伪代码如下,Product部分和简单工厂代码一样:
class Factory //抽象工厂类
{
public:
	virtual product* Create();
	void display(); //product 方法
};
void Factory::display()  //product 方法
{
	Product pd = this.Create(); //由子类创建
	pd.display();
}

class ConcreteFactoryA:public Factory //具体工厂类A
{
public:
	product* Create();
};
product* ConcreteFactoryA::Create()
{
	return new ConcreteProductA();
}

class ConcreteFactoryB:public Factory //具体工厂类B
{
public:
	product* Create();
};
product* ConcreteFactoryB::Create()
{
	return new ConcreteProductB();
}

(2)总结

1)工厂方法是简单工厂的延伸,继承了他的优点,是使用频率最高的设计模式之一;
2)基于工厂角色和产品角色的多态性设计是关键;
3)新加入产品,无需更改原有代码,只需添加一个对应的具体工厂和具体产品就可以;
4)扩展需要同时加入具体工厂和具体产品,类个数将成对增加,会增加系统的复杂性。

(3)适用场景

1)客户端不知道他所需要的具体产品对象的类,只需要知道所对应的工厂即可;
2)当一个类希望由他的子类来指定它所创建的对象的时候;
3)抽象工厂类提供创建产品的接口,通过其子类来指定创建哪个对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值