设计模式之工厂模式

来源:互联网 发布:添加网络打印机 不显示 编辑:程序博客网 时间:2024/06/05 04:30


看设计模式已经有一段时间了,感触颇深,现将工厂模式做一个总结。

面向对象的一个核心就是开放封闭原则,就是对扩展是开放的,对修改是封闭的,通过抽象工厂模式和反射方法的的灵活运用可以将该原则体现的淋漓尽致。

什么是工厂模式?工厂模式就是创建一系列相互依赖对象的接口,不用指明具体的要创建的类。

工厂模式又细分为简单工厂模式和抽象工厂模式。先看简单工厂模式。简单工厂模式需要一个有一个工厂类来负责创建不同的对象,比如创建一个查询数据库的用户表根据传进去的参数的类型进行不同对象的创建。eg:

public class SimPleFactory {public static final int DB_ORACLE = 1;public static final int DB_SQL = 2;public static IUser createUser(int type) {IUser result = null;// type = 1;switch (type) {case DB_ORACLE:result = new SQLUser();break;case DB_SQL:result = new OracleUser();break;}return result;}}

DataAccess类就是一个简单工厂模式,只要调用createUser方法就会返回不同的user对象。

而 抽象工厂模式是运用多态的技术,来创建不同的对象,他解决了简单工厂模式如果要新加一个对象类型需要修改工厂类的缺点,维护了面向对象的开放封闭原则。如果上面的代码用抽象工厂来实现可能类更多一些,复杂一些,但是它有良好的可扩展性,对于需求变化的项目作用不言而喻。

首先 得创建一个抽象工厂类:

public interface IAbstractFactory {        //创建用户信息表public IUserInfTable createUserInfTable();//创建用户表public IUser createUser();}
然后 再创建一个SQL的具体工厂类继承IAbstractFactory该方法实现了抽象工厂类的接口:
public class SQLFactory implements IAbstractFactory{@Overridepublic IUserInfTable createUserInfTable() {// TODO Auto-generated method stubreturn new SQLUserInfTable();}@Overridepublic IUser createUser() {// TODO Auto-generated method stubreturn new SQLUser();}
,接着创建一个Oracle的具体工厂类:
public class OracleFactory implements IAbstractFactory{@Overridepublic IUserInfTable createUserInfTable() {// TODO Auto-generated method stubreturn new OracleUserInfTable();}@Overridepublic IUser createUser() {// TODO Auto-generated method stubreturn new OracleUser();}}
一共 有几种对象类型就写几个这样的类,以后如果要增加新的对象类型的话IAbstractFactory工厂类也不用修改代码。客户端则应该这样调用:
    IFactory oracle = new OracleFactory();IUser user = oracle.createUser();user.insert();IUserInfTable table = oracle.createUserInfTable();table.insert();

但是抽象方法也有其缺点,它把具体创建那种类型的对象交给客户端来进行了:

 IFactory oracle = new OracleFactory();

因此,我们可以把两种工厂方法结合起来用:

public class SimPleAbstraFactory {public static final int DB_ORACLE = 1;public static final int DB_SQL = 2;public static IUser createUser(int type) {IUser result = null;// type = 1;switch (type) {case DB_ORACLE:result = new SQLFactory();break;case DB_SQL:result = new OracleFactory();break;}return result.createUser();}}
但是这样还是没解决增加新对象类型加switch的弊病。这时候我们就得用反射方法了,利用反射可以从根本上解决这个问题:

public class SimPleAbstractFactory {        //type是具体对象工厂方法的类名public static IUser createUser(String type) {IUser result = null;Class<?> demo = null;try {demo = Class.forName(type);// "Reflect.Person"} catch (Exception e) {e.printStackTrace();}IFactory fac = null;try {fac = (IFactory) demo.newInstance();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}result = fac.createUser();return result;}}

客户端代码如下:

IUser user = DataAccess.createUser("darren.designmodel.abstractfactory.OracleFactory");

user.insert();

当然我们可以把  darren.designmodel.abstractfactory.OracleFactory  字符串写在配置文件里面,这样就完美的解决了破坏开放封闭原则的代码。程序的源代码见附件,链接: http://download.csdn.net/detail/dongtaochen2039/5250493。

原创粉丝点击