java工厂模式dao_JAVA设计模式--工厂模式

JAVA设计模式--工厂模式

工厂模式分为简单工厂、工厂方法模式和抽象工厂模式。简单工厂顾名思义是最简单的,从一个工厂获取所需的产品类似于factory.getProduct1();或factory.getProduct2(),最经典的运用switch语句。简单工厂要增加产品要修改源码,破坏ocp原则(对扩展开放,修改封闭)

57a06dfd0600cf5b23ccae0606c056e6.png

工厂方法模式与简单工厂最不一样的是工厂方法模式有工厂接口

eb849ad8046f097b03a9c7c238bcedc3.png

抽象工厂模式与工厂方法模式最大的不同:工厂方法模式的产品都衍生于同一个接口或抽象类,而抽象工厂模式的产品衍生自不同的接口或抽象类。因为工厂方法模式针对一个产品等级结构,而抽象工厂方法针对多个,分别对应一个接口(抽象类)和多个接口(抽象类)。什么产品等级结构?举个例子,比如车子,分奥迪和宝马,而奥迪和宝马分为大排量和小排量的,那么大排量的奥迪和小排量的奥迪属于同一产品等级结构,而大排量的奥迪和大排量的宝马属于同一产品族。如果针对一个产品等级结构,也就是奥迪或宝马,那么工厂产品为一个产品等级结构就使用工厂方法模式,如果针对多个,如宝马和奥迪,那么就使用抽象工厂模式,它的产品是一个产品族。这就是它们的应用场景。

3052e8da7824898b99237fb83ee4c092.png

这里用一个例子熟悉一下抽象工厂模式。(使用单例模式避免大量工厂创建,浪费资源,不懂看前面有一篇说单例的)

public interfaceIFactoryDao {publicIUserDao createUserDao();publicIAddressDao createAddressDao();

}//工厂接口

public interfaceIAddressDao {public void add(Address address,intuserId);public voidupdate(Address address);public void delete(intid);

}//产品1接口

public interfaceIUserDao {public voidadd(User user);public void delete(intid);public voidupdate(User user);

}//产品2接口

public class UserJDBCDao implementsIUserDao {

@Overridepublic voidadd(User user) {

System.out.println("UserJDBCDao....add");

}

@Overridepublic void delete(intid) {

System.out.println("UserJDBCDao....delete");

}

@Overridepublic voidupdate(User user) {

System.out.println("UserJDBCDao....update");

}

}//针对JDBC的产品2实现

public class AddressJDBCDao implementsIAddressDao {

@Overridepublic void add(Address address, intuserId) {

System.out.println("addressJDBCDao....add");

}

@Overridepublic voidupdate(Address address) {

System.out.println("addressJDBCDao....update");

}

@Overridepublic void delete(intid) {

System.out.println("addressJDBCDao....delete");

}

}//针对JDBC的产品1实现

public class JDBCDaoFactory implementsIFactoryDao {private static JDBCDaoFactory factory = newJDBCDaoFactory();privateJDBCDaoFactory(){}public staticIFactoryDao getInstance() {returnfactory;

}

@OverridepublicIUserDao createUserDao() {return newUserJDBCDao();

}

@OverridepublicIAddressDao createAddressDao() {return newAddressJDBCDao();

}

}//工厂接口实现1(JDBC)

public class UserMySqlDao implementsIUserDao {

@Overridepublic voidadd(User user) {

System.out.println("UserMySqlDao....add");

}

@Overridepublic void delete(intid) {

System.out.println("UserMySQlDao....delete");

}

@Overridepublic voidupdate(User user) {

System.out.println("UserMySqlDao....update");

}

}//针对MySql的产品2实现

public class AddressMySqlDao implementsIAddressDao {

@Overridepublic void add(Address address, intuserId) {

System.out.println("addressMySqlDao....add");

}

@Overridepublic voidupdate(Address address) {

System.out.println("addressMySqlDao...update");

}

@Overridepublic void delete(intid) {

System.out.println("addressMySqlDao....delete");

}

}//针对MySql的产品1实现

//工厂实现2(MySql)

public class MysqlDaoFactory implementsIFactoryDao {

private static IFactoryDao factory = newMysqlDaoFactory();privateMysqlDaoFactory() { }public staticIFactoryDao getInstance() {returnfactory;

}

@OverridepublicIAddressDao createAddressDao() {return newAddressMySqlDao();

}

@OverridepublicIUserDao createUserDao() {return newUserMySqlDao();

}

}

由两个工厂可以发现,两个工厂里的产品都是产品族(AddressMySqlDao和AddressJDBCDao是同一个接口的实现)

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

在项目中调用工厂1或2也要修改代码,这也不好,因此可以用反射。把要创建的工厂className写在配置文件这样只需修改配置文件即可,灵活、不破坏封装性、ocp。

package com.yan.factory.dao;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.Properties;

public class DaoUtil {

public static IFactoryDao createDaoFactory() {

IFactoryDao f = null;

try {

Properties prop = PropertiesUtil.getDaoProp();

String fs = prop.getProperty("factory");

Class clz = Class.forName(fs);

String mn = "getInstance";

Method m = clz.getMethod(mn);

f = (IFactoryDao)m.invoke(clz);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

}

return f;

}

}

dao.properties文件

factory=com.yan.factory.dao.JDBCDaoFactory

可修改配置文件测试。

在项目中private IAddressDao addressDao = DaoUtil.createDaoFactory().createAddressDao();即可

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

上面有点缺点就是太繁杂,要创建多个工厂实例,我们可以利用反射,只创建一个工厂,把要创建的Dao写在配置文件

packagecom.yan.factory.dao;importjava.util.HashMap;importjava.util.Map;importjava.util.Properties;public class PropertiesFactory implementsIFactoryDao {private static PropertiesFactory f = newPropertiesFactory();privatePropertiesFactory() { }public staticIFactoryDao getInstance() {returnf;

}

@OverridepublicObject getDao(String name) {try{

Properties prop=PropertiesUtil.getDaoProp();

String cn=prop.getProperty(name);

Object obj=Class.forName(cn).newInstance();

System.out.println(obj);returnobj;

}catch(InstantiationException e) {

e.printStackTrace();

}catch(IllegalAccessException e) {

e.printStackTrace();

}catch(ClassNotFoundException e) {

e.printStackTrace();

}return null;

}

}

factory=com.yan.factory.dao.PropertiesFactory

UserDao="com.yan.factory.dao.UserJDBCDao"

转载:https://blog.csdn.net/empyan/article/details/54897088;如有侵权,请联系删除.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值