java-工厂模式
1,简单工厂
package com.yangwei.shop.dao; public class DaoFactory { public static IAddressDao getAddressDao(){ return new AddressDao(); } public static IUserDao getUserDao(){ return new UserDao(); } }
public class TestAddress { private static IAddressDao addressDao=DaoFactory.getAddressDao(); //使用简单工厂创建dao对象 public static void main(String[] args){ testLoad(); }public static void testLoad(){ Address add=addressDao.loadAddress(3); System.out.println(add.getName()+add.getUser().getUsername()); } }
2, 简单工厂的缺陷
简单工厂违背了java的OCP(open close principle)原则,即对增加开发对修改关闭 如果要符号OCP原则,必须针对接口编程
3,工厂方法
package com.yangwei.shop.dao; public interface IDaoFactory { public IUserDao createUserDao(); public IAddressDao createAddressDao(); }
jdbc实现:
package com.yangwei.shop.dao; public class DaoFactoryJdbc implements IDaoFactory { @Override public IUserDao createUserDao() { return new UserJdbcDao(); } @Override public IAddressDao createAddressDao() { return new AddressJdbcDao(); } }
// mybatis 实现
package com.yangwei.shop.dao; public class DaoFactoryMybatis implements IDaoFactory { @Override public IUserDao createUserDao() { return new UserDao(); } @Override public IAddressDao createAddressDao() { return new AddressDao(); } }
使用方式 :
private static IAddressDao addressDao=new DaoFactoryMybatis().createAddressDao();
其实这种还是违背着ocp原则,因为 还是要new DaoFactoryMybatis(),new DaoFactoryJdbc()等
怎么让它不违背ocp原则呢,只能使用配置文件的形式?
package com.yangwei.shop.dao; /**dao工厂接口*/ public interface IDaoFactory { public IUserDao createUserDao(); public IAddressDao createAddressDao(); }
package com.yangwei.shop.dao; public class DaoFactoryJdbc implements IDaoFactory { /**增加了单例模式*/ private static IDaoFactory factory=new DaoFactoryJdbc(); private DaoFactoryJdbc(){} public static IDaoFactory getInstance(){ return factory; } @Override public IUserDao createUserDao() { return new UserJdbcDao(); } @Override public IAddressDao createAddressDao() { return new AddressJdbcDao(); } }
package com.yangwei.shop.dao; /**mybatis工厂实现,也是单例模式*/ public class DaoFactoryMybatis implements IDaoFactory { private static IDaoFactory factory=new DaoFactoryMybatis(); private DaoFactoryMybatis(){} public static IDaoFactory getInstance(){ return factory; } @Override public IUserDao createUserDao() { return new UserDao(); } @Override public IAddressDao createAddressDao() { return new AddressDao(); }
properties文件读取工具类 package com.yangwei.shop.util; import java.io.IOException; import java.util.Properties; public class PropertiesUtil { private static Properties jdbcProp; private static Properties daoProp; /** * 获取jdbc.properties内容 * @return */ public static Properties getJdbcProp() { try { if(jdbcProp==null) { jdbcProp = new Properties(); jdbcProp.load(PropertiesUtil.class.getClassLoader().getResourceAsStream("jdbc.properties")); } } catch (IOException e) { e.printStackTrace(); } return jdbcProp; } public static Properties getDaoProp() { try { if(daoProp==null) { daoProp = new Properties(); daoProp.load(PropertiesUtil.class.getClassLoader().getResourceAsStream("dao.properties")); } } catch (IOException e) { e.printStackTrace(); } return daoProp; } }
package com.yangwei.shop.util; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties; import com.yangwei.shop.dao.IDaoFactory;
/**dao工具类,主要使用反射机制*/ public class DaoUtil { public static IDaoFactory createDaoFactory(){ Properties prop = PropertiesUtil.getDaoProp(); try { Class clz=Class.forName((String)prop.get("factory"));
//每一个工厂都有方法 getInstance方法 String mm="getInstance"; Method method=clz.getMethod(mm); //调用静态方法 使用类来调用 return (IDaoFactory)method.invoke(clz); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
使用方式: private static IAddressDao addressDao=DaoUtil.createDaoFactory().createAddressDao();
dao.properties配置文件内容
factory=com.yangwei.shop.dao.DaoFactoryMybatis #factory=com.yangwei.shop.dao.DaoFactoryJdbc
前面的方法已经很好了,我们再进行一次简化,将UserDao,AddressDao也写到配置文件中,不要那么多的工厂
package com.yangwei.shop.dao; /**dao工厂接口*/ public interface IDaoFactory { /** *根据dao名称获取相应的dao */ public Object getDao(String daoName); }
dao.properties配置文件
factory=com.yangwei.shop.dao.PropertyFactory
#factory=com.yangwei.shop.dao.DaoFactoryJdbc
userDao=com.yangwei.shop.dao.UserDao
addressDao=com.yangwei.shop.dao.AddressDao
IDaoFactory接口的一个唯一实现类PropertyFactory
package com.yangwei.shop.dao; import java.util.HashMap; import java.util.Map; import com.yangwei.shop.util.PropertiesUtil; public class PropertyFactory implements IDaoFactory{ //单例化 private static PropertyFactory f=new PropertyFactory(); private PropertyFactory(){} public static PropertyFactory getInstance(){ return f; } //已经存在的dao private Map<String,Object> daos=new HashMap<String,Object>(); @Override public Object getDao(String daoName) { //1, 从map获取,如果存在就直接返回 Object obj=daos.get(daoName); if(obj!=null){ return obj; } //2,根据指定dao名称从配置文件中获取类名 String className= PropertiesUtil.getDaoProp().getProperty(daoName); try { //3,利用反射创建对象 obj=Class.forName(className).newInstance(); daos.put(daoName, obj); return obj; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } }
//使用 private static IAddressDao addressDao=(IAddressDao) DaoUtil.createDaoFactory().getDao("addressDao");
----------- 赠人玫瑰,手有余香 如果本文对您有所帮助,动动手指扫一扫哟 么么哒 -----------
未经作者 https://www.cnblogs.com/xin1006/ 梦相随1006 同意,不得擅自转载本文,否则后果自负