设计模式-工厂模式
简单工厂模式,https://www.cnblogs.com/Kyle-Wang/p/16063512.html
一、工厂模式的引出
工厂模式是简单工厂模式的升级版本。简单工厂一般就是提供一个CreateInstance方法,允许通过传入一个对象类型的参数,来实例化返回一个对象给调用方。这样违背了设计模式6大原则种的“单一职责”。
因为CreateInstance方法里面,耦合了一组对象。它既可以实例化A对象,也可以实例化B、C、D对象,职责不单一会导致,假设以后需要新增一个对象E,就i必须修改CreateInstance方法。而我们一般需要遵守“开闭原则”
开闭原则:对扩展开放(open) - 对修改关闭(closed) ,在设计一个软件系统模块(类,方法)的时候,应该可以在不修改原有的模块(修改关闭)的基础上,能扩展其功能(扩展开放)。
因此,引出工厂模式。
二、工厂模式的实现
1、新增工厂接口
public interface IFactory { IRace CreateInstance(); }
2、新增具体工厂,实现工厂接口
public class HumanFactory : IFactory { public IRace CreateInstance() { IRace race = new Human(); return race; } } public class NEFactory : IFactory { public IRace CreateInstance() { IRace race = new NE(); return race; } } public class ORCFactory : IFactory { public IRace CreateInstance() { IRace race = new ORC(); return race; } }
3、调用方式
IFactory humanFactory = new HumanFactory(); IRace human = humanFactory.CreateInstance(); IFactory neFactory = new NEFactory(); IRace ne = neFactory.CreateInstance();
这样的话,如果要新增一个Undead种族,只需要新增一个UndeadFactory就行了
public class UndeadFactory : IFactory { public IRace CreateInstance() { IRace race = new Undead(); return race; } }
三、工厂模式的意义
在引出简单工厂模式之前,有一个最开始的代码
Player player = new Player() { Id = 123, Name = "Eleven" }; Human race = new Human();//1 最原始最习惯的 player.PlayHuman(race); ORC oRC = new ORC(); player.PlayORC(oRC);
现在工厂模式的调用方式似乎又回到了原点,甚至还要繁琐点。最开始是依赖了具体种族对象,需要什么种族就new哪个种族,
而现在,变成了需要哪个种族,new哪个种族的工厂,然后再由工厂创建对象。这样有什么意义呢?
1、目前所举例的种族,实例化时都很简单,但如果种族的实例化是很复杂的呢?比如新种族Six
public class Six : IRace { public Six(string name, int id, object special, IRace race1, IRace race2, IRace race3) { } public void ShowKing() { Console.WriteLine("The King of {0} is 悠悠吾心", this.GetType().Name); } }
该种族实例化时,需要传递多个参数。此时工厂模式就体现出优势了,调用者不需要关心Six种族需要什么参数,他要做的只需要通过SixFactory来获取Six。
而最开始的代码,调用者必须知道Six种族的所需参数才能正确使用。
public class SixFactory : IFactory { public virtual IRace CreateInstance() { IRace race = new Six("Yoyo", 123, new Undead(), new Undead(), new Human(), new NE());//一些具体业务 return race; } }
2、留下了扩展点,上面的SixFactory工厂的CreateInstance方法定义为virtual虚方法,允许子类重写,这在很多框架里面,都时基本用法。允许自定义工厂类继承框架自带的工厂类,重写对象实例化方法。
/// <summary> /// 我们扩展的工厂 /// </summary> public class SixFactoryExtend : SixFactory { public override IRace CreateInstance() { Console.WriteLine("这里是我们扩展的工厂"); return base.CreateInstance(); } }
调用方式
IFactory sixFactory = new SixFactoryExtend();