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   当中的博客,并且再加之自己的理解和话进行重新表述,也许引用的例子会大部分类似,还请谅解。

  • 相关阅读:
    nohub
    swoole聊天室
    swoole httpserver学习
    swore tcp服务学习
    ps查看命令
    nginx和php-fpm调用方式
    Unix/Linux环境C编程入门教程(1) Solaris 11 64bit环境搭建
    Unix/Linux环境C编程入门教程(1) Solaris 11 64bit环境搭建
    C语言入门(4)——常量、变量与赋值
    C语言入门(3)——对Hello World程序的解释
  • 原文地址:https://www.cnblogs.com/WellHold/p/7458206.html
Copyright © 2011-2022 走看看