在进行工厂模式的实践前先了解下软件世界里两条重要的原则
1、里式代换原则:一个软件实体如果使用的是父类的话,那么一定可以被替换成他的子类,并且程序觉察不出父类对象与子类对象之间的区别,也就是说在软件世界里面把父类替换成子类程序是不会发生变化的。只有当子类替换掉父类后软件单位功能不受影响,才能真正发挥父类的抽象作用,子类可以在父类的基础上增加自己的特有功能。
2、开放-封闭原则:该原则阐述了软件世界里的两大规则1)向扩展开放2)向修改关闭,说的是当需求发生变化时,应该尽可能的通过扩展程序来达到目的,而非修改程序。
2、开放-封闭原则:该原则阐述了软件世界里的两大规则1)向扩展开放2)向修改关闭,说的是当需求发生变化时,应该尽可能的通过扩展程序来达到目的,而非修改程序。
- 简单工厂模式
一般在工厂方法中通过传入的参数进行判断并由此决定生产出类型匹配的实现实体。当增加一个业务实现时只需要更改工厂方法的判断逻辑即可
/**
*计算器接口,可能由此派生出各种不同实现的计算器类
*/
public interface Operate
{
public Integer execute(Integer oper1,Integer oper2);
/**
*具体的计算器类,实现了加法计算
*/
public class AddOperate implements Operate
{
@Override
public Integer execute (Integer oper1, Integer oper2)
{
return oper1+oper2;
}
/**
*具体的计算器类,实现了减法计算
*/
public class SubOperate implements Operate
{
/* (non-Javadoc)
* @see net.carefx.pattern.Operate#execute(java.lang.Integer, java.lang.Integer)
*/
@Override
public Integer execute (Integer oper1, Integer oper2)
{
// TODO Auto-generated method stub
return oper1-oper2;
}
/**
*简单工厂模式,通过传入的类型来为客户端生成不同类型的真实计算器
*/
public class SimpFactory
{
public Operate getOperate (String type)
{
if ("add".equals (type))
{
return new AddOperate ();
}
else if ("sub".equals (type))
{
return new SubOperate ();
}
else
{
throw new RuntimeException ("the operating dose not surpport!!");
}
}
2、工厂方法模式:提供了一个抽象的工厂接口,将具体实现实体的初始化工作延迟到具体的工厂,即需要为每一个实现提供一个具体工厂类,这样一来当增加一个业务实现时不再需要修改相关工厂代码,而只需要增加新的业务类和与之对应的具体工厂类即可。使得程序更符合“开闭原则”的设计理念。但此时需要修改客户端(根据需要不同的实现调用不同的工厂实现,其实还是要修改,只是相比简单工厂模式修改的要少,但缺点也比较明显,会增加大量的工厂类,并且效果上感觉和直接使用业务实现的接口没有什么区别(其实是使用了依赖倒转的策略,不需要自己主动的去调用构造函数,而是通过其他的途径注入进来))
/**
*工厂方法抽象
*/
public interface OperateFactory
{
public Operate getOperate();
/**
*加法计算器工厂实现
*/
public class AddOperateFactory implements OperateFactory
{
/* (non-Javadoc)
* @see net.carefx.pattern.OperateFactory#getOperate()
*/
@Override
public Operate getOperate ()
{
// TODO Auto-generated method stub
return new AddOperate ();
}
/**
*减法计算器工厂实现
*/
public class SubOperateFactory implements OperateFactory
{
/* (non-Javadoc)
* @see net.carefx.pattern.OperateFactory#getOperate()
*/
@Override
public Operate getOperate ()
{
// TODO Auto-generated method stub
return new SubOperate ();
}
3、抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口、无需指定他们具体的类(工厂方法模式一般只负责创建一类接口,而这里是一系列,这也是两者不同的地方),具体说是一个抽象工厂接口,它里面应该包含所有的产品创建的抽象方法。并且在运行时刻再创建一个具体的工厂实例,并且由他来创建不同的产品对象,其最大好处为易于更换产品系列。
/**
*用户信息数据访问层接口,可以基于ibatis或hibnate等不同技术有不同的实现
*/
public interface UserDao
{
public void addUser(Object user);
/**
*角色信息数据访问层接口,可以基于ibatis或hibnate等不同技术有不同的实现
*/
public interface RoleDao
{
public void addRole(Object role);
/**
*userDao基于ibatis的实现
*/
public class UserDaoIbatisImpl implements UserDao
{
/* (non-Javadoc)
* @see net.carefx.pattern.UserDao#addUser(java.lang.Object)
*/
@Override
public void addUser (Object user)
{
System.out.println (user);
}
/**
*userDao基于hibernate的实现
*/
public class UserDaoHibernateImpl implements UserDao
{
/*
* (non-Javadoc)
*
* @see net.carefx.pattern.UserDao#addUser(java.lang.Object)
*/
@Override
public void addUser (Object user)
{
// TODO Autos-generated method stub
System.out.println (user);
}
/**
*RoleDao基于ibatis的实现
*/
public class RoleDaoIbatisImpl implements RoleDao
{
/* (non-Javadoc)
* @see net.carefx.pattern.RoleDao#addRole(java.lang.Object)
*/
@Override
public void addRole (Object role)
{
// TODO Auto-generated method stub
System.out.println (role);
}
/**
*RoleDao基于hibernate的实现
*/
public class RoleDaoHibernateImpl implements RoleDao
{
/* (non-Javadoc)
* @see net.carefx.pattern.RoleDao#addRole(java.lang.Object)
*/
@Override
public void addRole (Object role)
{
// TODO Auto-generated method stub
System.out.println (role);
}
/**
*抽象工厂方法接口,能够同时生产出UserDao与RoleDao
*/
public interface AbstractFacotry
{
public UserDao getUserDao();
public RoleDao getRoleDao();
/**
*能够同时生产出RoleDao与UserDao的Ibatis实现的具体工厂类
*/
public class IbatisDaoFactory implements AbstractFacotry
{
/* (non-Javadoc)
* @see net.carefx.pattern.AbstractFacotry#getRoleDao()
*/
@Override
public RoleDao getRoleDao ()
{
// TODO Auto-generated method stub
return new RoleDaoIbatisImpl ();
}
/* (non-Javadoc)
* @see net.carefx.pattern.AbstractFacotry#getUserDao()
*/
@Override
public UserDao getUserDao ()
{
// TODO Auto-generated method stub
return new UserDaoIbatisImpl ();
}
/**
*能够同时生产出RoleDao与UserDao的Hibernate实现的具体工厂类
*/
public class HibernateDaoFactory implements AbstractFacotry
{
/* (non-Javadoc)
* @see net.carefx.pattern.AbstractFacotry#getRoleDao()
*/
@Override
public RoleDao getRoleDao ()
{
// TODO Auto-generated method stub
return new RoleDaoHibernateImpl ();
}
/* (non-Javadoc)
* @see net.carefx.pattern.AbstractFacotry#getUserDao()
*/
@Override
public UserDao getUserDao ()
{
// TODO Auto-generated method stub
return new UserDaoHibernateImpl ();
}
4、抽象工厂模式的改进:反射+抽象工厂模式,在所有用简单工厂的地方,都可以考虑用反射技术来消除switch或if,解除分之判断带来的耦合。
/**
*通过反射和配置文件动态的决定生产出什么类型的Dao
*/
public class WithReflectDaoFactory
{
public static final String DAO_TYPE="HibernateImpl";
public UserDao getUserDao(){
try
{
return (UserDao)Class.forName ("net.carefx.pattern.factorypattern"+"UserDao"+DAO_TYPE).newInstance ();
}
catch ( Exception e)
{
throw new RuntimeException (e);
}
}
public RoleDao getRoleDao(){
try
{
return (RoleDao)Class.forName ("net.carefx.pattern.factorypattern"+"RoleDao"+DAO_TYPE).newInstance ();
}
catch ( Exception e)
{
throw new RuntimeException (e);
}
}