• JAVA设计模式工厂模式


    JAVA设计模式--工厂模式

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

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

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

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

    public interface IFactoryDao {  
        public IUserDao createUserDao();  
        public IAddressDao createAddressDao();  
    }//工厂接口 

     

    public interface IAddressDao {  
        public  void add(Address address,int userId);  
        public void update(Address address);  
        public void delete(int id);  
          
    }//产品1接口  
    
     
    public interface IUserDao {  
        public void add(User user);  
        public void delete(int id);  
        public void update(User user);  
          
    }//产品2接口  
     
    
    
     
    public class UserJDBCDao implements IUserDao {  
      
        @Override  
        public void add(User user) {  
            System.out.println("UserJDBCDao....add");  
      
        }  
      
        @Override  
        public void delete(int id) {  
            System.out.println("UserJDBCDao....delete");  
      
        }  
      
        @Override  
        public void update(User user) {  
            System.out.println("UserJDBCDao....update");  
      
        }  
      
      
      
    }//针对JDBC的产品2实现  
    
    
     
    public class AddressJDBCDao implements IAddressDao {  
      
        @Override  
        public void add(Address address, int userId) {  
            System.out.println("addressJDBCDao....add");  
        }  
      
        @Override  
        public void update(Address address) {  
            System.out.println("addressJDBCDao....update");  
      
        }  
      
        @Override  
        public void delete(int id) {  
            System.out.println("addressJDBCDao....delete");  
      
        }  
      
          
      
    }//针对JDBC的产品1实现  
    
    
     
    public class JDBCDaoFactory implements IFactoryDao {  
        private static JDBCDaoFactory factory = new JDBCDaoFactory();  
          
        private JDBCDaoFactory(){}  
          
        public static IFactoryDao getInstance() {  
            return factory;  
        }  
      
        @Override  
        public IUserDao createUserDao() {  
            return new UserJDBCDao();  
        }  
      
        @Override  
        public IAddressDao createAddressDao() {  
            return new AddressJDBCDao();  
        }  
      
    }//工厂接口实现1(JDBC)  
    
    
    
     
    public class UserMySqlDao implements IUserDao {  
      
        @Override  
        public void add(User user) {  
            System.out.println("UserMySqlDao....add");  
      
        }  
      
        @Override  
        public void delete(int id) {  
            System.out.println("UserMySQlDao....delete");  
      
        }  
      
        @Override  
        public void update(User user) {  
            System.out.println("UserMySqlDao....update");  
      
        }  
      
          
      
    }//针对MySql的产品2实现  
    
    
    
     
    public class AddressMySqlDao implements IAddressDao {  
      
        @Override  
        public void add(Address address, int userId) {  
            System.out.println("addressMySqlDao....add");  
        }  
      
        @Override  
        public void update(Address address) {  
            System.out.println("addressMySqlDao...update");  
      
        }  
      
        @Override  
        public void delete(int id) {  
            System.out.println("addressMySqlDao....delete");  
      
        }  
      
          
      
    }//针对MySql的产品1实现  
    
    
    //工厂实现2(MySql)  
    public class MysqlDaoFactory implements IFactoryDao {
    private static IFactoryDao factory = new MysqlDaoFactory();  
        private MysqlDaoFactory() { }  
          
        public static IFactoryDao getInstance() {  
            return factory;  
        }  
          
        @Override  
        public IAddressDao createAddressDao() {  
            return new AddressMySqlDao();  
        }  
      
        @Override  
        public IUserDao createUserDao() {  
            return new UserMySqlDao();  
        }  
      
          
    }
     


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

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

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

    [java] view plain copy
     
    1. package com.yan.factory.dao;  
    2.   
    3.   
    4.   
    5. import java.lang.reflect.InvocationTargetException;  
    6. import java.lang.reflect.Method;  
    7. import java.util.Properties;  
    8.   
    9. public class DaoUtil {  
    10.       
    11.     public static IFactoryDao createDaoFactory() {  
    12.         IFactoryDao f = null;  
    13.         try {  
    14.             Properties prop = PropertiesUtil.getDaoProp();  
    15.             String fs = prop.getProperty("factory");  
    16.             Class clz = Class.forName(fs);  
    17.             String mn = "getInstance";  
    18.             Method m = clz.getMethod(mn);  
    19.             f = (IFactoryDao)m.invoke(clz);  
    20.         } catch (ClassNotFoundException e) {  
    21.             e.printStackTrace();  
    22.         } catch (SecurityException e) {  
    23.             e.printStackTrace();  
    24.         } catch (NoSuchMethodException e) {  
    25.             e.printStackTrace();  
    26.         } catch (IllegalArgumentException e) {  
    27.             e.printStackTrace();  
    28.         } catch (IllegalAccessException e) {  
    29.             e.printStackTrace();  
    30.         } catch (InvocationTargetException e) {  
    31.             e.printStackTrace();  
    32.         }  
    33.         return f;  
    34.     }  
    35. }  

    dao.properties文件

     
    1. factory=com.yan.factory.dao.JDBCDaoFactory  

    可修改配置文件测试。

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

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

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

    package com.yan.factory.dao;  
      
      
      
    import java.util.HashMap;  
    import java.util.Map;  
    import java.util.Properties;  
      
    public class PropertiesFactory implements IFactoryDao {  
        private static PropertiesFactory f = new PropertiesFactory();  
          
        private PropertiesFactory() {   }  
        public static IFactoryDao getInstance() {  
            return f;  
        }  
        @Override  
        public Object getDao(String name) {  
            try {  
                  
                Properties prop = PropertiesUtil.getDaoProp();  
                String cn = prop.getProperty(name);  
                Object obj = Class.forName(cn).newInstance();  
                System.out.println(obj);  
                return obj;  
            } 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;如有侵权,请联系删除.

     
  • 相关阅读:
    解决tomcat启东时一闪而过的问题
    如果数据库中的时间类型与mybatis的时间类型对应关系
    el 表达式中某一项过长时需要截取字符串长度,当悬停的时候显示全部内容
    ubuntu/linux系统中安装jdk以及eclipse(附图解详细步骤)
    Unity利用SMSSDK实现短信验证码(附代码)
    Unity利用Share SDK实现QQ、微信及微博第三方登录及定制内容分享(附代码)
    Unity编辑器扩展
    VR中射线点击按钮的实现
    Unity中几个特殊路径在各个平台的访问方式
    多态
  • 原文地址:https://www.cnblogs.com/yulibo/p/8908558.html
Copyright © 2020-2023  润新知