首页 > 代码库 > 设计模式学习(1) --- 3类工厂模式

设计模式学习(1) --- 3类工厂模式

   讲个故事吧。从前一个老板非常有钱,非常喜欢数码产品手机,经常喜欢买智能手机,那么怎么买?当然,可以自己去各个手机店买,比如去苹果店,三星店买。但是老板是非常忙的,怎么办?老板是程序员出生。面向对象嘛。加个层次,叫秘书去买,把要买的型号,写张纸条给秘书即可。为什么这样做,对老板来说当然省事了,直接窃取秘书的劳动成果即可(因为付薪水了嘛)。秘书根据老板的指示去做,要买什么牌子手机就去相应的专卖店买即可。OK,这样应付了一段时间,因为这个时期智能手机刚刚兴起,也就几家可以做。

       时光飞逝,岁月如梭。随着科技的进步,智能手机市场太大,至于处于一个智能手机的元年,用某人的话说“风口上,猪都能飞起来”。所以,一大批智能手机厂商出现,一大批智能手机品牌出现,但是这个老板从喜欢买智能手机到喜欢收集研究智能手机了,因为土豪嘛,不差钱。所以知道哪里又出款手机了,就叫秘书去买,天啊。这下可忙坏了秘书,要知道,世上的智能手机品牌这么多,秘书的工作现在负担变得更重了,不光要负责公司各种会议,还要天天出去买手机,心里甚是不爽。当然,老板看在眼里,就加了秘书的工资,并且给秘书配了几个同事协助秘书买智能手机这件事。秘书加薪了又有同事一起来分担,秘书这下爽了,这是要升职加薪充当CEO迎娶高富帅的节奏啊,顿时高兴起来了。而且秘书又是总管。老板要买什么新品牌手机,都是跟秘书先说,然后秘书在去分配其他同事分头去买。当然为此老板需要多些人工费,土豪嘛,这能有几个钱。ok这样又过了一段时间。

       时间飞逝,岁月如梭。随着各大手机厂商的产品迭代,尼玛iphone都出到了6了。老板收集起来更加疯狂了,要把所有品牌的所有型号都买回来研究。这下又忙坏了秘书,因为秘书要搞清楚哪些个品牌都产到几代了,这当然也不是什么太大的难事,百度一下嘛,ok,在了解了各个品牌的系类产品后,再吩咐其他同事分别去买各个系列产品。当然如果产品品类太多,再增加个同事嘛。多付几个人力费而已。

      最后土豪老板就这样将所有智能手机体验了个遍,都觉得不行,没有抓住消费者发烧心里,于是打算自己干一款产品,于是安静的创建了一家公司,势必要打造一款全球级别的重量级智能手机...美好的事情即将发生....那么问题来了,使用设计模式哪家强?

1.简单工厂模式(simple factory)

     OK,小学语文老师教会了我们在分析语文课文时,按照自然段来划分中心思想。在第一段自然中程序员老板成分利用了自己所学的专长,将实际买手机问题,变成了面向对象问题(面向秘书哇!好幸福)。秘书具有按照老板要求买手机的功能。这个秘书就是工厂了(神马秘书是工厂?)抽象为工厂啦!专门做一间买各种品牌手机的事。而对于手机而言,需不需要抽象?各大手机厂商,也不太可能造芯片,屏幕等配件,所以也是个具有技术含量的零配件组装厂,所以可以具体抽象出行为(具有发短信,打电话,上网等功能的设备),各个实际手机厂商按照各自设计来设计。于是java代码如下:

//抽象类实现
abstract class phone
{ //抽象类至少一个抽象方法 这样才是抽象类
	abstract void phoneInf(); 
}
//具体产品
class iphone extends phone
{
	public void phoneInf()
	{
		System.out.println("Buy iphone");
	}
}
class XiaoMi extends phone
{
	public void phoneInf()
	{
		System.out.println("Buy XiaoMi");
	}
}
//工厂
class Secretary
{
	public static phone BuyPhone(String brand)
	{
		if(brand.equals("iphone") )
			return new iphone();
		else 
		{
			if( brand.equals("XiaoMi") )
				return new XiaoMi();
			else 
				return null;
		}
	}
}

