定义:简单工厂模式(Simple Factory Pattern),有一个提供接口的抽象类,然后实现不同功能的子类去实现抽象类,最后一个简单工厂类来完成对不同功能子类的创建。
类型:创建型模式。
类图:
参与角色:
- 抽象产品,提供接口供Client调用。
- 具体产品,根据具体产品的要求去实现接口。
- 工厂类,根据传入参数的不同,创建不同的产品。
概述:
简单工厂模式并不是GoF的23个设计模式之中,因为简单工厂模式是工厂方法模式的一种特例。但现实中,简单工厂模式使用得非常广泛,所以在此单列出予以记录。
假设有一手机代工厂,前些年买了两条手机生产线,全部代工Nokia的手机。但是随着智能手机的崛起,Nokia手机销量的大幅下滑,使得一条Nokia手机生产线不得不停工。眼看生产线停工,老板发动人脉,终于拉到了一个新的订单,代工Samsun手机。因为手机零配件基本一致,装配流程也一样,所以Nokia的手机生产线,经过细微更改就可以生产Samsung手机了,而且先前的生产工人基本不需要培训,立即就可以进入Samsung手机生产线生产了。停工的生产线又一次启动了。
这一案例正好非常适合简单工厂模式。标准流程的手机生产线,即是抽象产品类。Nokia,Samsung即是两个具体的手机生产线产品。然后工厂就根据拿到的订单,分别代工生产不同的手机。
代码:
1 #include <iostream> 2 #include <afxcom_.h> 3 using namespace std; 4 5 class CCellPhone 6 { 7 public: 8 virtual void ProducePhone() 9 { 10 cout<<"Produce Normal Phone."<<endl; 11 } 12 }; 13 14 class CNokia : public CCellPhone 15 { 16 public: 17 virtual void ProducePhone() 18 { 19 cout<<"Produce Nokia Phone."<<endl; 20 } 21 }; 22 23 class CSamsung : public CCellPhone 24 { 25 public: 26 virtual void ProducePhone() 27 { 28 cout<<"Produce Samsung Phone."<<endl; 29 } 30 }; 31 32 class CPhoneFactory 33 { 34 public: 35 static CCellPhone* CreatePhone(int _nType) 36 { 37 CCellPhone* pPhone = NULL; 38 39 switch (_nType) 40 { 41 case 0: // Nokia 42 pPhone = new CNokia(); 43 break; 44 case 1: // Samsung 45 pPhone = new CSamsung(); 46 break; 47 default: 48 ASSERT(FALSE); 49 break; 50 } 51 52 return pPhone; 53 } 54 }; 55 56 int _tmain(int argc, _TCHAR* argv[]) 57 { 58 // Nokia cellphone production line 59 CCellPhone* pNokiaPhone = CPhoneFactory::CreatePhone(0); 60 pNokiaPhone->ProducePhone(); 61 62 // Samsung cellphone production line 63 CCellPhone* pSamsungPhone = CPhoneFactory::CreatePhone(1); 64 pSamsungPhone->ProducePhone(); 65 66 delete pNokiaPhone; 67 pNokiaPhone = NULL; 68 69 delete pSamsungPhone; 70 pSamsungPhone = NULL; 71 72 return 0; 73 }
1 // C#代码 2 using System; 3 using System.Collections.Generic; 4 using System.Text; 5 using System.Diagnostics; 6 7 8 namespace Phone 9 { 10 public class CellPhone 11 { 12 public virtual void ProducePhone() 13 { 14 Console.WriteLine("Produce Normal Phone."); 15 } 16 } 17 18 class Nokia : CellPhone 19 { 20 public override void ProducePhone() 21 { 22 Console.WriteLine("Produce Nokia Phone."); 23 } 24 } 25 26 class Samsung : CellPhone 27 { 28 public override void ProducePhone() 29 { 30 Console.WriteLine("Produce Samsung Phone."); 31 } 32 } 33 34 public class PhoneFactory 35 { 36 public static CellPhone CreatePhone(string _strName) 37 { 38 CellPhone phone = null; 39 40 switch (_strName) 41 { 42 case "Nokia": 43 phone = new Nokia(); 44 break; 45 case "Samsung": 46 phone = new Samsung(); 47 break; 48 default: 49 Debug.Assert(false); 50 break; 51 } 52 53 return phone; 54 } 55 } 56 57 class Program 58 { 59 static void Main(string[] args) 60 { 61 CellPhone phone = PhoneFactory.CreatePhone("Nokia"); 62 phone.ProducePhone(); 63 64 phone = PhoneFactory.CreatePhone("Samsung"); 65 phone.ProducePhone(); 66 } 67 } 68 }
1 /** 2 * CellPhone.java 3 */ 4 5 /** 6 * @author feihe027@163.com 7 * 8 */ 9 public class CellPhone { 10 11 public static void main(String[] args) { 12 // TODO Auto-generated method stub 13 14 // Nokia cellphone production line 15 ICellPhone nokiaPhone = PhoneFactory.createPhone("Nokia"); 16 nokiaPhone.producePhone(); 17 18 // Samsung cellphone production line 19 ICellPhone samsungPhone = PhoneFactory.createPhone("Samsung"); 20 samsungPhone.producePhone(); 21 } 22 23 } 24 25 26 public class PhoneFactory { 27 28 public static ICellPhone createPhone(String _strName) { 29 ICellPhone phone = null; 30 switch (_strName) { 31 case "Nokia": 32 phone = new NokiaPhone(); 33 break; 34 case "Samsung": 35 phone = new Samsung(); 36 break; 37 default: 38 break; 39 } 40 41 return phone; 42 } 43 } 44 45 46 /** 47 * IEllPhone.java 48 */ 49 50 /** 51 * @author feihe027@163.com 52 * 53 */ 54 55 public interface ICellPhone { 56 57 // The interface that produce cellphone 58 public void producePhone(); 59 60 } 61 62 63 /** 64 * NokiaPhone.java 65 */ 66 67 /** 68 * @author feihe027@163.com 69 * 70 */ 71 72 public class NokiaPhone implements ICellPhone { 73 74 public void producePhone() 75 { 76 System.out.println("Produce Nokia Phone."); 77 } 78 } 79 80 81 /** 82 * Samsung.java 83 */ 84 85 /** 86 * @author feihe027@163.com 87 * 88 */ 89 public class Samsung implements ICellPhone{ 90 91 public void producePhone() { 92 System.out.println("Produce Samsung Phone."); 93 } 94 95 }
优缺点:
- 优点,客户不需要了解产品的具体实现过程,只需要关注生产产品的接口即好。另外客户只需要告诉工厂需要什么类型的产品,工厂即会提供给客户指定的产品。非常简单,所以在不是非常大型的项目的编程当中,经常被用到。
- 缺点,当工厂老板拉到新顾客LG时,引入新的生产线,但是在确定生产哪种类型的手机时,必须得修改工厂类,这违背了OCP(开闭原则)。工厂方法模式就是为了解决这个问题而产生的。
参考资料:
- 《java与模式》
- 《UML基础、案例与应用》
- 《大话设计模式》
- 一些网络博客