• 设计模式之工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)


    简单工厂模式:

      角色: 抽象产品类 具体产品类 产品工厂类

      定义:将被使用方的创建过程封装到一个类中,这样就在使用方和被使用方之间做了一个缓冲,也就是使用方和被使用方做了一个解耦,提高了软件的可扩展性和可维护性和可复用性.

    现在有一个手机抽象类

    public abstract class Phone {
    
       public abstract void makePhone();
    }

    两个实现类

    public class XiaoMi extends Phone {
    
        @Override
        public void makePhone() {
            System.out.println("制造出了小米手机");
        }
    }
    public class HWPhone extends Phone {
    
        @Override
        public void makePhone() {
            System.out.println("制造出了华为手机");
        }
    }

    为了不让调用方直接去调用这两个类去创建实例.我们提供一个工厂类的静态方法去创建不同品牌手机的实例对象

    public class PhoneFactory {
    
        public static Phone createPhone(Integer type){
            Phone phone=null;
           if(1==type){
               phone = new XiaoMi();
           }else if(type==2){
               phone = new HWPhone();
           }
            return phone;
        }
    
    }

    接下来一个客户端调用工厂类来创建

    public class Consumer {
    
        public static void main(String[] args) {
            PhoneFactory.createPhone(1).makePhone();
            PhoneFactory.createPhone(2).makePhone();
        }
    
    }

    输出结果:

     这样我们就在使用和被使用方之间做了一层缓冲,避免了使用方和被使用方耦合性过高.当我们需要再次创建一个新品牌的手机,我们还是需要在工厂类修改代码.

    所以简单工厂的使用场景:

      具体类十分确定且固定的一类产品的创建,这样不至于频繁的修改工厂类的代码去实现扩展.而为了弥补简单工厂模式的缺点,再次基础上我们就要延伸下面的模式

    工厂方法模式:

      角色:抽象产品类 具体产品类 抽象工厂类(只有一个接口方法生产产品) 具体工厂类

      定义:将简单工厂的创建对象的方法写成一个抽象方法,也就是在工厂类或者接口中不知道如何创建该对象,创建具体对象交给工厂类的子类或者实现类去做.

    我们首先改造之前的工厂类为抽象接口

    public interface PhoneFactory {
        
       Phone createPhone();
       
    
    }

    我们为每一个手机品牌实现一个对应的工厂类

    public class HWFactory implements PhoneFactory {
    
        @Override
        public Phone createPhone() {
          new HWPhone();
        }
    }
    public class XiaoMiFactory implements PhoneFactory {
    
        @Override
        public Phone createPhone() {
         return new XiaoMi();
        }
    }

     然后我们再次通过消费者调用

    public class Consumer {
    
        public static void main(String[] args) {
            XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();
            xiaoMiFactory.createPhone().makePhone();
            HWFactory hwFactory = new HWFactory();
            hwFactory.createPhone().makePhone();
        }
    
    }

    输出结果:

     我们在之前简单工厂的基础上,把工厂类页向上抽象了一层,这样我们需要什么工厂就去实现工厂抽象接口,获得不同的工厂,我们的工厂方法相比之前的静态方法工厂类

      优点:让扩展变得简单,并且每个工厂创建不同的产品,符合单一职能原则

      缺点:当新增加一个产品,需要创建对应的产品工厂类,一个工厂只能创建一个产品.

    抽象工厂模式

       角色:抽象产品类 具体产品类 抽象工厂类(多个生产产品方法,一个产品族) 具体工厂类

    原有基础上,我们之前的抽象工厂接口只有一个创建产品的方法,在抽象工厂模式里面,我们的抽象工厂将有多个创建同一族产品的方法,架设现在我们有需要生产手机壳

    手机壳抽象类

    public abstract class PhoneShell {
        
         abstract void makePhoneShell();
    }

    手机壳实现类

    public class XiaoMiShell extends PhoneShell {
    
    
        @Override
        void makePhoneShell() {
            System.out.println("小米手机壳");
        }
    }
    public class HWShell extends PhoneShell {
    
        @Override
        void makePhoneShell() {
            System.out.println("华为手机壳");
        }
    }

    现在我们把之前的抽象工厂类接口增加一个抽象方法

    public interface PhoneFactory {
    
       Phone createPhone();
    
       PhoneShell createShell();
    
    
    }

    抽象工厂实现类

    public class XiaoMiFactory implements PhoneFactory {
    
        @Override
        public Phone createPhone() {
           return new XiaoMi();
        }
    
        @Override
        public PhoneShell createShell() {
            return new XiaoMiShell();
        }
    } 
    public class HWFactory implements PhoneFactory {
    
        @Override
        public Phone createPhone() {
          return new HWPhone();
        }
    
        @Override
        public PhoneShell createShell() {
            return new HWShell();
        }
    }

    调用方

    public class Consumer {
    
        public static void main(String[] args) {
            XiaoMiFactory xiaoMiFactory = new XiaoMiFactory();
            xiaoMiFactory.createPhone().makePhone();
            xiaoMiFactory.createShell().makePhoneShell();
            HWFactory hwFactory = new HWFactory();
            hwFactory.createPhone().makePhone();
            hwFactory.createShell().makePhoneShell();
        }
    
    }

    输出结果:

     抽象工厂模式相比工厂方法模式: 抽象工厂方法不再是单独的接口,而是生产一类产品的接口,可以生产多个相关联产品,接下来我们看下UML类图关系

      抽象工厂模式的使用场景:

        引用<<Java与模式>>的说法:

      1:一个系统不应当依赖于产品类实例如何创建,组合和表达的细节,这对于所有形态的工厂模式都是重要的

      2:这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品(上面这一条叫做抽象工厂的原始用意)

      3:同属于一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来

      4:系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现

    为什么会有这样的说法,我想就应该深入到抽象工厂模式的起源的具体场景去讨论这个问题

  • 相关阅读:
    微信公众号支付JSAPI,提示:2支付缺少参数:appId
    Application对象
    Apache安装和文件配置
    Apache编译教程
    MS4W安装教程
    MapServer教程2
    Tomcat修改源码,重新编译
    MapServer教程
    QGIS SDK下载
    OpenStreetMap全球库
  • 原文地址:https://www.cnblogs.com/zhaoletian/p/12739381.html
Copyright © 2020-2023  润新知