首页 > 其他分享 >建造者模式

建造者模式

时间:2023-01-17 13:34:20浏览次数:26  
标签:Product return String void 建造 product 模式 public

建造者模式

定义:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

作用:

在用户不知道对象的建造过程和细节的情况下,可以直接创建复杂的对象

优点:

  • 产品的建造和表示分离,实现了解耦。使用建造者模式可以使客户端不必要知道产品内部组成的细节
  • 将复杂产品的创建步骤分截在不同的方法中,使得创建过程更加清晰
  • 具体的建造者之间使相互独立的,这有利于系统的扩展。增加新的具体建造者无需修改原有类库的代码,符合”开闭原则“。

缺点:

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

应用场景:

  • 需要生成的产品对象有复杂的内部结构,这些产品对象具有共性
  • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品
  • 适合于一个具有较多的零件(属性)的产品(对象)的创建过程

1、测试案例一

先设想一个场景:工程师修建房子,并且他知道他需要做的工作是打地基、铺电线、打钢筋、粉刷墙壁以及最终得到房子,但是他不会自己做,这个具体的事情由工人完成,他只是负责指挥工人完成相应的工作。

这段话里面含有四个对象:

  • 工程师:建造出来的房子、口头上的命令工作
  • 抽象的工作(口头上的工作):名义上的建造房子需要做的四项工作、得到房子
  • 工人:真实完成的四项工作、建造出来的产品
  • 修建出来的房子:房子是由四个工作累积起来的

建造者模式_其他

  1. 抽象的工作类:Buider.java

    package pers.mobian.buider.demo01;
    
    public abstract class Buider {
        abstract void buiderA(); //地基
        abstract void buiderB(); //钢筋工程
        abstract void buiderC(); //铺电线
        abstract void buiderD(); //粉刷
    
        //完工:得到具体的产品
        abstract Product getProduct();
    }
    
  2. 工人类:Worker.java

    package pers.mobian.buider.demo01;
    
    //具体的建造者:工人
    public class Worker extends Buider{
        private Product product;
    
        public Worker() {
            product = new Product();
        }
    
        @Override
        void buiderA() {
            product.setBuiderA("地基");
            System.out.println("地基");
        }
    
        @Override
        void buiderB() {
            product.setBuiderB("钢筋工程");
            System.out.println("钢筋工程");
    
        }
    
        @Override
        void buiderC() {
            product.setBuiderC("铺电线");
            System.out.println("铺电线");
    
        }
    
        @Override
        void buiderD() {
            product.setBuiderD("粉刷");
            System.out.println("粉刷");
    
        }
    
        @Override
        Product getProduct() {
            return product;
        }
    }
    
  3. 修建出来的房子:Product.java

    package pers.mobian.buider.demo01;
    
    public class Product {
        private String buiderA;
        private String buiderB;
        private String buiderC;
        private String buiderD;
    
        @Override
        public String toString() {
            return "Product{" +
                    "buiderA='" + buiderA + '\'' +
                    ", buiderB='" + buiderB + '\'' +
                    ", buiderC='" + buiderC + '\'' +
                    ", buiderD='" + buiderD + '\'' +
                    '}';
        }
    
        public String getBuiderA() {
            return buiderA;
        }
    
        public void setBuiderA(String buiderA) {
            this.buiderA = buiderA;
        }
    
        public String getBuiderB() {
            return buiderB;
        }
    
        public void setBuiderB(String buiderB) {
            this.buiderB = buiderB;
        }
    
        public String getBuiderC() {
            return buiderC;
        }
    
        public void setBuiderC(String buiderC) {
            this.buiderC = buiderC;
        }
    
        public String getBuiderD() {
            return buiderD;
        }
    
        public void setBuiderD(String buiderD) {
            this.buiderD = buiderD;
        }
    }
    
  4. 工程师:Director.java

    package pers.mobian.buider.demo01;
    
    //指挥:核心,负责只会构建一个工程,工程如果构建,
    public class Director {
        //指挥工人,按照顺序修建房子
        public Product build(Buider buider) {
            buider.buiderA();
            buider.buiderB();
            buider.buiderC();
            buider.buiderD();
            return buider.getProduct();
        }
    }
    
  5. 验房,即测试类:Test.java

    package pers.mobian.buider.demo01;
    
    public class Test {
        public static void main(String[] args) {
            //叫对应的工程师
            Director director = new Director();
            //工程师去指挥对应的工人
            Product build = director.build(new Worker());
            //打印输出修好了的房子
            System.out.println(build.toString());
        }
    }
    
  6. 结果

    地基
    钢筋工程
    铺电线
    粉刷
    Product{buiderA='地基', buiderB='钢筋工程', buiderC='铺电线', buiderD='粉刷'}
    

