工程(factory)除了创建对象的细节。我觉得还是先记下书上的例子吧,再说了,这个例子很有意思。我们创建一个简单的披萨工厂类(simplePizzaFactory)。
public class SimplePizzaFactory
{
public Pizza CreatePizza(string type)
{
Pizza pizza=null;
if(type.equals("cheese"))
pizza=new CheesePizza();
else if(type.equals("pepperoni"))
pizza=new PepperoniPizza();
else if(type.equals("clam"))
pizza=new ClamPizza();
else if(type.equals("veggie"))
pizza=new VeggiePizza();
return pizza
}
}
下面我们再做个披萨店的类,这个类使用披萨工厂来创建披萨
public class PizzaStore{
SimplePizzaFactory factory;
public PizzaStore(SimplePizzaFactory factory)
{
this.factory=factory;
}
public Pizza orderPizza(string type)
{
Pizza=pizza;
pizza=factory.CreatePizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
由于经营得当,开分店已经是这个世界上最正常不过的事情了,为了体现地方特色,我们希望我们开的分店(或是说加盟店)能够加入当地的特色来做披萨,所以,我们把披萨的生产下放到每一个分店中。下面是我们重新设计的代码:
public abstract class PizzaStore { public Pizza OrderPizza(string pizzaType) { Pizza pizza = new Pizza(); pizza = CreatePizza(pizzaType); pizza.PrePare(); pizza.Bake(); pizza.Cut(); pizza.Box(); return pizza; } public abstract Pizza CreatePizza(string pizzaType); }
下面我们就可以开一家披萨加盟店了,也就是具体实现CreatePizza函数的子类。
public class NYPizzaStore : PizzaStore { public Pizza CreatePizza(string item) { if (item.Equals("cheese")) return new NYCheesePizza(); else return null; } }
这里是完整的代码 PizzaStore.rar
所有的工厂模式都是用来封装对象的创建。工厂方法模式(Factory Method Pattern)通过让子类决定该创建的对象时什么,来达到将对象创建的过程封装的目的。在工厂模式里面,我们要弄清楚两个重要的角色。
1.创建类(Creator)类
这是抽象创建者类,它定义了一个抽象的工厂方法,让子类实现此方法制造产品。创建者通常会包含依赖于抽象产品的代码,而这些抽象产品偶子类制造。创建者不需要真的知道在制造哪中具体产品。也就是这里的PizzaStore类。其中的CreatePizza()方法正是工厂方法,用来制造产品。
2.产品类,也就是这里的Pizza类。工厂生产产品。对PizzaStore来说,产品就是Pizza。
这两个类层级为什么是平行的:因为它们都有抽象类,而抽象类都有许多具体的子类,每个之类都有自己特定的实现。
工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类时哪一个。工厂方法让类把实例化推迟到子类。
依赖倒置原则(Dependency Inversion Principle)设计原则:要依赖抽象,不要依赖具体类。不要让高层组件依赖于底层组件,而且,不管高层或低层组件,“两者”都应该依赖于抽象。所谓“高层”组件,是由其他底层组件定义其行为的类。例如,PizzaStore是个高层组件,因为它的行为是又披萨地沟油的:PizzaSotre创建所有不同的比萨对象,准备。烘烤。切片,装盒。而比萨本身属于底层组件。
几个指导方针帮助我们遵循依赖倒置原则:
1.变量不可以持有具体类的引用。如果使用new,就会持有具体类的引用。你可以改用工厂来避开这样的做法。
2.不要让类派生自具体类。如果派生自具体类,你就会依赖具体类。请派生自一个抽象(接口或抽象类)。
3.不要覆盖基类中已经实现的方法。如果覆盖基类已经实现的方法,那么你的基类就不是一个真正适合被继承的抽象基类中已经实现的方法,应该有所有的子类共享。
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
一张很复杂的图,一张我没有看懂的图
本书中还比较了工厂方法和抽象工厂,我觉得那个对话很有意思,我想概括为一句话,工厂方法利用继承来创建对象,而抽象工厂利用类的组合来创建对象。
这里是比较完整的一个程序框架(子所以叫框架,是因为没有完成一些功能,仅仅是框架层面上的完成了)。