1、工厂模式简介
工厂模式属于创建型模式,是专门用来创建对象的模式,抽象了实例化的过程。工厂模式分为 : 工厂方法模式、抽象工厂模式。
在学习工厂方法模式、抽象工厂之前,首先先要了解一下简单工厂模式,简单工厂不在23种设计模式之列,一般它是根据自变量的不同而返回不同的类型。比较简单实用一些,在学习工厂模式之前下来学习一下简单工厂,有助于我们理解工厂模式。
1.1、简单工厂定义
简单工厂是由一个工厂对象决定创建出哪一种产品类的实例。
其实质就是由一个工厂类根据传入的参数,来决定调用哪一个产品类的实例。
1.2、简单工厂的角色(参与者)
工厂角色 : 负责实现创建所有实例的内部逻辑,直接被外部调用,创建所需的产品对象.
抽象产品角色 : 创建所有对象的基类,负责描述所有实例所共有的公共接口
具体产品角色 : 所有创建的对象都是充当这个角色的某个具体类的实例.
1.3、业务需求
需求如下 : 现在有电脑、手机等电子设备,当使用电脑上网时,我要知道是电脑在上网,手机上网时要知道是手机在上网。
1.4、使用简单工厂分析业务需求图
首先我们要抽象出一个电子产品类,电脑、手机继承电子产品,工厂负责生产电子产品
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Factory factory = new Factory(); 6 IElectronic computer = factory.Create("Computer"); 7 computer.Internet(); 8 Console.ReadLine(); 9 } 10 } 11 12 /// <summary> 13 /// 抽象产品角色 14 /// </summary> 15 interface IElectronic 16 { 17 void Internet(); 18 } 19 /// <summary> 20 /// 具体产品角色 21 /// </summary> 22 public class Computer : IElectronic 23 { 24 public void Internet() 25 { 26 Console.WriteLine("Computer Internet"); 27 } 28 } 29 /// <summary> 30 /// 具体产品角色 31 /// </summary> 32 public class Phone : IElectronic 33 { 34 public void Internet() 35 { 36 Console.WriteLine("Phone Internet"); 37 } 38 } 39 /// <summary> 40 /// 工厂角色 41 /// </summary> 42 class Factory 43 { 44 45 public IElectronic Create(string type) 46 { 47 switch (type) 48 { 49 case "Computer": 50 return new Computer(); 51 case "Phone": 52 return new Phone(); 53 default: 54 return null; 55 } 56 } 57 }
现在如果我想加入一个Ipad的产品,那么我要重新修改工厂类,这样是很不利于软件架构设计的,同时也违反了开闭原则,那么接下来的工厂方法模式,正很好的避免了这几点.
1.5、适用性
创建对象需要大量重复的代码
创建对象需要访问某些信息,而这些信息不应该包含在复合类中。
创建对象的生命周期必须集中管理,以保证在整个程序中具有一致的行为。
1.6、局限性
1 : 重构的话会破坏客户端的代码。
2 : 工厂方法所实例化的类具有私有的构造方法,
2:工厂方法模式简介
2.1 、工厂方法(Factory Method)模式 :
定义一个创建产品对象的工厂接口,将实际创建工厂推迟到子类当中.核心工厂类不在负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化使得工厂方法模式可以使我们的系统不修改具体工厂角色的情况下添加新的产品
上面的一大节的定义,貌似很难,其实理解了就简单的一下几句 :
一个抽象的产品类,可以派生出多个具体产品类.
一个抽象的工厂类,可以派生出多个具体工厂类
每个具体工厂类只能创建一个具体产品类的实例.
2.2、工厂方法的角色(参与者)
1: 抽象工厂角色(Creator) : 工厂方法模式的核心,与应用程序无关,任何在模式中创建的对象的工厂类必须实现这个接口.
2: 具体工厂角色(Concrete Creator) : 实现抽象工厂接口的具体工厂类,包含于应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象.
3: 抽象产品角色(Product) : 工厂方法模式所创建的对象的超类型,也就是产品对象的基类/接口.
4: 具体产品角色(Contrete Product) : 实现了抽象产品角色所定义的接口,具体产品有专门的具体工厂创建,它们之间往往一一对应.
2.3、业务需求
依旧还是拿出简单工厂的电子产品例子,只不过我们这次添加一个Ipd,即 : 电脑、手机、IPAD。
2.4、使用工厂方法分析业务需求图
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 IFactory factory = new ComputerFactory(); 6 IProduct pro = factory.Product(); 7 pro.ProductType(); 8 Console.ReadLine(); 9 } 10 } 11 // 抽象产品角色 12 interface IProduct 13 { 14 void ProductType(); 15 } 16 // 具体产品角色 17 class Computer : IProduct 18 { 19 public void ProductType() 20 { 21 Console.WriteLine("Product Is Computer"); 22 } 23 } 24 // 具体产品角色 25 class Phone : IProduct 26 { 27 public void ProductType() 28 { 29 Console.WriteLine("Product Is Phone"); 30 } 31 } 32 // 抽象工厂角色 33 interface IFactory 34 { 35 IProduct Product(); 36 } 37 38 // 具体工厂角色 39 class ComputerFactory : IFactory 40 { 41 public IProduct Product() 42 { 43 return new Computer(); 44 } 45 } 46 // 具体工厂角色 47 class PhoneFactory : IFactory 48 { 49 public IProduct Product() 50 { 51 return new Phone(); 52 } 53 }
2.5、工厂方法模式适用性
1: 创建对象需要大量重复的代码。
2: 创建对象需要访问某些信息,而这些信息不应该包含在复合类中。
3:创建对象的生命周期必须集中管理,以保证在整个程序中具有一致的行为。
工厂方法模式常用于接口、框架、工具包库文件中,在这些库文件中需要创建客户端代码实现的具体类型的对象。
2.6、工厂方法的优点
1 : 在系统添加新产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,很好的利用了封装和委托.
2 : 符合高内聚低耦合原则.很好的避免了简单工厂中的缺点.