总结:测试类只需要简单的调用工程师类,具体工程师去叫哪个工人,得出什么样的产品,测试类不需要关心。并且,用此方法实现的话,代码有很强的可扩展性。需要不同的产品只需要让工程师调用不同的工人即可。

但是有时候,我们需要简化的系统结构,可以把Director和抽象类进行一个结合。通过静态内部类方式实现零件无序装配构造,此方式更加的灵活且符合规定。内部有复杂对象的默认实现,使用时间可以根据用户需求自由定义更改内容,并且无需修改具体的构造方式。就饿能够生产出不同的复杂产品。

例如:你去快餐,服务员(具体的建造者Worker)可以随意搭配任意几种产品(零件Builder)组成一套套餐(产品Product),然后出售给客户。比第一种方式少了指挥者,主要是因为第二种方式把指挥者交给了用户自己来操作,使得产品更加灵活。


2、测试案例二

设想一个场景:某天客户(Test)去一个餐馆吃饭,但是他却不知道改吃什么,于是就点了一个他们店的经典套餐(默认菜单)。第二天他又去,但是这次他只想喝白开水,于是他就叫服务员(Worker),让他给他来四杯白开水,服务员问了一下后厨(Builder),后厨说还有白开水,于是服务员就修改了菜单,然后就上了四倍白开水。

这段话里面含有四个对象:

  • 客户:叫服务员、得到菜
  • 后厨(口头上的工作):询问是否还有菜、做菜
  • 服务员:负责修改菜单、上菜
  • 菜单:菜单上是经典套餐、菜单上是自己点的水

建造者模式_建造者模式_02

  1. 后厨:Builder.java

    package pers.mobian.buider.demo02;
    
    public abstract class Builder {
        abstract Builder builderA(String msg);
    
        abstract Builder builderB(String msg);
    
        abstract Builder builderC(String msg);
    
        abstract Builder builderD(String msg);
    
        abstract Product getProduct();
    }
    
  2. 菜单:Product.java

    package pers.mobian.buider.demo02;
    
    public class Product {
        private String builderA = "青椒肉丝";
        private String builderB = "豆腐汤";
        private String builderC = "白米饭";
        private String builderD = "咸菜";
    
    
    
        public String getBuilderA() {
            return builderA;
        }
    
        public void setBuilderA(String builderA) {
            this.builderA = builderA;
        }
    
        public String getBuilderB() {
            return builderB;
        }
    
        public void setBuilderB(String builderB) {
            this.builderB = builderB;
        }
    
        public String getBuilderC() {
            return builderC;
        }
    
        public void setBuilderC(String builderC) {
            this.builderC = builderC;
        }
    
        public String getBuilderD() {
            return builderD;
        }
    
        public void setBuilderD(String builderD) {
            this.builderD = builderD;
        }
    
        //打印具体的产品
        @Override
        public String toString() {
            return "Product{" +
                    "builderA='" + builderA + '\'' +
                    ", builderB='" + builderB + '\'' +
                    ", builderC='" + builderC + '\'' +
                    ", builderD='" + builderD + '\'' +
                    '}';
        }
    }
    
  3. 服务员:Worker.java

    package pers.mobian.buider.demo02;
    
    public class Worker  extends Builder{
    
        private Product product;
    
        public Worker() {
            product = new Product();
        }
    
        @Override
        Builder builderA(String msg) {
            product.setBuilderA(msg);
            return this;
        }
    
        @Override
        Builder builderB(String msg) {
            product.setBuilderB(msg);
            return this;
        }
    
        @Override
        Builder builderC(String msg) {
            product.setBuilderC(msg);
            return this;
        }
    
        @Override
        Builder builderD(String msg) {
            product.setBuilderD(msg);
            return this;
        }
    
        @Override
        Product getProduct() {
            return product;
        }
    }
    
  4. 用户测试类:Test.java

    package pers.mobian.buider.demo02;
    
    //类似于之前是工程师Directer
    public class Test {
        public static void main(String[] args) {
            Worker worker = new Worker();
            //默认套餐
            System.out.println(worker.getProduct().toString());
            //用户修改以后的套餐,此处可以使用链式编程,直接修改好一整个菜单
            Product product = worker.builderA("白开水1号").builderB("白开水2号").builderC("白开水3号").builderD("白开水4号").
                    getProduct();
            System.out.println(product.toString());
    
    
        }
    }
    
  5. 结果:

    Product{builderA='青椒肉丝', builderB='豆腐汤', builderC='白米饭', builderD='咸菜'}
    Product{builderA='白开水1号', builderB='白开水2号', builderC='白开水3号', builderD='白开水4号'}
    