class Main
{
	public static void main(String[] args)
	{ //老板只需要告诉秘书买什么牌子的手机即可
		phone p1 = Secretary.BuyPhone("XiaoMi");
		p1.phoneInf();
		
		phone p2 = Secretary.BuyPhone("iphone");
		p2.phoneInf();
	}
}

/************************************************************************/
/* C++实现 简单工厂模式 
 */
/************************************************************************/
#include <iostream>
#include <string>
using namespace std;

class Phone
{
public :
	virtual void phoneInf() =0; //纯虚函数 
};

class iPhone : public Phone
{
public:
	void phoneInf()
	{
		cout<<"Buy iPhone"<<endl;
	}
};
class XiaoMi : public Phone
{
public :
	void phoneInf()
	{
		cout<<"Buy XiaoMi"<<endl;
	}
};

class Secretary
{
public:
	static Phone* BuyPhone(string brand)
	{
		if(brand == "iPhone")
			return new iPhone();
		else 
		{
			if(brand == "XiaoMi")
				return new XiaoMi();
			else 
				return NULL;
		}
	}
};

int main()
{
	Phone* p1 = Secretary::BuyPhone("iPhone");
	p1->phoneInf();

	Phone* p2 = Secretary::BuyPhone("XiaoMi");
	p2->phoneInf();
	return 0;
}

从上可见简单工厂模式组成:

         a.工厂类(这里是秘书),核心部分。由一个具体的类实现。

         b.抽象产品。 (这里是phone),java中由一个接口或者抽象类实现。C++中可以由抽象类(含有纯虚函数的类)实现。

         C.具体产品。这里指的是各个手机厂商产生的产品,比如iphone,xiaomi等。java中继承或者实现 抽象类和接口,完成实际产品实例的创建。C++中子类实例化对象。

      这样做,老板(实际客户)只提出请求,执行全部将由秘书(工厂类)来做。其中工厂类必须具有逻辑判断等一些功能,比如秘书要能分辨各种手机品牌的功能。这样子,数据量小时候,完全可以这么做。一旦老板需要有些新手机,但是数据量较小时候,秘书就需要在买一些品牌了(对于工厂类而言,就是需要在修改类了)。

2.工厂方法模式(factory method)

  第二自然段告诉我们,当秘书实在忙不过来了,频繁的修改工厂类,相当于导致秘书工作量巨大,必须有人来帮忙才行。这下秘书只管负责安排任务,具体的手机叫手下买了,再给秘书即可。这时候,需要增加一个抽象工厂类,用于只分发任务功能,具体的工作由实际工厂来做。代码如下:

//java 工厂方法模式 
//抽象产品
abstract class phone
{ 
	public abstract void phoneInf(); 
}
//具体产品
class iphone extends phone
{
	public void phoneInf()
	{
		System.out.println("Buy iphone");
	}
}
class XiaoMi extends phone
{
	public void phoneInf()
	{
		System.out.println("Buy XiaoMi");
	}
}
//抽象工厂类
abstract class Secretary
{
	public abstract phone BuyPhone();
}

//实际工厂类
class PersonA_iphone extends Secretary
{
	public phone BuyPhone()
	{
		return new iphone();
	}
}
class PersonB_XiaoMi extends Secretary
{
	public phone BuyPhone()
	{
		return new XiaoMi();
	}
}

