工厂方法模式 (Factory Method Pattern)
一、定义
创建型模式之一。
Define an interface for creating an object, but let subclass decide which class to instantiate .
Factory Method lets a class defer instantiation to subclass.
(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类)
二、结构解析
工厂方法模式的一般结构有四种角色:抽象工厂、具体工厂、抽象产品、具体产品。
它将 简单工厂模式(静态工厂方法模式) 中的工厂类抽象为一个接口(抽象工厂)(这个接口中定义了一个用于创建对象的方法,即工厂方法) 。然后派生出具体工厂类与具体产品类一一对应 ,即, 决定了工厂就意味着决定了产品,最后在具体工厂类中实例化具体产品类。从而使一个类(具体产品类)的实例化延迟到其子类(从抽象工厂类延迟到具体工厂类)。
三、评价
工厂方法模式解决了 简单工厂模式 (非泛型的实现)违背开闭原则、单一职责原则的问题。
当有产品新增时,不用再需要修改工厂类(抽象工厂类和具体工厂类都不需要修改),而是新增一个与之对应的具体工厂类。
四、实现
//独立负责一个产品的工厂方法
namespace FactoryMethod
{
//抽象产品类
public abstract class Product { }
public class ConcreteProduct1 : Product { }
public class ConcreteProduct2 : Product { }
//可扩展新的具体产品
//...
//抽象工厂类
public abstract class Creator
{
//定义创建对象的公共接口
public abstract Product FactorMethod();
}
//具体工厂类1, 只用来生产产品1
public class ConcreteCreator1 : Creator
{
public override Product FactorMethod()
{
return new ConcreteProduct1();
}
}
//具体工厂类2,只用来生产产品2
public class ConcreteCreator2 : Creator
{
public override Product FactorMethod()
{
return new ConcreteProduct2();
}
}
public class Client
{
private void Main()
{
ConcreteCreator1 factory1 = new ConcreteCreator1();
ConcreteCreator2 factory2 = new ConcreteCreator2();
factory1.FactorMethod();
factory2.FactorMethod();
}
}
}
缺点:工厂方法模式中,具体工厂类直接依赖具体产品类。违背依赖倒置原则(高层模块不应该依赖低层模块,它俩都应该依赖低层模块的抽象) 。
五、泛型工厂方法模式
可以认为泛型T和Object类型一样,是所有类型的抽象基类。
这样,具体工厂类(高层模块)将只依赖泛型T(低层模块的抽象基类),并且当产品新增时,也不需要任何改动。
具体实现如下:
抽象工厂类中定义一个用于创建产品对象的公共泛型接口,泛型T 约束为抽象产品类。
实际工厂类继承抽象工厂类,并实现这个泛型接口,通过反射对T进行实例化。
using System;
//泛型工厂方法
namespace FactoryMethod.GenericFunction
{
//抽象产品类
public abstract class Product { }
//具体产品类
public class ConcreteProduct1 : Product { }
public class ConcreteProduct2 : Product { }
//可扩展新的具体产品
//...
//抽象工厂类
public abstract class Creator
{
//定义创建对象的公共接口
public abstract T FactorMethod<T>() where T : Product;
}
//具体工厂类
public class ConcreteCreator : Creator
{
//实现创建对象的公共接口
public override T FactorMethod<T>()
{
return Activator.CreateInstance<T>();
}
}
public class Client
{
private void Main()
{
//建造工厂
ConcreteCreator factory = new ConcreteCreator();
//创建具体产品1
factory.FactorMethod<ConcreteProduct1>();
//创建具体产品2
factory.FactorMethod<ConcreteProduct2>();
}
}
}