• 设计模式之——工厂模式


    一、相关概念了解

    首先知晓什么是工厂模式(概念)?

      ①实例化对象,用工厂方法代替new操作。②工厂模式包括工厂方法模式和抽象工厂模式。③抽象工厂模式是工厂方法模式的拓展。

    其次明白工厂模式的意图

      ①定义一个借口来创建对象,但是让子类来决定哪些类需要被实例化。②工厂方法把实例化的工作推迟到子类中去实现。

    最后了解什么情况下适合工厂模式?

      ①有一组类似的对象需要创建。②在编码时不能预见需要创建哪种类的实例。③系统需要考虑扩展性,不应依赖于产品类实例如何被创建、组合和表达的细节。

    二、几种工厂模式的描述(打比方)

    三、主要实现方式

    以发型实现为例:

    (一)常规方法

    1.创建接口,定义实现发型的方法

    package Factory.sunny.project;
    /**
     * 发型接口
     * 
     * */
    public interface HairInterface {
    
        //实现了发型
        public void draw();    //注意 :  接口中没有方法体
            
    }

    2.用相应的类来实现该接口,重写接口内的方法

    左偏分发型——

    package Factory.sunny.project;
    
    public class LeftHair implements HairInterface {
    
        @Override
        public void draw() {
            // TODO Auto-generated method stub
            System.out.println("---------左偏分发型------------");
        }
    }

    右偏分发型——

    package Factory.sunny.project;
    
    public class RightHair implements HairInterface {
    
        @Override
        public void draw() {
            // TODO Auto-generated method stub
            
            System.out.println("------------右偏分发型----------");
        }
    
    }

    3.测试代码(贴一小段主要的)

        HairInterface left=new LeftHair();
        left.draw();

    缺点是每来一个发型都需要创建新的...Hair类实现,而且还要在客户端调用,不利于维护......

    (二)采用发型工厂方法

    1.创建发型工厂

    package Factory.sunny.project;
    
    import java.util.Map;
    
    /**
     * 发型工厂
     * */
    public class HairFactory {
        
        /**
         * 根据类型创建对象
         * */    
    public HairInterface getHair(String key){
        if("left".equals(key)){//字符放在前面是预防key报空指针
            return new LeftHair();
        }else if("right".equals(key)){
            return new RightHair();
        }
        return null;
    }
    }

    2.测试

        HairFactory factory=new HairFactory();
        
         HairInterface left=factory.getHair("left");
         left.draw();

    缺点:不智能,判断条件太冗杂,解决办法——>反射

    (三)反射方法解决上述问题(一步到位,采取映射)

    1.首先看未采取映射办法的代码

    //生产发型的方法,为了优化上面代码对于大量发型的大量判断,使用反射原理,类似于spring里的BeanFactory
    
    public HairInterface getHairByClass(String className){
        try {
            HairInterface hair=(HairInterface) Class.forName(className).newInstance();
            return hair;
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return null;
    }

    2.采取映射的代码(在此之前先要创建properties文件和properties文件读取类

    properties文件

    properties文件读取类

    package Factory.sunny.project;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    
    /**
     * properties文件的读取工具
     * 
     * */
    public class ProrpertiesReader {
    
        public Map<String,String> getProperties(){
            
            Properties props =new Properties();
            Map<String,String> map=new HashMap<String,String>();
            
            //将key和property读入到map中
            try {
                
                InputStream in=getClass().getResourceAsStream("type.properties");
                props.load(in);
                Enumeration en=props.propertyNames();
                
            while(en.hasMoreElements()){
                    String key=(String) en.nextElement();
                    String property=props.getProperty(key);
                    map.put(key, property);
                }
                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            
            return map;
             
        }
         
    }

    反射&映射方法代码

    public HairInterface getHairByClasskey(String key){
        try {
            Map<String,String> map=new ProrpertiesReader().getProperties();
            
            HairInterface hair=(HairInterface) Class.forName(map.get(key)).newInstance();
            return hair;
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return null;
    }

     3.测试

        //反射方法
    HairInterface right=factory.getHairByClass("Factory.sunny.project.RightHair");
    right.draw(); // 反射&映射方法 HairInterface hair
    =factory.getHairByClasskey("right"); hair.draw(); HairInterface hair2=factory.getHairByClasskey("in"); hair2.draw();
  • 相关阅读:
    【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
    【权值线段树】bzoj3224 Tyvj 1728 普通平衡树
    【转载】【树形DP】【数学期望】Codeforces Round #362 (Div. 2) D.Puzzles
    ReStart
    Good-Bye
    【分块打表】bzoj1662 [Usaco2006 Nov]Round Numbers 圆环数
    【分块打表】bzoj1026 [SCOI2009]windy数
    【分块打表】bzoj3798 特殊的质数
    【分块打表】bzoj3758 数数
    【线段树】bzoj3995 [SDOI2015]道路修建
  • 原文地址:https://www.cnblogs.com/zjfjava/p/6496974.html
Copyright © 2020-2023  润新知