工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
构成:
1.Product工厂方法创建的对象的接口
2.ConcreteProduct具体的产品,实现Product接口
3.Creator声明工厂方法,返回Product
4.ConcreteCreator实现/重写Creator的工厂方法,返回ConcreteProduct实例
UML类图:
实现
要生产的产品都实现一个接口
interface Product { string getName(); }
具体产品实现
class Phone : Product { private string name = "MyPhone"; public string getName() { return name; } }
工厂接口
interface Creator { Product createProduct(); }
具体工厂
class PhoneCreator : Creator { public Product createProduct() { return new Phone(); } }
使用
class Program { static void Main(string[] args) { Creator creator = new PhoneCreator(); Product phone= creator.createProduct(); Console.WriteLine(phone.getName()); Console.ReadKey(); } }
效果:
1.客户仅需处理Product接口,而不用知道它的具体实现是什么,符合针对接口编程的OO原则
2.要创建一个ConcreteProduct,就不得不创建一个ConcreteCreator
简单工厂:提供一个类,由它负责根据一定的条件创建某一具体类的实例,简单工厂不是一个设计模式(GOF没提,《HeadFirst设计模式》说像一种编程习惯)
UML类图:
构成:
1.SimpleFactory简单工厂,根据条件(参数)创建并返回一个实例
2. Product产品接口
3.ConcreteProduct具体产品,实现Product接口
以生产披萨为例,因为Pizza有许多不同口味,SimpleFactory根据客户的口味生产不同Pizza
class SimpleFactory { public Pizza getPizza(string type) { switch (type.Trim().ToLower()) { case "cheesepizza": return new CheesePizaa(); break; case "clampizza": return new ClamPizza(); break; default: return new NormalPizza(); break; } } }
Pizza接口
abstract class Pizza { virtual public string getName() { return "NormalPizza"; } }
不同口味的Pizza
class CheesePizaa : Pizza { override public string getName() { return "CheesePizaa"; } }
class ClamPizza : Pizza { override public string getName() { return "ClamPizza"; } }
class NormalPizza:Pizza { }
客户选择可以提供条件来获得不同的实例
class Program { static void Main(string[] args) { SimpleFactory factory = new SimpleFactory(); Pizza cheesePiz = factory.getPizza("CheesePizza"); Pizza clamPiz = factory.getPizza("ClamPizza"); Pizza NormalPiz = factory.getPizza(""); Console.WriteLine(cheesePiz.getName()); Console.WriteLine(clamPiz.getName()); Console.WriteLine(NormalPiz.getName()); Console.ReadKey(); } }
效果:
1.客户不再控制实例的创建,只需要使用,减少了客户的责任(单一责任原则?)
2.多个客户可以使用一个工厂,实现了代码复用
3.当实例的创建方法改变,并不影响客户(封装变化?)
4.当要添加产品就必须修改工厂,工厂方法模式一定程度上弥补了这个缺陷