freelancerh
4/26/2020 - 3:18 AM

builder模式

1.对象构造 2.方法参数构造 3.接口子类构造 4.接口静态方法构造

/**
 * 对象构造器模式
 */
public class ComplexClass {
    /**
     * 必要字段
     */
    private int a;
    private int b;
    private String c;
    private double d;

    public ComplexClass(int a, int b, String c, double d) {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }

    public static class Builder{
        /**
         * 将所有需要构建的字段添加构建类里
         */
        private int a;
        private int b;
        private String c;
        private double d;

        public Builder(int a){
            this.a = a;
            this.b = 0;
            this.c = "";
            this.d = 0;
        }

        public Builder withB(int b){
            this.b = b;
            return this;
        }

        public Builder withC(String c){
            this.c = c;
            return this;
        }

        public Builder withD(double d){
            this.d = d;
            return this;
        }

        public ComplexClass build(){
            return new ComplexClass(a, b, c, d);
        }
    }
}
import java.math.BigDecimal;

/**
 * @author zengb
 * Create at: 2020/4/26 11:29
 */
public class ComplexMethod {

    /**
     * 参数 a, b 是必须字段
     */
    public int calculate(int a, int b){
        return calculate(a, b, "", 0);
    }

    public int calculate(int a, int b, String c, double d){
        return calculate(a, b, c, d, false);
    }

    public int calculate(int a, int b, String c, double d, boolean e){
        return calculate(a, b, c, d, e, BigDecimal.ZERO);
    }

    public int calculate(int a, int b, String c, double d, boolean e, BigDecimal f){
        // 忽略计算过程
        return 0;
    }

    public int calculate2(int a, int b, String c, double d, boolean e, BigDecimal f){
        // 忽略计算过程
        return 0;
    }

}


/**
 * 方法有很多个参数,且其中部分参数是可以选的。
 */
class ComplexMethod1 {

    public static void main(String[] args) {

    }

    public int caculate(CalculateParamBuilder calculateParamBuilder){
        return calculate(calculateParamBuilder.getA(), calculateParamBuilder.getB(), calculateParamBuilder.getC(),
                calculateParamBuilder.getD(),calculateParamBuilder.isE(), calculateParamBuilder.getF());
    }

    public int calculate(int a, int b, String c, double d, boolean e, BigDecimal f){
        // 忽略计算过程
        return 0;
    }

    public static class CalculateParamBuilder{
        private int a;
        private int b;
        private String c;
        private double d;
        private boolean e;
        private BigDecimal f;

        public static CalculateParamBuilder craete(int a, int b){
            return new CalculateParamBuilder(a, b);
        }

        public CalculateParamBuilder(int a, int b){
            this.a = a;
            this.b = b;
            this.c = "";
            this.d = 0;
            this.e = false;
            this.f = BigDecimal.ZERO;
        }

        public CalculateParamBuilder withC(String c){
            this.c = c;
            return this;
        }

        public CalculateParamBuilder withD(double d){
            this.d = d;
            return this;
        }

        public CalculateParamBuilder withE(boolean e){
            this.e = e;
            return this;
        }

        public CalculateParamBuilder withF(BigDecimal f){
            this.f = f;
            return this;
        }

        public int getA() {
            return a;
        }

        public int getB() {
            return b;
        }

        public String getC() {
            return c;
        }

        public double getD() {
            return d;
        }

        public boolean isE() {
            return e;
        }

        public BigDecimal getF() {
            return f;
        }
    }
}


/**
 * 有多个方法,这些方法参数相同,其中某些参数是必要参数,有些是非必要参数
 */
class ComplexMethod2 {

    public CalculateParamBuilder createCalculate(int a, int b){
        return new CalculateParamBuilder(this, a, b);
    }

    public int calculate(int a, int b, String c){
        // 忽略计算过程
        return 0;
    }

    public int calcuate2(int a, int b, String c){
        // 忽略计算过程
        return 0;
    }

