zoukankan      html  css  js  c++  java
  • 设计模式之建造者模式

    建造者模式--导读

      生活中我们经常碰到,餐馆中各种不同的套餐,和各种不同的汽车,但是这些都有一个共同的特性,那就是他们多是由各种部件组成。

    就比如在kfc点餐一样,他给你提供很多不同的组合,比如说薯条和饮料和汉堡,薯条和果汁和烤翅,你会发现这些单个的东西都会单买,但是

    跟据不同的组合,就形成了五花八门的套餐,这就用到了我们的建造者模式了,用户仅需知道这个套餐是什么,而不需要知道套餐中的具体组合

    便可以得到自己想要的套餐,不需要管这其中复杂的组合关系

    建造者模式--定义

      建造者模式将一个复杂对象的构建过程和表是分开,是的同样的创建过程,通过不同的组合过程可以创建出不同的表示 。

      建造者模式构建复杂对象就像造汽车一样,是一个一个组件一个一个步骤创建出来的,它允许用户通过制定的对象类型和内容来创建他们,但是用户并不需要知道这个复杂对象是如何构建的,它只需要明白通过这样做我可以得到一个完整的复杂对象实例

    建造者模式--模式结构

      一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式的本质是使组装过程(用指挥者类进行封装,从而达到解耦的目的)和创建具体产品解耦,使我们不用去关心每个组件是如何组装的。

    建造者模式的实现:

    ①在建造者模式中,指挥者是直接与客户端打交道的,指挥者将客户端创建产品的请求划分为对各个部件的建造请求,再将这些请求委派到具体建造者角色,具体建造者角色是完成具体产品的构建工作的,却不为客户所知道。

    ②建造者模式主要用于“分步骤来构建一个复杂的对象”,其中“分步骤”是一个固定的组合过程,而复杂对象的各个部分是经常变化的(也就是说电脑的内部组件是经常变化的,这里指的的变化如硬盘的大小变了,CPU由单核变双核等)。

    ③产品不需要抽象类,由于建造模式的创建出来的最终产品可能差异很大,所以不大可能提炼出一个抽象产品类。

    ④在前面文章中介绍的抽象工厂模式解决了“系列产品”的需求变化,而建造者模式解决的是 “产品部分” 的需要变化。

    ⑤由于建造者隐藏了具体产品的组装过程,所以要改变一个产品的内部表示,只需要再实现一个具体的建造者就可以了,从而能很好地应对产品组成组件的需求变化。

    建造者模式--具体实现

    package Builder_Pattern;
    /**
     * 为创建具体产品提供具体建构者提供接口
     * @author liu
     *
     */
    public abstract class CarBuilder {
        public Car car=new Car();public  abstract void createTyer();
        public abstract void createSeats();
        public abstract void createEngine();
        public Car getCar() {
            return car;
        }
    }
    Car.java
    package Builder_Pattern;
    
    public class Car {
        private String tyer;
        private String seats;
        private String engine;
        @Override
        public String toString() {
            return "Car [tyer=" + tyer + ", seats=" + seats + ", engine=" + engine + "]";
        }
        public String getTyer() {
            return tyer;
        }
        public void setTyer(String tyer) {
            this.tyer = tyer;
        }
        public String getSeats() {
            return seats;
        }
        public void setSeats(String seats) {
            this.seats = seats;
        }
        public String getEngine() {
            return engine;
        }
        public void setEngine(String engine) {
            this.engine = engine;
        }
        
    }
    package Builder_Pattern;
    
    

    public class CheaperCarBuilder extends CarBuilder{

      @Override
      public void createTyer() {
        this.car.setTyer("垃圾的轮胎");

      }

      @Override
      public void createSeats() {
        this.car.setSeats("垃圾的座位");

      }

      @Override
      public void createEngine() {
      // TODO Auto-generated method stub
      this.car.setEngine("垃圾的发动机");
      }

    }

    package Builder_Pattern;
    /**
     * 指挥者通过调用build接口来实现创建客户所需的
     * 对象,从而实现客户端与创建过程的解耦
     * @author liu
     *
     */
    public class Director {
        CarBuilder builder;
        public Director(CarBuilder builder) {
            this.builder=builder;
        }
        public Car construct() {
            builder.createEngine();
            builder.createSeats();
            builder.createTyer();
            return builder.getCar();
        }
    }
    package Builder_Pattern;
    
    public class client {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //客户端不需要接触具体的创建过程
            CheaperCarBuilder builder=new CheaperCarBuilder();
            Director director=new Director(builder);
            Car car=director.construct();

          System.out.println(car.toString());

    
        }
    
    }

    建造者模式--优缺点

      1、将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,使得我们能够更加精确的控制复杂对象的产生过程。

          2、将产品的创建过程与产品本身分离开来,可以使用相同的创建过程来得到不同的产品。也就说细节依赖抽象。

          3、每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。

    缺点

          1、建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
          2、如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

    建造者模式--使用场景

      1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。

       2、JAVA 中的 StringBuilder。

  • 相关阅读:
    python上传阿里云oss
    python调用百度图片识别api
    python实现sm2和sm4国密(国家商用密码)算法
    python坐标获取经纬度或经纬度获取坐标免费模块--geopy
    剑指 Offer 36. 二叉搜索树与双向链表
    vs code中终端中的命令不能使用的解决方法
    VS Code切换默认终端(cmd、powershell)
    剑指 Offer 35. 复杂链表的复制
    剑指 Offer 33. 二叉搜索树的后序遍历序列
    剑指 Offer 32
  • 原文地址:https://www.cnblogs.com/sank/p/10651164.html
Copyright © 2011-2022 走看看