定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。——《设计模式》GoF
目录
1.UML图
说明:
(1)、抽象工厂角色(Creator): 充当抽象工厂角色,定义工厂类所具有的基本的操作,任何具体工厂都必须继承该抽象类。
(2)、具体工厂角色(ConcreteCreator):充当具体工厂角色,该类必须继承抽象工厂角色,实现抽象工厂定义的方法,用来创建具体产品。
(3)、抽象产品角色(Product):充当抽象产品角色,定义了产品类型所有具有的基本操作,具体产品必须继承该抽象类。
(4)、具体产品角色(ConcreteProduct):充当具体产品角色,实现抽象产品类对定义的抽象方法,由具体工厂类创建,它们之间有一一对应的关系。
2.案例
这里以生产电脑为例:
首先定义电脑接口(Product),所有的电脑又能启动,开机、关机:
internal interface IComputer
{
public void Start();
public void Run();
public void Stop();
}
然后定义生产电脑的抽象厂(Creator),生产的东西必须有电脑的功能(IComputer)
internal abstract class ComputerFactory
{
public abstract IComputer CreateComputer();
}
然后,华为,联系都有生产电脑,定义具体的电脑(ConcreteProduct):
internal class HuaweiComputer:IComputer
{
public const string Name = "HuaWei";
public void Run()
{
Console.WriteLine(Name + "is Running!");
}
public void Start()
{
Console.WriteLine(Name + "is going to Start >>>>>>>>>>");
}
public void Stop()
{
Console.WriteLine(Name + " is going to shut up >>>>>>>>>>>");
}
}
internal class LenovoComputer : IComputer
{
public const string Name = "Lenove";
public void Run()
{
Console.WriteLine(Name + "is Running!");
}
public void Start()
{
Console.WriteLine(Name + "is going to Start >>>>>>>>>>");
}
public void Stop()
{
Console.WriteLine(Name + " is going to shut up >>>>>>>>>>>");
}
}
(ps:都是贴牌厂,所以除了名字,其它一样)
最后是定义华为,联想的各自电脑工厂(ConcreteFactory),当然是生产自己家的产品:
internal class LenovoComputeFactory : ComputerFactory
{
public override IComputer CreateComputer()
{
return new LenovoComputer();
}
}
internal class HuaWeiComputerFactory : ComputerFactory
{
public override IComputer CreateComputer()
{
return new HuaweiComputer();
}
}
最后使用如下:
List<ComputerFactory> computerFactories = new List<ComputerFactory>()
{
new HuaWeiComputerFactory(),
new LenovoComputeFactory()
};
computerFactories.ForEach(factory =>
{
var computer = factory.CreateComputer();
computer.Start();
computer.Run();
computer.Stop();
});
3.总结
3.1 优点
- 在工厂方法中,用户只需要知道所要产品的具体工厂,无须关系具体的创建过程,甚至不需要具体产品类的类名。
- 在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”。
3.2 缺点
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,是的系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。(比如你再增加一个华硕电脑,以及对应的电脑厂)
3.3 使用场景
(1)一个类不知道它所需要的对象的类。在工厂方法模式中,我们不需要具体产品的类名,我们只需要知道创建它的具体工厂即可。
(2)、一个类通过其子类来指定创建那个对象。在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
(3)、将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定。
完整代码:DesignPatternReview