《Head First 设计模式》之工厂方法模式
2014-07-15 22:38
218 查看
书上举的例子讲的是创建各个不同城市的PizzaStore的例子,感觉不是一两句话讲的清的,还是直接看模式的定义吧,然后对比实际的例子返回到定义和类图,这样应该会更有感觉。
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类
下面的代码和书上的代码有出入,只是为了反映工厂方法的基本,没有书上的全,如果需要全部的代码,还是看书对应的源代码
1.Creator类,PizzaStore类是一个抽象类,其中的factoryMethod方法是createPizza方法
书上还用该模式引用了一个设计原则,依赖倒置原则:要依赖抽象,不要依赖具体类。书上说这个原则说明了:不能让高层组件依赖底层组件,而是不管高层组件和底层组件,“两者”都应该依赖与抽象。而所谓的“高层”组件,是由其他底层组件定义其行为的类。如本例中的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")。
如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步
文章转载请注明出处,请尊重知识产权
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类
下面的代码和书上的代码有出入,只是为了反映工厂方法的基本,没有书上的全,如果需要全部的代码,还是看书对应的源代码
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")。
如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步
文章转载请注明出处,请尊重知识产权
相关文章推荐
- head first 设计模式学习之 简单工厂,工厂方法和抽象工厂
- <Head First 设计模式>:工厂模式1:方法模式--Pizza
- Head First 设计模式 —— 工厂模式与工厂方法
- Head First 设计模式学习——简单工厂方法-工厂方法模式-抽象工厂模式
- 设计模式之工厂方法
- JAVA设计模式——工厂方法(Factory Method)模式
- 设计模式--工厂方法
- 设计模式示例一 Factory Method(工厂方法)
- 设计模式(1)工厂方法 感觉没必要用工厂方法
- C# 设计模式 之 工厂方法
- 设计模式 之 工厂方法
- GoF 23个经典的设计模式03--创建模式之工厂方法(未完代续)
- 设计模式之Factory1(简单工厂,工厂方法,抽象工厂的比较)
- 每周一个设计模式之工厂方法与抽象工厂
- 设计模式学习笔记四:工厂方法(Factory Method)
- 设计模式(三)、FACTORY METHOD(工厂方法)---对象创建型模式
- 设计模式--工厂方法
- 第二个设计模式:工厂方法
- 设计模式示例一 Factory Method(工厂方法)
- 设计模式 之 工厂方法