Factory Method工厂方法模式
- 定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类,属于创建型模式
- 在此模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类负责生产具体的产品对象,使一个类的实例化延迟到其子类,由子类来确定实例化哪个具体的产品类。
[TestClass]
public class UnitTest2
{
[TestMethod]
public void TestMethod1()
{
//测试
//当前只是实例化了工厂,工厂的产品还尚未实例化
Creator creator = new ConcreteCreator();
//调用了“工厂方法”后,产品这个对象才真正被实例化
var product = creator.FactoryMethod();
}
}
/// <summary>
/// 产品抽象类 是子类ConcreteProduct的泛华
/// </summary>
public abstract class Product
{
}
/// <summary>
/// 具体的产品 继承自 Product
/// </summary>
public class ConcreteProduct : Product
{
}
/// <summary>
/// 实例化工厂
/// </summary>
public abstract class Creator
{
/// <summary>
/// 定义创建产品对象的公共接口
/// </summary>
/// <returns></returns>
public abstract Product FactoryMethod();
}
public class ConcreteCreator : Creator
{
public override Product FactoryMethod()
{
Console.Write("具体对象的方法");
return new ConcreteProduct();
}
}
案例
调用者只需要通过工厂获取想要的对象,而不需要知道对象的创建具体细节,
参考用例,一家工厂可以生产TV,MP4,MP3等电子产品,这些电子产品都有播放功能。
namespace DesignPatterns.FactoryMethod
{
public class Factory
{
/// <summary>
/// 通过名称决定实例化哪种子类对象
/// </summary>
/// <param name="name">对象名称</param>
/// <returns></returns>
public Product GetProduct(string name)
{
if (name.ToLower() == "tv")
return new TV();
if (name.ToLower() == "mp4")
return new MP4();
if (name.ToLower() == "mp3")
return new MP3();
throw new Exception("unknow product name");
}
public static void Test()
{
var factory = new Factory();
var tv = factory.GetProduct("tv");
tv.Play();
var mp4 = factory.GetProduct("mp4");
mp4.Play();
}
}
public abstract class Product
{
public abstract void Play();
}
public class TV : Product
{
public override void Play()
{
Console.WriteLine("TV play");
}
}
public class MP4 : Product
{
public override void Play()
{
Console.WriteLine("MP4 play");
}
}
public class MP3 : Product
{
public override void Play()
{
Console.WriteLine("MP3 play");
}
}
}
实际运用
在具体的运用场景中比如日志存储方式,有远程TCP,UDP存储,本地磁盘存储,发邮件,这些具体的存储方式,可以通过配置工厂方法中的种类,由调用者选择具体哪种存储方式;
工厂方法只适合统一的对象创建,就是子类和父类拥有相同的构造函数,如果构造函数不一,那么工厂方法将很难管理起这些子类。