java设计模式之工厂方法
来源:互联网 发布:电魂网络千股千评 编辑:程序博客网 时间:2024/04/27 23:49
工厂方法模式使用的频率非常高,在我们日常的开发中总能见到它的身影。其定义为:Define an interface for creating an object,but let subclasses deide which class to instantiate.Factory Method lets a class defer instantitaion to subclasses.(定义一二个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使用一个类的实例化延迟到其子类。)
下面笔者提供一个比较实用的通用源码。
Product.java 抽象产品类,具体的产品类可以有多个,都集成于抽象产品类
package com.jaynol.designpatterns.factorymethod;public abstract class Product {/** * 产品类公共方法 * 可以考虑增加final关键字,防止子类重写,因为重写后会破坏封装性 */public void method1(){//业务逻辑实现}//抽象方法,供子类做个性化扩展public abstract void method2();}
ConcreteProduct1.java 具体产品类
package com.jaynol.designpatterns.factorymethod;public class ConcreteProduct1 extends Product{@Overridepublic void method2() {//业务逻辑实现System.out.println("ConcreteProduct1 业务逻辑");}}
ConcreteProduct2.java 具体产品类
package com.jaynol.designpatterns.factorymethod;public class ConcreteProduct2 extends Product{@Overridepublic void method2() {//业务逻辑实现System.out.println("ConcreteProduct2 业务逻辑");}}
Creator.java 抽象工厂
package com.jaynol.designpatterns.factorymethod;public abstract class Creator {/** * 创建一个产品对象,其输入参数类型可以自行设置 * 通常为String,Enum,Class等,当然也可以为空 */public abstract <T extends Product> T createProduct(Class<T> c);}
package com.jaynol.designpatterns.factorymethod;public class ConcreteCreator extends Creator{@Overridepublic <T extends Product> T createProduct(Class<T> c) {Product product = null;try{product = (Product) Class.forName(c.getName()).newInstance();}catch(Exception e){//异常处理}return (T)product;}}
Client.java 场景类
package com.jaynol.designpatterns.factorymethod;public class Client {/** * @param args */public static void main(String[] args) {//创建一个产Product的工厂Creator creator = new ConcreteCreator();//生产concreteProduct1这个类产品ConcreteProduct1 concreteProduct1 = creator.createProduct(ConcreteProduct1.class);concreteProduct1.method2();//生产concreteProduct2这个类产品ConcreteProduct2 concreteProduct2 = creator.createProduct(ConcreteProduct2.class);concreteProduct2.method2();}}
工厂方法模式的优点:
1.良好的封装性,代码结构清晰。一个对象的创建是有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的艰辛过程,降低模块间的耦合。
2.工厂方法模式的扩展性非常优秀。在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,就可以完成“拥抱变化”。例如在我们的例子中,需要增加一个ConcreteProduct3产品,只需要增加一个ConcreteProduct3类,工厂类都不用任何修改就能完成系统的扩展。
3.屏蔽产品类。这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。因为产品类的实例化工作是由工厂类负责的。一个产品的对象具体由那个一个产品生成是由工厂类决定的。在数据库开发中,大家因应该能够深刻体会到工厂方法模式的好处:如果使用JDBC连接数据库,数据库从MySQL切换到Oracle,需要改动的地方就是切换一下驱动名称(前提条件是SQL语句是标准语句),其他的都不需要修改,这是工厂方法模式灵活性的一个直接案例。
4.工厂方法模式是典型的解耦框架。高层模块只需要知道产品的抽象类,其他的实现类都不用关心,符合迪米特法则,则我不需要的就不要去交流;也复核依赖倒置原则,只依赖产品的抽象;当然也复核里氏替换原则,使用产品子类替换产品父类,没问题!
工厂方法模式扩展:
1.缩小为简单工厂模式
我们这样考虑一个问题:一个模块仅需要一个工厂类,没有必要把它生产出来,使用静态的方法就可以了,根据这一要求,笔者把上面例子中的Creator修改一下,代码如下:
package com.jaynol.designpatterns.factorymethod;public class SimpleFactoryMethod {public static <T extends Product> T createProduct(Class<T> c) {Product product = null;try{product = (Product) Class.forName(c.getName()).newInstance();}catch(Exception e){//异常处理}return (T)product;}}通过这样的修改,场景类修改如下:
package com.jaynol.designpatterns.factorymethod;public class Client {/** * @param args */public static void main(String[] args) {//生产concreteProduct1这个类产品ConcreteProduct1 concreteProduct1 = SimpleFactoryMethod.createProduct(ConcreteProduct1.class);concreteProduct1.method2();//生产concreteProduct2这个类产品ConcreteProduct2 concreteProduct2 = SimpleFactoryMethod.createProduct(ConcreteProduct2.class);concreteProduct2.method2();}}
2.升级为多个工厂
当我们做一个比较复杂的项目时,经常会遇到初始化一个对象是一件很复杂的事情,并且需要针对不同的产品的生产过程做定制,如果把这些逻辑都放在一个工厂里代码结构就不清晰了。例如,上面例子中的两个产品ConcreteProduct1和ConcreteProduct2,需要在生产ConcreteProduct1时给它初始化名字为ConcreteProduct1而ConcreteProduct2则需要初始化名字为ConcreteProduct2,把这段逻辑通过if eslse写在一个Creator里就不易于扩展和维护了。为了满足这种需求,需要把上面的工厂方法模式升级为多个工厂的方式,代码如下:
抽象工厂:
package com.jaynol.designpatterns.factorymethod;public abstract class AbstractCreator {protected abstract Product createProduct();}
生产ConcreteProduct1的工厂:
package com.jaynol.designpatterns.factorymethod;public class ConcreteProduct1Creator extends AbstractCreator{@Overrideprotected Product createProduct() {/** * 可在此处实现初始化的逻辑 */return new ConcreteProduct1();}}
生产ConcreteProduct2的工厂:
package com.jaynol.designpatterns.factorymethod;public class ConcreteProduct2Creator extends AbstractCreator{@Overrideprotected Product createProduct() {/** * 可在此处实现初始化的逻辑 */return new ConcreteProduct2();}}
场景类如下:
package com.jaynol.designpatterns.factorymethod;public class Client {/** * @param args */public static void main(String[] args) {//生产concreteProduct1这个类产品Product concreteProduct1 = (new ConcreteProduct1Creator()).createProduct();concreteProduct1.method2();//生产concreteProduct2这个类产品Product concreteProduct2 = (new ConcreteProduct2Creator()).createProduct();concreteProduct2.method2();}}
- JAVA设计模式之工厂模式之工厂方法模式
- Java设计模式之工厂方法模式
- Java设计模式之工厂方法模式
- java设计模式之工厂方法模式
- Java设计模式之工厂方法模式
- Java设计模式之工厂方法模式
- java设计模式之工厂方法模式
- Java设计模式之工厂方法模式
- Java设计模式之工厂方法模式
- Java设计模式之工厂方法模式
- 【Java设计模式】之工厂方法模式
- Java设计模式之工厂方法模式
- java设计模式之工厂方法模式
- Java设计模式之工厂方法模式
- java设计模式之"工厂方法模式"
- Java设计模式之工厂方法模式
- Java设计模式之工厂方法模式
- java之设计模式---工厂方法模式
- Windows 8实例教程系列 - 数据绑定高级实例
- 构建高可扩Web架构和分布式系统实战(上)
- truncate 和 delete删除表的区别比较
- STL填充与生成(fill,fill_n,generate,generate_n)的用法
- DevExpress DXTREME多渠道应用
- java设计模式之工厂方法
- Hadoop中Partition解析
- Linux下压缩文件、解压缩文件命令详解 [转]
- poj3481
- 利用directshow修改曝光、增益等参数。
- Java中垃圾回收机制
- 手机屏幕的总结
- mysql longtext问题
- arp高速缓存保存时间