总结:此方式比第一种更加的灵活。


3、与抽象工厂做比较

  • 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族
  • 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象。
  • 如果将抽象工厂模式看出汽车而配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件得组装可以返回一辆完整得汽车。

标签:Product,return,String,void,建造,product,模式,public
From: https://blog.51cto.com/u_15942107/6017176

相关文章

  • 原型模式
    原型模式原型模式(PrototypePattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。1、使用方法实现Cl......
  • 代理模式
    代理模式即ProxyPattern,23种java常用设计模式之一。代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问。代理模式也是SpringAOP的底层代理模式分类:静态......
  • 工厂模式+抽象工厂模式
    工厂模式1、概述核心实例化对象不使用new,用工厂方法代替将选择实现类,创建对象统一管理和控制。从而将调用者跟我们的实现类解耦工厂模式满足的OOP原则:开闭原则......
  • 单例模式
    单例模式1、概述核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点常见场景:Window的任务管理器Window的回收站项目中,读取配置文件的类,一般......
  • 22.(行为型模式)java设计模式之备忘录模式
    一、什么是备忘录模式(MementoPattern)定义:在不破坏封闭的前提下,捕获⼀个对象的内部状态,保存对象的某个状态,以便在适当的时候恢复对象,⼜叫做快照模式,属于⾏为模式。备......
  • 04-代理模式
    04代理模式背景本博客是照着程杰的《大话设计模式》一书实现的Java代码的版本,再加自己的一点理解问题卓贾易追求娇娇的方式是派出自己的好友戴笠实现该模型的代码逻辑......
  • 读书笔记:价值投资.03.商业模式是什么
    商业模式是什么这个世界上有很多公司,靠商业模式赚钱.比如Uber,滴滴,几乎不拥有出租车,却是市场上最大的出租车公司.比如airbnb,几乎不拥有任何一家酒店,却是全球......
  • 设计模式之单例模式
    一、什么是单例模式?单例设计模式属于创建型模式范畴,所以主要用于处理对象创建和操作,当我们需要确保只创建一个特定类的实例,然后为整个应用程序提供对该实例的简单全局访问......
  • 设计模式——概览
     设计模式分二十三种,三大类,分别是:对象创建型抽象工厂、生成器、工厂方法、原型、单例结构型适配器、桥接、组合、装饰器、外观、享元、代理行为型责任链、......
  • 手写笔记22:代理模式
    ......