定义
定义一个创建对象的接口,但由子类决定要实例的类是哪一个。工厂方法让类把实例推迟到子类。
设计原则
要依赖抽象,不要依赖具体的类:不能让高层组件依赖于底层组件,并且两者都应该依赖于抽象。
指导方针
- 变量不可以持有具体类的引用:如果使用new,就会持有具体类的引用。可以用工厂来避开这样的做法。
- 不要让类派生自具体类:如果派生自具体类,你就会依赖具体类。派生自一个抽象。
- 不要覆盖基类中已实现的方法:如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象。基类中所有实现的方法,应该由所有子类共享。
抽象工厂模式
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定的具体类。
第一次设计(识别变化)
假设我们有一个披萨店,我们需要写代码来制造一些不同类型的披萨。
下面来看看我们最开始的设计:
Pizza orderPizza(string type) { Pizza pizza; if (type.Equals("cheese")) { pizza = new CheesePizza(); } else if (type.Equals("greek")) { pizza = new GreekPizza(); } else if (type.Equals("pepperoni")) { pizza = new PepperoniPizza(); } else { pizza = new Pizza(); } pizza.perpare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; }
再这里我们根据type传入的类型来创建对应的pizza,但这里有一个问题,当我们需要修改一些pizza种类的时候,我们就必须要修改里面的代码。比如:不在提供GreekPizza的pizza,我们就必须删除创建GreekPizza的代码。这样就不符合我们的开放-关闭原则。
封装创建对象代码
下面,我们将创建pizza对象代码封装到一个单独的对象中,由这个对象专职创建pizza。
class SimplePizzaFactory { public Pizza createPizza(string type) { Pizza pizza = null; if (type.Equals("cheese")) { pizza = new CheesePizza(); } else if (type.Equals("greek")) { pizza = new GreekPizza(); } else if (type.Equals("pepperoni")) { pizza = new PepperoniPizza(); } else { pizza = new Pizza(); } } }
重做PizzaStore类
class PizzaStore { private SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory) { this.factory = factory; } Pizza orderPizza(string type) { Pizza pizza=null; pizza=factory.createPizza(type); pizza.perpare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
类图
这种简单的工厂其实并不是一个设计模式,反而比较像是一种编程习惯。
使用框架
下面我们把createPizza的方法放回PizzaStore中,但是要把它设置成"抽象方法",然后为每个区域创建不同的PizzaStore子类。让每个子类各自决定如何制造披萨。
public abstract class PizzaStore { //private SimplePizzaFactory factory; //public PizzaStore(SimplePizzaFactory factory) //{ // this.factory = factory; //} Pizza orderPizza(string type) { Pizza pizza = null; // factory.createPizza(type); //从工厂对象中移回PizzaStore中 pizza = createPizza(type); pizza.perpare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } //工厂对象移到这里 public abstract Pizza createPizza(string type); } }
在这里,orderPizza会对Pizza对象做许多的事情,但并不知道究竟是哪一种披萨,这里其实就是解耦。
开一家披萨店
public override Pizza createPizza(string type) { if (type.Equals("cheese")) { return new CheesePizza(); } //根据类型不同,创建其他对象 return null; }
工厂模式
所有工厂模式都用来封装对象创建的。
创建者类
Creator类是一个抽象类,它定义了一个抽象的工厂方法,让子类实现此方法制造产品。
子类可以利用createPrizza创建自己的产品。
产品类
对于上面的PizzaStore来说,Pizza就是产品。
定义工厂方法模式
工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推出到子类。
依赖倒置原则
当你直接实例化一个对象时,就是在依赖它的具体类。
在代码里减少对于具体类依赖是件"好事"。这个原则就是依赖倒置原则——要依赖抽象,不要依赖具体类。
不能让高层组件(由其他底层组件定义其行为的类)赖低层组件,不管高层还是底层,两者都应该依赖与抽象。
上面示例应用工厂模式后类图:
可以看到,高层组件(PizzaStore)和底层组件都依赖了Pizza抽象。
几个指导方针帮助你遵循此原则
- 变量不可以持有具体的引用
- 不要让类派生自具体类
- 不要覆盖基类中已经实现的方法
来源:https://www.cnblogs.com/Tan-sir/p/8269292.html