《Head First 设计模式》之工厂方法模式

   书上举的例子讲的是创建各个不同城市的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容器实现控制反转的主要方式。



   工厂方法模式的应用,在Spring中有一个FactoryBean,是Spring容器提供的一种可以扩展容器对象实例化逻辑的接口,FactoryBean只是一个Bean而已,主语是Bean,定语是Factory,不要和BeanFactory弄混淆,BeanFactory是一个生产Bean的工厂,主语是 Factory,定语是Bean。当我们实现FactoryBean接口,实现它的Object getObject()方法,该方法就会返回该FactoryBean“生产”的对象实例,然后就可以再xml文件中像其他bean一样定义了,其中调用getBean("beanId")方法直接会返回的 “生产”的对象实例,如果在spring中需要获得该FactoryBean,则需要加上&,如getBean("&beanId")。


如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步

文章转载请注明出处,请尊重知识产权

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值