    public int calculate(CalculateParamBuilder calculateParamBuilder){
        // 忽略计算过程
        return calculate(calculateParamBuilder.getA(), calculateParamBuilder.getB(), calculateParamBuilder.getC());
    }

    public int calculate2(CalculateParamBuilder calculateParamBuilder){
        // 忽略计算过程
        return calcuate2(calculateParamBuilder.getA(), calculateParamBuilder.getB(), calculateParamBuilder.getC());
    }


    public static class CalculateParamBuilder{
        private int a;
        private int b;
        private String c;
        private ComplexMethod2 complexMethod2;

        public CalculateParamBuilder(ComplexMethod2 complexMethod2, int a, int b){
            this.complexMethod2 = complexMethod2;
            this.a = a;
            this.b = b;
            this.c = "";
        }

        public CalculateParamBuilder withC(String c){
            this.c = c;
            return this;
        }

        public int getA() {
            return a;
        }

        public int getB() {
            return b;
        }

        public String getC() {
            return c;
        }

        public int calculate(){
            return complexMethod2.calculate(this);
        }

        public int calculate2(){
            return complexMethod2.calculate2(this);
        }
    }
}

class Test{
    public static void main(String[] args) {
        ComplexMethod1 complexMethod1 = new ComplexMethod1();
        ComplexMethod1.CalculateParamBuilder builder = ComplexMethod1.CalculateParamBuilder.craete(1, 2).withC("hello").withD(3);
        int result1 = complexMethod1.caculate(builder);

        int result2 = new ComplexMethod2().createCalculate(1, 2).withC("hello").calculate();
    }
}
// 子类构造器。所有默认子类构造器封装在一起,可以有公共的父类。摘录自com.codahale.metrics.MetricRegistry
private interface MetricBuilder<T extends Metric> {
    MetricBuilder<Counter> COUNTERS = new MetricBuilder<Counter>() {
        @Override
        public Counter newMetric() {
            return new Counter();
        }

        @Override
        public boolean isInstance(Metric metric) {
            return Counter.class.isInstance(metric);
        }
    };

    MetricBuilder<Histogram> HISTOGRAMS = new MetricBuilder<Histogram>() {
        @Override
        public Histogram newMetric() {
            return new Histogram(new ExponentiallyDecayingReservoir());
        }

        @Override
        public boolean isInstance(Metric metric) {
            return Histogram.class.isInstance(metric);
        }
    };

    MetricBuilder<Meter> METERS = new MetricBuilder<Meter>() {
        @Override
        public Meter newMetric() {
            return new Meter();
        }

        @Override
        public boolean isInstance(Metric metric) {
            return Meter.class.isInstance(metric);
        }
    };

    MetricBuilder<Timer> TIMERS = new MetricBuilder<Timer>() {
        @Override
        public Timer newMetric() {
            return new Timer();
        }

        @Override
        public boolean isInstance(Metric metric) {
            return Timer.class.isInstance(metric);
        }
    };

    T newMetric();

    boolean isInstance(Metric metric);
}
/**
 * 接口静态方法构造实例。方法名即为构造出类的特性。摘录自com.codahale.metrics.MetricFilter
 * A filter used to determine whether or not a metric should be reported, among other things.
 */
public interface MetricFilter {
    /**
     * Matches all metrics, regardless of type or name.
     */
    MetricFilter ALL = (name, metric) -> true;

    static MetricFilter startsWith(String prefix) {
        return (name, metric) -> name.startsWith(prefix);
    }

    static MetricFilter endsWith(String suffix) {
        return (name, metric) -> name.endsWith(suffix);
    }

    static MetricFilter contains(String substring) {
        return (name, metric) -> name.contains(substring);
    }

    /**
     * Returns {@code true} if the metric matches the filter; {@code false} otherwise.
     *
     * @param name   the metric's name
     * @param metric the metric
     * @return {@code true} if the metric matches the filter
     */
    boolean matches(String name, Metric metric);
}