zoukankan      html  css  js  c++  java
  • Factory Method 和AbstractFactory

    对应慕课视频的连接:https://www.imooc.com/video/5316

    1,工厂模式的应用场景

    有一组类似的对象需要被创建

    在编码时不能预见需要被创建哪种类的实例

    在系统需要考虑扩展性的情况下,不应依赖产品类实例如何创建,组合和表达的细节

    2,项目中的现状:

    在软件系统中经常面临着“对象”的创建工作,由于需求的变化,这个对象可能随之发生改变,但它却拥有比较稳定的接口。

    为此我们需要提供一种风专辑之来隔离这个易变对象的变化,从而保持系统中其他依赖对该对象的对象不随着需求变化而改变

    比如说,客户端要求生产苹果,creater就生产苹果,Uproduct就代表水果,他下面的Product1,Product2,Product3就可以表苹果,香蕉,橘子等具体的水果

    在抽象工厂中呢,用户发出请求,factory生产水果,CreateFactory1,CreateFactory2他两个都可生产两种类型的水果,但是生产的具体产品又各不相同,CreateFactory1,CreateFactory2为两个系列。

     一、代码部分(工厂模式实现)

    (1)是定义生产头发的接口类

    package com.songyan.factory;
    /**
     * 生产头发
     * @author Administrator
     *
     */
    public interface Hair {
        public void draw();
    }

    (2)定义生产发型的实现类:生产左偏分发型的类,生产右偏分发型的类

    package com.songyan.factory;
    
    public class LeftHair implements Hair{
    
        @Override
        public void draw() {
            System.out.println("left hair");
        }
        
    }
    package com.songyan.factory;
    
    public class RightHair implements Hair{
    
        @Override
        public void draw() {
            System.out.println("right hair");
        }
    
    }

    (3)编写测试类,生产左偏分发型

    package com.songyan.factory;
    
    public class Test {
        public static void test1()
        {
            Hair hair=new LeftHair();
            hair.draw();
            
        }
    
        public static void main(String[] args) {
        
            test1();
            
        }
    }

    这种方法生产发型是在客户端生产,不安全------>在工厂中生产发型

    (4)定义生产发型的工厂类

    package com.songyan.factory;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class HairFactory {
        public static Hair getHair(String key)
        {
            Hair hair=null;
            if("left".equals(key))
            {
                hair=new LeftHair();
            }
            else if("right".equals(key))
            {
                hair=new RightHair();
            }
            return hair;
        }
        
        
    }

    (5)编写对应的测试类

    package com.songyan.factory;
    
    public class Test {
        public static void test1()
        {
            Hair hair=new LeftHair();
            hair.draw();
            
        }
        public static void test2()
        {
            HairFactory factory=new HairFactory();
            Hair hair=factory.getHair("left");
            hair.draw();
        }public static void main(String[] args) {
        
            //test1();
            test2();
        }
    }

    这种方式,当添加新的发型时,需要在factory中添加新的else if判断(不合理)---->运用反射的技术,通过类名,动态的创建对象

    反射的知识点:http://www.cnblogs.com/excellencesy/p/8868567.html

    (6)通过反射创建对象

    package com.songyan.factory;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class HairFactory {
    
        public static Hair getHairByClass(String ClassName)
        {
            Hair hair=null;
            try {
                hair=(Hair) Class.forName(ClassName).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            
            return hair;
        }
        
    }

    通过传入累的全名,创建对应的对象

    (7)对应的测试方法test3()

    package com.songyan.factory;
    
    public class Test {
        public static void test1()
        {
            Hair hair=new LeftHair();
            hair.draw();
            
        }
        public static void test2()
        {
            HairFactory factory=new HairFactory();
            Hair hair=factory.getHair("left");
            hair.draw();
        }
        public static void test3()
        {
            HairFactory factory=new HairFactory();
            Hair hair=factory.getHairByClass("com.songyan.factory.LeftHair");
            hair.draw();
        }
    
        public static void main(String[] args) {
        
            //test1();
            //test2();
            test3();
    
        }
    }

    这种方式需要输入复杂的类全名(不合理)----->配置简单的关键字

    (8)编写配置文档type.properties

    left=com.songyan.factory.LeftHair
    right=com.songyan.factory.RightHair

    (9)编写配置文档的读取类及方法

    package com.songyan.factory;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Properties;
    
    public class PropertiesReader {
        public Map<String,String> getProperties()
        {
            //定义储存properties的map集合
            Map<String ,String> map= new HashMap<String,String>();
            //定义properties对象,操作Properties文件
            Properties pro=new Properties();
            //输入流以行的形式输入
            InputStream in=getClass().getResourceAsStream("type.properties") ;
            try {
                pro.load(in);
                
                Enumeration enu=pro.propertyNames();
                while(enu.hasMoreElements())
                {
                    //
                    String key =(String)enu.nextElement();
                    String value=pro.getProperty(key);
                    map.put(key,value);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            return map;
        }
    }

    (10)编写相应的工厂方法

    package com.songyan.factory;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class HairFactory {
        
        public static Hair getHairByKey(String key)
        {
            Hair hair=null;
            Map<String,String> map=new HashMap<String,String>();
            PropertiesReader reader=new PropertiesReader();
            map=reader.getProperties();
            System.out.println(map);
            String className=map.get(key);
            try {
                hair=(Hair) Class.forName(className).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return hair;
        }
    }

    (11)编写对应的测试test4()

    package com.songyan.factory;
    
    public class Test {
        public static void test4()
        {
            HairFactory factory= new HairFactory();
            Hair hair=factory.getHairByKey("left");
            hair.draw();
        }
        public static void main(String[] args) {
    
            test4();
        }
    }

     二、工厂模式的应用(抽象工厂)

    抽象工厂的代码实现

    (1)定义生产男孩子的接口、女孩子接口

    package com.songyan.factory;
    /**
     * 男孩接口
     * @author Administrator
     *
     */
    public interface Boy {
        public void drawMan();
    }
    package com.songyan.factory;
    /**
     *女孩接口
     * @author Administrator
     *
     */
    public interface Girl {
        public  void drawWomen();
    }

    (2)定义新年男孩,圣诞男孩 继承男孩,

    定义新年女孩,圣诞女孩 继承女孩,

    package com.songyan.factory;
    /**
     * 新年男孩
     * @author Administrator
     * 
     */
    public class HNBoy implements Boy{
    
        @Override
        public void drawMan() {
            System.out.println("新年男孩");
            
        }
        
    }
    package com.songyan.factory;
    /**
     * 圣诞男孩
     * @author Administrator
     *
     */
    public class MCBoy implements Boy{
    
        @Override
        public void drawMan() {
            System.out.println("圣诞男孩");
        }
    
    }
    package com.songyan.factory;
    /**
     * 新年女孩
     * @author Administrator
     *
     */
    public class HNGirl implements Girl{
    
        @Override
        public void drawWomen() {
            System.out.println("新年女孩");
        }
    
    }
    package com.songyan.factory;
    /**
     * 圣诞女孩
     * @author Administrator
     *
     */
    public class MCGirl implements Girl{
    
        @Override
        public void drawWomen() {
            System.out.println("圣诞女孩");
            
        }
    
    }

    (3)定义生产男孩女孩的工厂接口

    package com.songyan.factory;
    /**
     * 生产男孩女孩的工厂接口
     * @author Administrator
     *
     */
    public interface PersonFactory {
        //生产男孩子
        public Boy getBoy();
        //生产女孩子
        public Girl getGirl();
    }

    (4)生产

    新年

    类型的男孩子,女孩子

    package com.songyan.factory;
    /**
     * 生产新年类型的男孩子,女孩子
     * @author Administrator
     *
     */
    public class HNFactory implements PersonFactory {
    
        @Override
        public Boy getBoy() {
            // TODO Auto-generated method stub
            return null;
        }
    
        @Override
        public Girl getGirl() {
            // TODO Auto-generated method stub
            return null;
        }
    
    }

    (5)生产圣诞类型的男孩子,女孩子

    package com.songyan.factory;
    /**
     * 生产圣诞类型的男孩子,女孩子
     * @author Administrator
     *
     */
    public class MCFactory implements PersonFactory{
    
        //
        @Override
        public Boy getBoy() {
            return null;
        }
    
        @Override
        public Girl getGirl() {
            return null;
        }
    
    }

    (6)编写测试类

    package com.songyan.factory;
    
    public class Test2 {
    public static void main(String[] args) {
        //绘制圣诞女孩
        PersonFactory factory=new MCFactory();
        Girl girl=factory.getGirl();
        girl.drawWomen();
        
    }
    }

    抽象工厂的应用

    (1)数据库的链接

    (2)生产bean返回给客户端

        

     三、工厂模式总结

        

        

     

  • 相关阅读:
    类中代码执行顺序 及 组合
    初识面向对象
    内置函数及匿名函数 补充
    生成器 补充
    再回首 基本数据类型和 if语句
    day 023-python 包
    day022 python (re模块和 模块)
    day021python 正则表达式
    day 020 常用模块02
    android studio 菜鸟实战项目 之 点击事件以及动态添加
  • 原文地址:https://www.cnblogs.com/excellencesy/p/8856387.html
Copyright © 2011-2022 走看看