class Main
{
	public static void main(String[] args)
	{ 
		//秘书分配person1去买iphone
		PersonA_iphone person1 = new PersonA_iphone() ;
		phone p1 = person1.BuyPhone();
		p1.phoneInf(); 
		//秘书分配person2去买XiaoMi
		PersonB_XiaoMi person2 = new PersonB_XiaoMi();
		phone p2 = person2.BuyPhone();
		p2.phoneInf();
	}
}
/************************************************************************
 C++实现 工厂方法模式 
************************************************************************/
#include <iostream>
#include <string>
using namespace std;

class Phone
{
public :
	virtual void phoneInf() =0; //纯虚函数 
};

class iPhone : public Phone
{
public:
	void phoneInf()
	{
		cout<<"Buy iPhone"<<endl;
	}
};
class XiaoMi : public Phone
{
public :
	void phoneInf()
	{
		cout<<"Buy XiaoMi"<<endl;
	}
};

//抽象工厂
class Secretary
{
public:
	virtual Phone* BuyPhone()= 0 ;
};
//实际工厂 
class PersonA_iphone : public Secretary
{
public:
	Phone* BuyPhone()
	{
		return new iPhone();
	}
};
class PersonB_XiaoMi : public Secretary
{
public:
	Phone* BuyPhone()
	{
		return new XiaoMi();
	}
};
int main()
{
	//秘书叫person1 去买iphone
	PersonA_iphone person1 ;
	Phone*  phone1 = person1.BuyPhone();
	phone1->phoneInf();
	
	//秘书叫person2 去买xiaomi
	PersonB_XiaoMi person2 ;
	Phone* phone2 = person2.BuyPhone();
	phone2->phoneInf();

	return 0;
}

从上可见工厂方法模式组成:

         a. 抽象产品。 (这里是phone),java中由一个接口或者抽象类实现。C++中可以由抽象类(含有纯虚函数的类)实现。

         b.具体产品。这里指的是各个手机厂商产生的产品,比如iphone,xiaomi等。java中继承或者实现 抽象类和接口,完成实际产品实例的创建。C++中子类实例化对象。

       c. 抽象工厂类(这里是秘书),相比于简单工厂模式,增加的,将秘书从实际劳力中解放出来,只负责安排任务,由一个抽象类实现。

      d.实际工厂。指的是 实际买手机的人。实际类实例化。

      这样将导致,秘书轻松了许多,具体买手机这件事,也比较好做,只要人手够多,一旦要新买个手机,只需要秘书在派个人即可,这样对于秘书而言,依然轻松,可扩展。但是唯一的坏处就是需要花钱雇佣人手,多应于实际代码张就是要多很多实际的类。whatever,事情可以达到要求嘛。

3.抽象工厂模式

  第三自然段告诉我们,手机厂商都出系列手机了,前两模式都不适用了,总不可能秘书吩咐A去买iphone1,又叫B去买iphone2吧..当然也可以,但是没必要啊。买iPhone1的肯定可以去买iphone2嘛。所以秘书需要从新规划下任务清单,好重新安排任务了。

//java 抽象工厂模式
//抽象产品类
abstract class phone
{ 
	public abstract void phoneInf(); 
}
//具体产品
class iphone1 extends phone
{
	public void phoneInf()
	{
		System.out.println("Buy iphone1");
	}
}
class iphone1s extends phone
{
	public void phoneInf()
	{
		System.out.println("Buy iphone1s");
	}
}
class XiaoMi1 extends phone
{
	public void phoneInf()
	{
		System.out.println("Buy XiaoMi1");
	}
}
class XiaoMi1s extends phone
{
	public void phoneInf()
	{
		System.out.println("Buy XiaoMi1s");
	}
}
//抽象工厂类
abstract class Secretary
{
	public abstract phone BuyPhone_1();//买一代手机
	public abstract phone BuyPhone_1s(); //买一代升级版
	//public abstract phone BuyPhone_2(); //买二代手机
	//继续扩展...
}

