简单工厂(Factory Pattern)
简单工厂(静态工厂)可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个工厂类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
结构图:
角色:
- 简单工厂(FactoryProduct):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
- 抽象产品(IProduct):创建的所有产品的父类,负责描述所有实例共有的公共接口。
- 具体产品(Product):具体的细化的产品
适用场景:
- 创建较少的产品/对象,且客户端不关心创建过程。
优点:
- 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。很方便的创建出相应的产品。工厂和产品的职责区分明确。
- 屏蔽了产品的具体创建过程。使用中只需要知道自己需要哪种产品即可。
缺点:
- 随着产品的增多 Factory 里面的代码会越来越臃肿,稍微不符合开闭原则。
- Factory 职责过于重,一旦这个工厂不能正常工作,整个系统都会受到影响。
- 工厂适用了静态方法,不能被继承和重写。
代码(C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
public interface IProduct { void ShowProduct(); }
public class Product1 : IProduct { public void ShowProduct() { Console.WriteLine("Product1"); } }
public class Product2 : IProduct { public void ShowProduct() { Console.WriteLine("Product2"); } }
public class FactoryProduct { public static IProduct CreateProduct(int productId) { switch (productId) { case 1: return new Product1(); case 2: return new Product1(); default: return null; } } }
var product1 = FactoryProduct.CreateProduct(1); product1.ShowProduct(); var product2 = FactoryProduct.CreateProduct(2); product2.ShowProduct();
|
工厂方法(Factory Method)
如果要去掉简单工厂中繁琐的判断,传统的方法就是利用多态为每个产品创建自己的工厂,因为添加新的产品不需要修改原有代码。所以工厂方法模式比起简单工厂模式更加符合开闭原则。
结构图
角色:
- 抽象工厂(IFactory):抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
- 抽象产品(IProduct):创建的所有产品的父类,负责描述所有实例共有的公共接口。
- 具体产品(Product):是抽象产品的多种不同类型实现
- 具体产品工厂(ProductFactory):具体产品的工厂。抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法。
适用场景:
- 无法预知对象类别及其依赖关系时,可使用工厂方法,用子类来决定类别。
优点:
- 增加产品部不需要修改原有代码符合开闭原则。
- 一个工厂只负责一个产品的创建符合职责单一原则。
缺点:
- 工厂模式需要额外创建诸多 Factory 类,增加代码的复杂性。
代码(C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
public interface IProduct { void ShowProduct(); }
public interface IFactory { IProduct CreateProduct(); }
public class Product1 : IProduct { public void ShowProduct() { Console.WriteLine("Product1"); } }
public class Product1Factory : IFactory { public IProduct CreateProduct() { return new Product1(); } }
public class Product2 : IProduct { public void ShowProduct() { Console.WriteLine("Product1"); } }
public class Product2Factory : IFactory { public IProduct CreateProduct() { return new Product1(); } }
IFactory product1Factory = new Product1Factory(); var pro1 = product1Factory.CreateProduct(); pro1.ShowProduct();
IFactory product2Factory = new Product2Factory(); var pro2 = product2Factory.CreateProduct(); pro1.ShowProduct();
|
抽象工厂(Abstract Factory)
抽象工厂对工厂的抽象化,让一个工厂生产一类产品。解决了按照工厂方法和简单工厂造成的工厂泛滥。
抽象工厂将各种产品分门别类,基于此来规划各种工厂的制造接口。譬如实例代码中,小米和苹果工厂不仅能生产手机还可以生产电脑或其他的产品。
结构图:
角色:
- 抽象产品(Abstract Product):创建的所有产品的父类,负责描述所有实例共有的公共接口。
- 具体产品(Concrete Product):是抽象产品的多种不同类型实现。
- 抽象工厂(Abstract Factory):一组创建各种抽象产品的方法
- 具体工厂(Concrete Factory):产出具体的产品。
适用场景:
- 有一个基于一组抽象方法/接口的对象,且其主要功能因此变得不明确,那么在这种情况下可以考虑使用抽象工厂模式。
优点:
- 同一工厂生成的产品相互匹配。
- 抽象后的工厂更加符合单一原则。
- 新增产品变体不时不需要修改原有代码符合开闭原则。
- 避免客户端和具体产品代码的耦合。
缺点:
- 代码复杂度高。
代码(C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
interface IPhone { void ShowPhone(); }
interface IComputer { void ShowComputer(); }
class ApplePhone : IPhone { public void ShowPhone() { Console.WriteLine("iphone 12"); } }
class AppleComputer : IComputer { public void ShowComputer() { Console.WriteLine("mac book pro M1"); } }
class MiPhone : IPhone { public void ShowPhone() { Console.WriteLine("mi 13"); } }
class MiComputer : IComputer { public void ShowComputer() { Console.WriteLine("mi book"); } }
interface IAbstractFactory { IPhone CreatePhone(); IComputer CreateComputer(); }
class AppleFactory : IAbstractFactory { public IPhone CreatePhone() { return new ApplePhone(); }
public IComputer CreateComputer() { return new AppleComputer(); } }
class MiFactory : IAbstractFactory { public IPhone CreatePhone() { return new MiPhone(); }
public IComputer CreateComputer() { return new MiComputer(); } }
IAbstractFactory appleFactory = new AppleFactory(); appleFactory.CreateComputer(); appleFactory.CreatePhone();
IAbstractFactory miFactory = new MiFactory(); miFactory.CreateComputer(); miFactory.CreatePhone();\
|
最后
工厂模式和抽象工厂应该是项目中常用的设计模式,抽象工厂通常基于一组工厂方法来实现的。.Net中的Dependency Injection底层也是基于工厂模式来实现的,DI就相当于一个工厂,负责在程序启动的时候,根据配置事先创建好对象。当应用程序需要使用某个类对象的时候,直接从容器中获取即可。