首页 > 其他分享 >设计模式学习(四):建造者模式

设计模式学习(四):建造者模式

时间:2022-11-08 07:55:30浏览次数:60  
标签:builder return int Builder 建造 private 模式 设计模式 public

设计模式学习(四):建造者模式

作者:Grey

原文地址:

博客园:设计模式学习(四):建造者模式

CSDN:设计模式学习(四):建造者模式

建造者模式

建造者模式是创建型模式。

我们在对一个实体类进行属性的 get 或 set 的时候,可以通过封装一些常用的构造方法来简化实体类的构造。

比如 Effective Java 中举到到这个例子

// Effective Java 3th examples
public class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;

    public static class Builder {
        // Required parameters
        private final int servingSize;
        private final int servings;

        // Optional parameters - initialized to default values
        private int calories      = 0;
        private int fat           = 0;
        private int sodium        = 0;
        private int carbohydrate  = 0;

        public Builder(int servingSize, int servings) {
            this.servingSize = servingSize;
            this.servings    = servings;
        }

        public Builder calories(int val) { 
            calories = val;  
            return this;
        }

        public Builder fat(int val) { 
           fat = val;   
           return this;
        }

        public Builder sodium(int val) { 
           sodium = val;  
           return this; 
        }

        public Builder carbohydrate(int val) { 
           carbohydrate = val;  
           return this; 
        }

        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
    }

    private NutritionFacts(Builder builder) {
        servingSize  = builder.servingSize;
        servings     = builder.servings;
        calories     = builder.calories;
        fat          = builder.fat;
        sodium       = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }
}

其中 Builder 就是一个内部类,用于构造 NutritionFacts 的必要信息,外部调用 NutritionFacts 的构造方法时候,可以这样使用:

NutritionFacts cocaCola = new NutritionFacts.Builder(240,8).calories(100).sodium(35).carbohydrate(27).build();

image

构造器模式也适用于类层次结构。抽象类有抽象的 Builder ,具体类有具体的 Builder 。Effective Java中还有一个例子, 假设我们抽象出一个披萨类,各种各样的披萨均可以继承披萨这个抽象类来实现自己的具体类型的披萨。

Pizza抽象类如下:

import java.util.*;

// Effective Java 3th examples
public abstract class Pizza {
    public enum Topping {HAM, MUSHROOM, ONION, PEPPER, SAUSAGE}
    final Set<Topping> toppings;
  
    abstract static class Builder<T extends Builder<T>> {
        EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);

        public T addTopping(Topping topping) {
            toppings.add(Objects.requireNonNull(topping));
            return self();
        }
  
        abstract Pizza build();
  
        // Subclasses must override this method to return "this"
        protected abstract T self();
    }

    Pizza(Builder<?> builder) {
        toppings = builder.toppings.clone(); // See Item 50
    }
}

其中的 Builder 方法是抽象的,所以子类需要实现具体的 Builder 策略,

一种披萨的具体实现 NyPizza

import java.util.Objects;

public class NyPizza extends Pizza {
    public enum Size {SMALL, MEDIUM, LARGE}

    private final Size size;

    public static class Builder extends Pizza.Builder<Builder> {
        private final Size size;

        public Builder(Size size) {
            this.size = Objects.requireNonNull(size);
        }

        @Override
        public NyPizza build() {
            return new NyPizza(this);
        }

        @Override
        protected Builder self() {
            return this;
        }
    }

    private NyPizza(Builder builder) {
        super(builder);
        size = builder.size;
    }
}

另一种披萨的具体实现 Calzone

public class Calzone extends Pizza {
    private final boolean sauceInside;

    public static class Builder extends Pizza.Builder<Builder> {
        private boolean sauceInside = false; // Default

        public Builder sauceInside() {
            sauceInside = true;
            return this;
        }

        @Override
        public Calzone build() {
            return new Calzone(this);
        }

        @Override
        protected Builder self() {
            return this;
        }
    }

    private Calzone(Builder builder) {
        super(builder);
        sauceInside = builder.sauceInside;
    }
}

我们在具体调用的时候,可以通过如下方式:

NyPizza pizza = new NyPizza.Builder(SMALL).addTopping(SAUSAGE).addTopping(ONION).build();
Calzone calzone = new Calzone.Builder().addTopping(HAM).sauceInside().build();

实际应用有非常多,很多组件都提供这样的构造方式,比如 OkHttp Client 的构造方法:

public static OkHttpClient create(long connectTimeOut) {
        return new OkHttpClient().newBuilder().connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS, ConnectionSpec.CLEARTEXT)).connectTimeout(connectTimeOut, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS).retryOnConnectionFailure(true).followRedirects(true).followSslRedirects(true).hostnameVerifier((s, sslSession) -> true).cookieJar(new CookieJar() {
            private List<Cookie> cookies;

            @Override
            public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
                this.cookies = cookies;
            }

            @Override
            public List<Cookie> loadForRequest(HttpUrl url) {
                if (cookies != null) {
                    return cookies;
                }
                return Collections.emptyList();
            }
        }).build();
    }

建造者模式的主要应用

  • JDK 中的 Calender
Calendar calendar = new Calendar.Builder().build();
  • MyBatis 中 CacheBuilder.build()SqlSessionFactoryBuilder.build()

  • Spring 中 BeanDefinitionBuilder.getBeanDefinition()方法

UML 和 代码

UML 图

代码

更多

设计模式学习专栏

参考资料

标签:builder,return,int,Builder,建造,private,模式,设计模式,public
From: https://www.cnblogs.com/greyzeng/p/16868456.html

相关文章

  • 浅谈PHP设计模式的注册树模式
    简介:注册树模式,属于结构型的设计模式。一种很简单的设计模式适用场景:类似IOC。写一个庞大的类库的时候,为了方便各种资源的归纳,可以统一放到一棵树上。优点:把一个个游......
  • 设计模式---装饰器模式
    简述运行时,为原对象拓展新的行为。相较于传统的继承来拓展新的行为,装饰器模式更为的灵活多变,当然实现起来也更为复杂。话不多说,看个优化案例吧。优化案例最初版v0现......
  • 设计模式学习(三):工厂模式
    设计模式学习(三):工厂模式作者:Grey原文地址:博客园:设计模式学习(三):工厂模式CSDN:设计模式学习(三):工厂模式工厂模式工厂模式是创建型模式,工厂模式分为:简单工厂,工厂方法和抽......
  • day24 设计模式
    day24设计模式概述:设计模式是一种解决某个问题的固定模式(原理都是一样的),它不区分语言.常用的设计模式有23种,他分为三类(主要针对的是类和对象)设计......
  • XpSp3(未开启PAE模式)内存管理之系统PTE区域 上
    前言  几年前就已经看过wrk中关于内存管理和缓存管理的实现,由于当时对内核调试尚不熟悉,因此仅仅停留在代码层面。现在结合windbg操作,希望能有新的收获。毛德操的<window......
  • zabbix 主动模式和被动模式的区别
    目录zabbix主动模式和被动模式的区别zabbix主被动模式介绍将监控的主机由被动模式修改为主动模式配置zabbixagent监控主机的被动模式修改为主动模式查看主机链接的模板有......
  • JAVA 模板设计模式
    今天来介绍下一个我觉得蛮不错的设计模式(比较容易应用于业务场景),它就是---模板设计模式。OK,我们直接看代码:模板模式,那当然我们需要建一个模板先,建一个抽象类,VehicleControlM......
  • 23 种设计模式C++实现
    设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:​​单例模式​​、​​原型模式​​、​​工厂方法模式​​、​​抽象工厂模式​​、​​建造者模式​​。结构......
  • 设计模式(十八)桥接模式 C++
    桥接模式即将抽象部分与它的实现部分分离开来,使他们都可以独立变化。桥接模式将继承关系转化成关联关系,它降低了类与类之间的耦合度,减少了系统中类的数量,也减少了代码量。桥......
  • JAVA 责任链设计模式
    这次介绍责任链模式,采用最普遍的请假例子来编码实现。先给列出个模拟的需求,一个人请假,调用一个接口,传入的参数是他请假的天数。然后,请假的天数---->如果小于2天,由直属领导......