//实际工厂类
class PersonA_iphone extends Secretary
{
	public phone BuyPhone_1()//买iphone一代手机
	{
		return new iphone1();
	}
	public phone BuyPhone_1s()//买iphone1s版
	{
		return new iphone1s();
	}
}
class PersonB_XiaoMi extends Secretary
{
	public phone BuyPhone_1()
	{
		return new XiaoMi1();
	}
	public phone BuyPhone_1s()
	{
		return new XiaoMi1s();
	}
}

class Main
{
	public static void main(String[] args)
	{ 
		//秘书分配person1去买iphone1,1s产品
		PersonA_iphone person1 = new PersonA_iphone() ;
		phone p1 = person1.BuyPhone_1();//personA 买的iphone1
		phone p2 = person1.BuyPhone_1s();//personA 买的iphone1s
		p1.phoneInf(); 
		p2.phoneInf();
		
		//秘书分配person2去买XiaoMi1,1s产品
		PersonB_XiaoMi person2 = new PersonB_XiaoMi();
		phone p3 = person2.BuyPhone_1();
		p3.phoneInf();
		phone p4 = person2.BuyPhone_1s();
		p4.phoneInf();
	}
}

/***********************************************************************
C++实现 抽象工厂模式
*********************************************************************/
#include <iostream>
#include <string>
using namespace std;
//抽象产品类
class Phone
{
public :
	virtual void phoneInf() =0; //纯虚函数 
};
//实际产品
class iPhone1 : public Phone
{
public:
	void phoneInf()
	{
		cout<<"Buy iPhone1"<<endl;
	}
};
class iPhone1s : public Phone
{
public:
	void phoneInf()
	{
		cout<<"Buy iPhone1s"<<endl;
	}
};
class XiaoMi1 : public Phone
{
public :
	void phoneInf()
	{
		cout<<"Buy XiaoMi1"<<endl;
	}
};
class XiaoMi1s : public Phone
{
public :
	void phoneInf()
	{
		cout<<"Buy XiaoMi1s"<<endl;
	}
};
//抽象工厂
class Secretary
{
public:
	virtual Phone* BuyPhone1()= 0 ; //买一代手机
	virtual Phone* BuyPhone1s()=0;  //买1s手机
	//...继续扩展
};
//实际工厂 
class PersonA_iphone : public Secretary
{
public:
	Phone* BuyPhone1()
	{
		return new iPhone1();
	}
	Phone* BuyPhone1s()
	{
		return new iPhone1s();
	}

};
class PersonB_XiaoMi : public Secretary
{
public:
	Phone* BuyPhone1()
	{
		return new XiaoMi1();
	}
	Phone* BuyPhone1s()
	{
		return new XiaoMi1s();
	}
};
int main()
{
	//秘书叫person1 去买iphone1,1s
	PersonA_iphone person1 ;
	Phone*  phone1 = person1.BuyPhone1();
	Phone*  phone2 = person1.BuyPhone1s();
	phone1->phoneInf();
	phone2->phoneInf();

	//秘书叫person2 去买xiaomi1,1s
	PersonB_XiaoMi person2 ;
	Phone* phone3 = person2.BuyPhone1();
	Phone* phone4 = person2.BuyPhone1s();
	phone3->phoneInf();
	phone4->phoneInf();

	return 0;
}
分析组成:和工厂方法模式一样:

         a. 抽象产品。 (这里是phone),java中由一个接口或者抽象类实现。C++中可以由抽象类(含有纯虚函数的类)实现。

         b.具体产品。这里指的是各个手机厂商产生的产品,比如iphone1,1s,xiaomi1等。java中继承或者实现 抽象类和接口,完成实际产品实例的创建。C++中子类实例化对象。

        c. 抽象工厂类(这里是秘书),相比于简单工厂模式,增加的,将秘书从实际劳力中解放出来,只负责安排任务,由一个抽象类实现。但是对于这样的产品族而言,需要重新设计秘书类了。如本例中。

       d.实际工厂。指的是 实际买手机的人。实际类实例化。


设计模式学习(1) --- 3类工厂模式