zoukankan      html  css  js  c++  java
  • 常见的设计模式:工厂模式

      设计模式,是一个在面试当中很常听到的词,是一些大佬们在编程的过程当中,总结出来的应用于不同场景的代码编写模版,那么今天我们就来学习一下一个最基础的设计模式——工厂模式。

      工厂模式属于创建型的设计模式,顾名思义,所谓的工厂,就是专门用来生产的,那么在编程当中,工厂模式的工厂,就是专门为我们生产 “实例” 的。在平常的使用当中,比如A类当中的某个方法需要使用到B类,则需要A类在自己的方法当中对B类进行new出一个实例,之后再进行应用,而这时候C类如果也需要在自己的方法当中使用B类,则也需要在自己的方法当中对B类实例化,这时候如果将B类实例化这个工作交与D类去做,而A类和C类都直接从D类去获取B类的实例直接进行使用,那么这时候的D类,就是我们所说的工厂类。也许你会问,不就是一个new操作嘛,何必需要再弄一个D类来new,不是更麻烦吗?如果我们约定,对B类进行实例化后,需要对B类当中的100种变量进行重新赋值(这里只是打个比方,实际上不会有那么变态的场景,之所以这么说,是为了表述B的实例化变为了一个复杂的过程)才能对B类的实例进行使用呢?这时候如果不引用D类(工厂类)那么需要在A类当中的方法写101行代码,在C类当中的方法也写相同的101行代码,这就显得很复杂了,所以这时候我们的工厂类就登场了。

      那么接下来我们先介绍工厂模式当中的最简单的形式——静态工厂模式(简单工厂模式)

    1.简单工厂模式:在静态工厂模式当中有这么几个概念:

    1)工厂类:即要生产产品(实例)的类;

    2)抽象产品:它一般是具体产品继承的父类或者实现的接口。 

    3)具体产品:工厂类所创建的对象就是此角色的实例。在Java中由一个具体类实现。 

      首先我们来设定这么一个背景:想必大家对本田车(Honda车)有一点的了解,那么假定现在有两种型号的本田车,CRV和URV,用户可能会对这两种车进行使用。那么在这里例子当中呢,我们的工厂类就是本田车厂,抽象产品为Honda车,而具体产品为:CRV和URV,接下来我们看看代码。

    public interface Honda {   //抽象产品
    
        public void CarVersion();
        
    }
    //具体产品
    public class CRV implements Honda {
        @Override
        public void CarVersion() {
            System.out.println("this is CRV");
        }
    }
    
    class URV implements Honda
    {
        @Override
        public void CarVersion() {
            System.out.println("this is URV");
        }
    }
    //工厂类
    public class HondaFactory {
    
        public Honda createTheCar(String version)
        {
             switch (version) {  
                case "CRV":  
                    return new CRV();  
          
                case "URV":  
                    return new URV();  
          
                default:  
                    break;  
                }  
            return null;
        }
        
    }
    //客户类、
    public class Customer {
    
        public static void main(String[] args) {
            HondaFactory f=new HondaFactory();
            Honda crv=f.createTheCar("CRV");
            crv.CarVersion();
            Honda urv=f.createTheCar("URV");
            urv.CarVersion();
        }
    
    }
    //运行结果
    this is CRV
    this is URV

    可以看到,客户根本不关心这两种车是怎么实现的,客户类所做的操作就是到工厂类提 “车”,这就是简单的工厂模式,那么这种简单的工厂模式会有一个很大的局限性,就是如果我们再加一种车型叫做XRV,那么我们就需要对工厂类进行改造,添加switch当中的case,这是很不方便的,为了解决这个问题,又提出了工厂方法模式。

    2.工厂方法模式

      工厂方法模式比起简单的工厂模式来说,不同点就在于它将工厂类也分为了抽象工厂和具体的工厂,抽象工厂呢,它是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。 在这个例子当中,我们的抽象工厂就是Honda的造车厂,而具体的工厂,就分化出来了CRV的造车厂,URV的造车厂,用这样的方法,在添加一种车型叫XRV的话,我们只需要添加一个具体的XRV的造车厂就可以,而不需要修改其他任何已有的代码。接下来看具体的代码:

    //抽象产品
    public interface HondaCar {
    
        public void CarVersion();
        
    }
    //具体产品
    public class CRV implements HondaCar {
        @Override
        public void CarVersion() {
            System.out.println("this is CRV");
        }
    }
    
    class URV implements HondaCar
    {
        @Override
        public void CarVersion() {
            System.out.println("this is URV");
        }
    }
    
    class XRV implements HondaCar
    {
        @Override
        public void CarVersion() {
            System.out.println("this is XRV");
        }
    }
    //抽象工厂
    public interface HondaFactory {
    
        HondaCar buildTheCar();
    }
    //具体工厂
    public class CRVFactory implements HondaFactory {
    
        @Override
        public HondaCar buildTheCar() {
            // TODO Auto-generated method stub
            return new CRV();
        }
    }
    
    class URVFactory implements HondaFactory
    {
        @Override
        public HondaCar buildTheCar() {
            // TODO Auto-generated method stub
            return new URV();
        }    
    }
    
    class XRVFactory implements HondaFactory
    {
        @Override
        public HondaCar buildTheCar() {
            // TODO Auto-generated method stub
            return new XRV();
        }    
    }
    //客户
    public class Customer {
    
        public static void main(String[] args) {
            HondaFactory c=new CRVFactory();
            HondaCar crv=c.buildTheCar();
            crv.CarVersion();
    
            HondaFactory u=new URVFactory();
            HondaCar urv=u.buildTheCar();
            urv.CarVersion();
            
            HondaFactory x=new XRVFactory();
            HondaCar xrv=x.buildTheCar();
            xrv.CarVersion();
        }
    
    }
    //运行结果
    this is CRV
    this is URV
    this is XRV

    通过工厂方法模式,我们看似完美的解决了添加车型的问题,但是,如果由于车型的不同,导致车上的配件的档次也不相同,比如说:在URV上,我们需要装高级的空调和座椅,而CRV上我们可能就装中级的空调和座椅,那么这时候我们就需要采用抽象工厂的方法的形式来解决。这里我们来举个例子来说明抽象工厂和工厂方法的区别

    我们依然拿生产汽车的例子来说明他们之间的区别。

            在上面的类图中,两厢车和三厢车称为两个不同的等级结构;而2.0排量车和2.4排量车则称为两个不同的产品族。再具体一点,2.0排量两厢车和2.4排量两厢车属于同一个等级结构,2.0排量三厢车和2.4排量三厢车属于另一个等级结构;而2.0排量两厢车和2.0排量三厢车属于同一个产品族,2.4排量两厢车和2.4排量三厢车属于另一个产品族。

            明白了等级结构和产品族的概念,就理解工厂方法模式和抽象工厂模式的区别了,如果工厂的产品全部属于同一个等级结构,则属于工厂方法模式;如果工厂的产品来自多个等级结构,则属于抽象工厂模式。在本例中,如果一个工厂模式提供2.0排量两厢车和2.4排量两厢车,那么他属于工厂方法模式;如果一个工厂模式是提供2.4排量两厢车和2.4排量三厢车两个产品,那么这个工厂模式就是抽象工厂模式,因为他提供的产品是分属两个不同的等级结构。当然,如果一个工厂提供全部四种车型的产品,因为产品分属两个等级结构,他当然也属于抽象工厂模式了。(参考:http://blog.csdn.net/zhengzhb/article/details/7359385/)

    明白了之后我们再回到我们的本田车的例子当中,接下来我们来看看本田车的抽象工厂去实现CRV使用中级座椅和空调,而URV使用高级座椅和空调的代码:

    //抽象产品接口
    public interface HondaCar {
    
        public void CarVersion();
        
    }
    
    public interface AirCondition {
    
        void AirconditionVersion();
        
    }
    
    public interface Seat {
    
        void SeatLevel();
    }
    //具体产品类
    class highAC implements AirCondition {
        @Override
        public void AirconditionVersion() {
            System.out.println("this is high AC");
        }
    }
    
     class MiddleAC implements AirCondition {
            @Override
            public void AirconditionVersion() {
                System.out.println("this is middle AC");
            }
    }
    
    class HighSeat implements Seat {
        @Override
        public void SeatLevel() {
            System.out.println("this is the High seat");
        }
    }
    
    class MiddleSeat implements Seat {
        @Override
        public void SeatLevel() {
            System.out.println("this is the Middle seat");
        }
    }
    
    class CRV implements HondaCar {
        @Override
        public void CarVersion() {
            System.out.println("this is CRV");
        }
    }
    
    class URV implements HondaCar
    {
        @Override
        public void CarVersion() {
            System.out.println("this is URV");
        }
    }
    
    class XRV implements HondaCar
    {
        @Override
        public void CarVersion() {
            System.out.println("this is XRV");
        }
    }
    //抽象工厂
    public interface HondaFactory {
    
        HondaCar buildTheCar();
        AirCondition getTheAirCondition();
        Seat getTheSeat();
    }
    //具体工厂
    public class CRVFactory implements HondaFactory {
    
        @Override
        public HondaCar buildTheCar() {
            // TODO Auto-generated method stub
            return new CRV();
        }
    
        @Override
        public AirCondition getTheAirCondition() {
            // TODO Auto-generated method stub
            return new MiddleAC();
        }
    
        @Override
        public Seat getTheSeat() {
            // TODO Auto-generated method stub
            return new MiddleSeat();
        }
    }
    
    class URVFactory implements HondaFactory
    {
        @Override
        public HondaCar buildTheCar() {
            // TODO Auto-generated method stub
            return new URV();
        }
    
        @Override
        public AirCondition getTheAirCondition() {
            // TODO Auto-generated method stub
            return new highAC();
        }
    
        @Override
        public Seat getTheSeat() {
            // TODO Auto-generated method stub
            return new HighSeat();
        }    
    }
    //客户
    public class Customer {
    
        public static void main(String[] args) {
            HondaFactory c=new CRVFactory();
            HondaCar crv=c.buildTheCar();
            crv.CarVersion();
            
    
            HondaFactory u=new URVFactory();
            HondaCar urv=u.buildTheCar();
            urv.CarVersion();
            
    
        }
    
    }

    到此,工厂模式就介绍完毕了。

    总结一下:

    简单工厂模式:对于增加新产品无能为力

    工厂方法模式:通过新增实现具体工厂类的方式,可以增加新产品。

    抽象工厂模式:对增加新产品无能为力,但是可以增加新产品族

    本文参考了:http://blog.csdn.net/jason0539/article/details/23020989#comments   当中的博客,并且再加之自己的理解和话进行重新表述,也许引用的例子会大部分类似,还请谅解。

  • 相关阅读:
    升级windows 11小工具
    windows 10更新升级方法
    您需要了解的有关 Oracle 数据库修补的所有信息
    Step by Step Apply Rolling PSU Patch In Oracle Database 12c RAC Environment
    Upgrade Oracle Database Manually from 12.2.0.1 to 19c
    如何应用版本更新 12.2.0.1.210420(补丁 32507738 – 2021 年 4 月 RU)
    xtrabackup 安装、备份和恢复
    Centos_Lvm expand capacity without restarting CentOS
    Centos_Lvm_Create pv vg lv and mount
    通过全备+relaylog同步恢复被drop的库或表
  • 原文地址:https://www.cnblogs.com/WellHold/p/7458206.html
Copyright © 2011-2022 走看看