书上举的例子讲的是创建各个不同城市的PizzaStore的例子,感觉不是一两句话讲的清的,还是直接看模式的定义吧,然后对比实际的例子返回到定义和类图,这样应该会更有感觉。
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类
下面的代码和书上的代码有出入,只是为了反映工厂方法的基本,没有书上的全,如果需要全部的代码,还是看书对应的源代码
1.Creator类,PizzaStore类是一个抽象类,其中的factoryMethod方法是createPizza方法
package factorymethod;
public abstract class PizzaStore {
public Pizza orderPizza(String type){
Pizza pizza;
pizza = createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
pizza.box();
return pizza;
}
abstract Pizza createPizza(String type);
}
2. NYPizzaStore是PizzaStore的具体实现类,仅实现了工厂方法createPizza
package factorymethod;
public class NYPizzaStore extends PizzaStore {
@Override
Pizza createPizza(String type) {
if(type.equals("cheese")){
return new NYStyleCheesePizza();
}
else return null;
}
}
3.Product类,这里是Pizza类
package factorymethod;
import java.util.ArrayList;
public abstract class Pizza {
String name;
String dough;
String sauce;
ArrayList toppings = new ArrayList();
void prepare(){
System.out.println("Preparing "+name);
for (int i = 0; i < toppings.size(); i++) {
System.out.println(" "+toppings.get(i));
}
}
void bake(){
System.out.println("Bake for 25 minutes at 350");
}
void cut(){
System.out.println("Cutting the pizza into diagonal slices");
}
void box(){
System.out.println("Place pizza in official PizzaStore box");
}
public String getName(){
return name;
}
}
4.具体产品类,这里是继承Pizza类
package factorymethod;
public class NYStyleCheesePizza extends Pizza {
public NYStyleCheesePizza(){
name = "NY Style Sauce and Cheese Pizza";
dough = "Thin Crust Dough";
sauce = "Marinara Sauce";
toppings.add("Grated Reggiano Cheese");
}
}
5.测试类
package factorymethod;
public class PizzaTestDrive {
public static void main(String[] args) {
PizzaStore nyStore = new NYPizzaStore();
Pizza pizza = nyStore.orderPizza("cheese");
System.out.println("Ethan ordered a"+pizza.getName()+"\n");
}
}
书上还用该模式引用了一个设计原则,依赖倒置原则:要依赖抽象,不要依赖具体类。书上说这个原则说明了:不能让高层组件依赖底层组件,而是不管高层组件和底层组件,“两者”都应该依赖与抽象。而所谓的“高层”组件,是由其他底层组件定义其行为的类。如本例中的PizzaStore是个高层组件,因为他的行为是由披萨定义的。这个依赖倒置我理解的还是不是很深,感觉可能是代码或者业务接触少了。
其中还有两个概念是依赖注入和控制反转,参考的文章http://openwares.net/java/dip_ioc_di.html
控制反转IoC(Inversion of Control)
通常情况下,class A依赖于class B,或者应用DIP之后依赖于Interface B,那么在运行时,我们必须自行主动的去实例化Interface B接口的实现类实例,然后将其引用传递给Class A,在传统的编程模型下,我们经常这样干。这样耦合度仍然很高,我们必须知道所依赖的实现类的一些细节。
而IoC则是将实例化被依赖模块的责任交出去,不再主动去做依赖装配工作,这样我们就可以彻底的只针对接口编程,而无需关心具体的实现。
IoC容器成为一个系统的对象容器和粘合剂,它负责创建对象的实例,并按照它们声明的依赖关系把它们粘合起来共同工作。通过配置文件或注解的方法,IoC容器会自动的满足模块之间的依赖关系,而无需我们再主动去处理依赖关系,只要被动接受就可以了。
这种依赖关系的满足由主动实现到被动接受的转变,就是所谓的控制反转了。其中依赖注入是实现控制反转的主要方式。
总的来讲,依赖倒置(DIP)是一种设计原则,控制反转(IoC)是一种处理对象间依赖关系的方式,与传统的主动方式正好相反,而依赖注入(DI)则是IoC容器实现控制反转的主要方式。
如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步
文章转载请注明出处,请尊重知识产权