• 设计模式——工厂模式


    1、简述

      工厂模式包括简单工厂模式、工厂方法模式和抽象工厂模式,属于创建型模式。

    2、不使用工厂模式

      (1)类图分析

        一个接口Computer,接口有两个实现类HP和Apple,同时有一个测试类Client。不使用工厂模式时,在Client中直接通过new操作符类创建HP和Apple类的实例。

      (2)代码展示

        Computer接口:

    package com.factory;
    public interface Computer {
        void compute();
    }

        HP类:

    package com.factory;
    public class HP implements Computer {
        @Override
        public void compute() {
            // TODO Auto-generated method stub
            System.out.println("This is HP PC");
        }
    }

        Apple类:

    package com.factory;
    public class Apple implements Computer {
        @Override
        public void compute() {
            // TODO Auto-generated method stub
            System.out.println("This is Apple PC");
        }
    }

        测试类:

    package com.factory;
    public class Client {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //不适用工厂模式常见多个类
            Apple apple = new Apple();
            HP hp = new HP();
            apple.compute();
            hp.compute();
        }
    }

      (3)运行结果:

    This is Apple PC
    This is HP PC

      (4)缺点和不足:

      对于测试类Client来说调用者而言,需要知道HP和Car类的细节,尤其是构造方法的细节,比如需要知道构造方法的参数类型、参数个数等。当有许多Conputer接口的实现类时候,对于Client来说,需要知道的类细节更多,给Client带来较大压力。

    3、使用工厂模式

      (1)简单工厂模式 

        (a)类图分析

          在上述实现方式的基础上,在类的实现结构中增加一层ComputerFactory,此类的作用是返回HP或者Apple等类的实例对象,具体创建并返回哪一个类的实例在ComputerFactory中通过分支语句来实现。最终的Client测试类仅仅需要调用ComputerFactory中的方法,并传入必要的参数即可。简言之,就是工厂类一般是使用静态方法,通过接受的参数的不同来返回不同的对象实例。

     

        (b)代码展示

          Computer接口、HP类、Apple类与(1)中相同

          ComputerFactory类:

        方式一:
    package com.factory;
    public class ComputerFactory {
        public static Computer createComputer(String computer) {
            if("HP".equals(computer)) {
                return new HP();
            }else if("Apple".equals(computer)){
                return new Apple();
            }else {
                return null;
            }
        }
    }
        方式二:
    package com.factory;
    public class ComputerFactory {
        public static Computer createHP() {
                return new HP();
            } 
        public static Computer createApple() {
                return new Apple();
            }
    }

     

          测试类:

        测试一(对应于方式一):

    package com.factory;
    public class Client {
        public static void main(String[] args) {
            //使用简单工厂模式
            Computer hp = ComputerFactory.createComputer("HP");
            Computer apple = ComputerFactory.createComputer("Apple");        
            apple.compute();
            hp.compute();
        }
    }

        测试二(对应于方式二):

    package com.factory;
    public class Client {
        public static void main(String[] args) {
            //使用简单工厂模式
            Computer hp = ComputerFactory.createHP();
            Computer apple = ComputerFactory.createApple();        
            apple.compute();
            hp.compute();
        }
    }

        (c)运行结果

    This is Apple PC
    This is HP PC

        (d)缺点和不足:

         如果需要增加新的Computer类的话,需要修改ComputerFactory内部的代码。这违反了类设计的开闭原则,开闭原则就是说类对拓展开放,对修改关闭。所以简单工厂模式在面对需要增加新的类的时候会违反开闭原则。

     

      (2)工厂方法模式

        (a)类图分析

          简单工厂模式中,只有一个公共的工厂类ComputerFactory,所以当需要增加商品的时候,需要修改ComputerFactory,导致违反了开闭原则。所以为每个商品类定义一个特定的工厂类,此处为HP类设置定义一个HPFactory工厂类,为Apple类定义一个AppleFactory类。这样的话看,当需要增加一个新的产品类的时候,不需要对原有的工厂类进行修改,只需要增加一个新的工厂类即可。同时,为了各个工厂的统一性,定义一个工厂接口Factory,然后各个具体产品工厂XXXFactory实现接口Factory,从而统一了接口中的方法。

        (b)代码展示

           Computer类: 

    package com.factorymethod;
    public interface Computer {
        void compute();
    }

          HP类:

    package com.factorymethod;
    public class HP implements Computer{
        @Override
        public void compute() {
            // TODO Auto-generated method stub
            System.out.println("HP");
        }
    }

          Apple类:

    package com.factorymethod;
    public class Apple implements Computer {
        @Override
        public void compute() {
            // TODO Auto-generated method stub
            System.out.println("Apple");
        }
    }

          Factory类:

    package com.factorymethod;
    public interface Factory {
         Computer createrComputer();
    }

          HPFactory类:

    package com.factorymethod;
    public class HPFactory implements Factory {
        @Override
        public Computer createrComputer() {
            // TODO Auto-generated method stub
            return new HP();
        }
    }

          AppleFactory类:

    package com.factorymethod;
    public class AppleFactory implements Factory {
        @Override
        public Computer createrComputer() {
            // TODO Auto-generated method stub
            return (Computer) new Apple();
        }
    }

          测试类Client:

    package com.factorymethod;
    public class Client {
        public static void main(String args[]) {
            Computer hp = new HPFactory().createrComputer();
            Computer apple = new AppleFactory().createrComputer();
            hp.compute();
            apple.compute();
        }
    }

        (c)运行结果

    HP
    Apple

        (d)缺点与不足

           相比于简单工厂模式,工厂方法模式避免了破坏开闭原则,但是由于为每个类都创建了一个工厂类,导致了类的数目增加。

     

      (3)抽象工厂模式

        (a)概述

          抽象工厂模式是工厂方法模式的升级版本,适用于有多个业务种类和等级的情形,可以用来生产不同产品族的全部产品,对于增加新的产品,无能为力;支持增加产品族 。

           抽象工厂模式中,有一系列产品接口,每个产品接口都有多个实现类,在工厂类中通过选择产品接口的不同实现类可以生产出不同种类、不同等级的产品,从而形成了产品族。例如,每个产品接口都有两个实现类GoodXXX和PoorXXX,工厂类中如果选择所有的GoodXXX实现类,将生产出Good产品,工厂类中如果选择所有的PoorXXX实现类,将生产出Poor产品,从而最终形成了两个产品线。

          

        (b)类图分析

           在此案例中,有三个产品接口CPU、Monitor和Keyboard,同时每个产品接口有两个实现类,分别为GoodCPU和PoorCPU、GoodMonitor和PoorMonitor、GoodKeyboar和PoorKeyboard,其中GoodFactory工厂选择GoodCPU、GoodMonitor、GoodKeyboar创建产品,PoorFactory工厂选择PoorCPU、PoorMonitor、PoorKeyboard创建产品,从而形成了Good和Poor产品两个产品线。

     

        (c)代码展示

           CPU类:

    package abstractfactory;
    
    public interface CPU {
        void say();
    }
    
    class GoodCPU implements CPU{
        @Override
        public void say() {
            // TODO Auto-generated method stub
            System.out.println("I am is Good CPU");
        }
    }
    
    class PoorCPU implements CPU{
        @Override
        public void say() {
            // TODO Auto-generated method stub
            System.out.println("I am is Poor CPU");
        }
        
    }

        

        Monitor类:

    package abstractfactory;
    
    public interface Monitor {
        void say();
    }
    
    class GoodMonitor implements Monitor{
        @Override
        public void say() {
            // TODO Auto-generated method stub
            System.out.println("I am Good Monitor");
        }    
    }
    
    class PoorMonitor implements Monitor{
        @Override
        public void say() {
            // TODO Auto-generated method stub
            System.out.println("I am Poor Monitor");
        }
    }

        

        Keyboard类:

    package abstractfactory;
    
    public interface Keyboard {
        void say();
    }
    
    class GoodKeyboard implements Keyboard{
        @Override
        public void say() {
            // TODO Auto-generated method stub
            System.out.println("I am Good Keyboard");
        }    
    }
    
    class PoorKeyboard implements Keyboard{
        @Override
        public void say() {
            // TODO Auto-generated method stub
            System.out.println("I am Poor Keyboard");
        }    
    }

         

        Factory接口:

    package abstractfactory;
    
    public interface Factory {
        CPU createCPU();
        Monitor createMonitor();
        Keyboard createKeyboard();
    }

        

        GoodFactory类:

    package abstractfactory;
    
    public class GoodFactory implements Factory {
    
        @Override
        public CPU createCPU() {
            // TODO Auto-generated method stub
            return new GoodCPU();
        }
    
        @Override
        public Monitor createMonitor() {
            // TODO Auto-generated method stub
            return new GoodMonitor();
        }
    
        @Override
        public Keyboard createKeyboard() {
            // TODO Auto-generated method stub
            return new GoodKeyboard();
        }
    
    }

        

        PoorFactory类:

    package abstractfactory;
    
    public class PoorFactory implements Factory {
    
        @Override
        public CPU createCPU() {
            // TODO Auto-generated method stub
            return new PoorCPU();
        }
    
        @Override
        public Monitor createMonitor() {
            // TODO Auto-generated method stub
            return new PoorMonitor();
        }
    
        @Override
        public Keyboard createKeyboard() {
            // TODO Auto-generated method stub
            return new PoorKeyboard();
        }
    
    }

        

        Client测试类:

    package abstractfactory;
    
    public class Client {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Factory gf = new GoodFactory();
            CPU gcpu = gf.createCPU();
            Monitor gmonitor = gf.createMonitor();
            Keyboard gkeyboard = gf.createKeyboard();
            gcpu.say();
            gmonitor.say();
            gkeyboard.say();
            
            System.out.println("----------------------------------");
            
            Factory pf = new PoorFactory();
            CPU pcpu = pf.createCPU();
            Monitor pmonitor = pf.createMonitor();
            Keyboard pkeyboard = pf.createKeyboard();
            pcpu.say();
            pmonitor.say();
            pkeyboard.say();
        }
    
    }

       

         运行结果;

    I am is Good CPU
    I am Good Monitor
    I am Good Keyboard
    ----------------------------------
    I am is Poor CPU
    I am Poor Monitor
    I am Poor Keyboard

     

        (d)缺点和不足

          抽象工厂莫斯可以增加产品族,但是不可以增加产品。

  • 相关阅读:
    小峰视频三:在eclipse中创建java类
    小峰视频二:java类的编译与解释
    小峰视频一:jdk环境变量的配置
    React/数据流
    React/组件
    React/生命周期
    React/虚拟DOM
    React/JSX简介
    12.朴素贝叶斯-垃圾邮件分类
    9、主成分分析
  • 原文地址:https://www.cnblogs.com/xwwbb/p/11098538.html
Copyright © 2020-2023  润新知