zoukankan      html  css  js  c++  java
  • 1.Java设计模式工厂模式

    1.简单工厂模式(Factory Method

    常用的工厂模式是静态工厂模式,利用static修饰方法,作为一种类似于常见的工具类Utils等辅助效果,一般情况下工厂类不需要实例化。

    //1.定义一个基类接口
    public interface Video {
        //定义一个生产视频的方法
        public void produce();
    }
    //2.定义实现类
    public class JavaVideo implements Video {
        @Override
        public void produce() {
            System.out.println("生产java视频");
        }
    }
    public class PythonVideo implements Video {
        @Override
        public void produce() {
            System.out.println("生产python视频的方法");
        }
    }
    //3.定义视频工厂
    public class VideoFactory {
        public static Video getVideo(String type) {
            if("java".equalsIgnoreCase(type)) {
                return new JavaVideo();
            }else if("python".equalsIgnoreCase(type)) {
                return new PythonVideo();
            }else {
                return null;
            }    
        }
    }
    //4.测试类
    public class Test {
        public static void main(String[] args) {
            Video video = VideoFactory.getVideo("java");
            if(video==null) {
                return;
            }
            video.produce();
        }
    }
    View Code

    工厂模式缺点:

        工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,违反开闭原则。但上述工厂类模式随着生产课程种类原来越多,工厂里的方法要不断修改,不符合开闭原则。

    改进:

    1.1.  利用反射弥补扩展性,重新定义VideoFactory内的getVideo方法。

    //修改工厂类
    public class VideoFactory01 {
        public static Video getVideo(Class<?> c) {
            Video video=null;
            try {
                video=(Video) Class.forName(c.getName()).newInstance();
            } 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 video;
        }
    }
    //测试类
    public class Test1 {
        public static void main(String[] args) {
            Video video = VideoFactory01.getVideo(PythonVideo.class);
            video.produce();
        }
    View Code

    1.2.工厂类只定义规范(接口),创建不同的实例只需要不同的工厂类实现统一的工厂接口即可。这样可以放VideoFactory这个超类代码与子类创建对象的代码解耦。(工厂模式)

    //视频工厂只提供规范,具体创建何种实例由具体的工厂实现类来决定
    public interface VideoFactory02 {
        public Video getVideo();
    }
    //具体的实现
    public class JavaVideoFactory02 implements VideoFactory02 {
        @Override
        public Video getVideo() {
            return new JavaVideo();
        }
    }
    public class PythonVideoFactory02 implements VideoFactory02 {
        @Override
        public Video getVideo() {
            // TODO Auto-generated method stub
            return new PythonVideo();
        }
    }
    //测试类
    public class Test2 {
        /**
         * 现在创建什么类型的视频是由VideoFactory的子类决定的,VideoFactory只定义规范,契约
         * @param args
         */
        public static void main(String[] args) {
            VideoFactory02 factory=new JavaVideoFactory02();
            Video video= factory.getVideo();
            video.produce();
        }
    }
    View Code

         从扩展性的角度来看,现在如果要添加一门前端课程,只需要创建FeVideoFactory实现VideoFactory接口就可以了,不需要修改VideoFactory的代码实现。符合开闭原则。且FeVideo,JavaVideo,PythonVideo处于同一产品等级,工厂模式就是方便解决同一产品等级创建实例的。

    2.工厂模式深入——体现产品等级概念

          举个栗子:假设我们想要找电脑组装人员DIY组装一台电脑。我们希望自己选择CPU、主板、内存、电源、显卡、电源等。由于内容较多,我们就拿CPU和主板来说事。

           在选择CPU的时候,主要的参数有CPU品牌,型号,针脚数量,主频等,只有这些都确定下来,我们才能确定具体的CPU;

           主板也一样,主板的主要参数有品牌,芯片组,总线频率等,只有这些确定下来,我们才能确定具体主板;

           且在选择的时候我们还需要考虑到CPU和主板的兼容性,比如说Intel的CPU与AMD的主板就不兼容,因为Intel的CPU的针脚数目与AMD主板的CPU插孔数量不一致,根本无法插入。所以装机方案需要整体考虑,里边的不同模块之间是有关联的。

          对于装机工程师来说,他只知道组装一台电脑需要响应的配件,而具体的配件选择还是需要由客户决定。对于不同的客户做出的选择不同,他需要根据客户的选择去获取配件,然后为该客户完成组装。

          使用工厂模式的解决方案:

         对于装机工程师来说,他只知道组装电脑需要CPU和主板,而两者具体选择什么品牌,型号他确定不了,需要客户去选择,客户选择好后他负责去相应的工厂里边获取这两种配件,然后组装。

        2.1.Cpu接口与具体实现

     

    //Cpu接口
    package com.itheima.pattern.entity;
    public interface CPU {
        //CPU具有计算功能
        public void calculate();
    }
    //Cpu具体实现Intel,可供客户选择
    package com.itheima.pattern.entity;
    
    public class IntelCpu implements CPU { 
        private int pins;
        public IntelCpu(int pins) {
            this.pins = pins;
        }
    
        @Override
        public void calculate() {
            System.out.println("Intel Cpu的针脚数:"+pins);
        }
    }
    //Cpu具体实现Amd,可供客户选择
    package com.itheima.pattern.entity;
    
    public class AmdCpu implements CPU {
        
        private int pins;
        public AmdCpu(int pins) {
            this.pins = pins;
        }
        @Override
        public void calculate() {
            System.out.println("Amd Cpu针脚数:"+pins);
        }
    }
    View Code

     

       2.2.主板接口与具体实现

    //主板接口
    package com.itheima.pattern.entity;
    
    public interface Mainboard {
        //主板上安装Cpu
        public void installCpu();
    }
    
    //主板具体实现Intel,可供客户选择
    package com.itheima.pattern.entity;
    
    public class IntelMainboard implements Mainboard {
        /**
         * cpu插槽孔数
         */
        private int cpuHolds;    
        public IntelMainboard(int cpuHolds) {
            this.cpuHolds = cpuHolds;
        }
    
        @Override
        public void installCpu() {
            System.out.println("Intel主板CPU插槽孔数是:"+cpuHolds);
        }
    }
    
    //主板具体实现Amd,可供客户选择
    package com.itheima.pattern.entity;
    
    public class AmdMainboard implements Mainboard {
        private int cpuHolds;
        public AmdMainboard(int cpuHolds) {
            this.cpuHolds = cpuHolds;
        }
        @Override
        public void installCpu() {
            System.out.println("Amd 主板Cpu插槽孔数:"+cpuHolds);
        }
    }
    View Code

       2.3.创建Cpu工厂

    package com.itheima.pattern.factory;
    
    import com.itheima.pattern.entity.AmdCpu;
    import com.itheima.pattern.entity.CPU;
    import com.itheima.pattern.entity.IntelCpu;
    
    public class CpuFactory {
        
        public static CPU createCpu(int type) {
            CPU cpu=null;
            if(type==1) {
                cpu=new IntelCpu(755);    
            }else if(type==2) {
                cpu=new AmdCpu(938);    
            }else {
                return null;
            }
            return cpu;
        }
    }
    View Code

      2.4.创建主板工厂

    package com.itheima.pattern.factory;
    
    import com.itheima.pattern.entity.AmdMainboard;
    import com.itheima.pattern.entity.IntelMainboard;
    import com.itheima.pattern.entity.Mainboard;
    
    public class MainboardFactory {
        public static Mainboard createMainboard(int type) {
            if(type==1) {
                return new IntelMainboard(755);
            }else if(type==2) {
                return new AmdMainboard(938);
            }else {
                return null;
            }
        }
    }
    View Code

      2.5.电脑组装工程师(工厂调用者)

    package com.itheima.pattern.computerEngineer;
    
    import com.itheima.pattern.entity.CPU;
    import com.itheima.pattern.entity.Mainboard;
    import com.itheima.pattern.factory.CpuFactory;
    import com.itheima.pattern.factory.MainboardFactory;
    
    public class ComputerEngineer {
        //装机需要Cpu
        private CPU cpu;
        //装机需要主板
        private Mainboard mainboard;
        //组装电脑
        public void makeComputer(int cpuType,int boardType) {
            cpu=CpuFactory.createCpu(cpuType);
            mainboard=MainboardFactory.createMainboard(boardType);
            cpu.calculate();
            mainboard.installCpu();
            System.out.println("电脑组装完成,可以使用");
        }
    }
    View Code

      2.6.客户(使用者)

    package com.itheima.pattern.client;
    
    import com.itheima.pattern.computerEngineer.ComputerEngineer;
    
    public class Client {
        public static void main(String[] args) {
            ComputerEngineer computerEngineer = new ComputerEngineer();
            computerEngineer.makeComputer(1, 1);
        }
    }
    View Code

      2.7.程序运行结果

    上边的实现是采用简单工厂模式实现的,但有个问题没有解决,就是Cpu与主板之间的兼容关系没有解决,实际上Cpu与主板之间时候有关系的,需要相互匹配。而上边的实现并没有维护这种关系。因此当客户选择makeComputer(1, 2)时,将出现无法组装的情况。该如何避免这种情况的发生?需要引入抽象工厂模式。见下一节。

     

     

  • 相关阅读:
    怎么在java 8的map中使用stream
    在java 8 stream表达式中实现if/else逻辑
    Lambda表达式最佳实践
    java并发Exchanger的使用
    java中functional interface的分类和使用
    java 8 Streams简介
    一篇文章让你彻底弄懂SSL/TLS协议
    基于口令的密码(PBE)
    更加安全的密钥生成方法Diffie-Hellman
    有关密钥的最全总结都在这了
  • 原文地址:https://www.cnblogs.com/yangyongxin/p/10152559.html
Copyright © 2011-2022 走看看