外观模式和建造者模式

1、外观模式

  • 思想:

为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

注:采用大话设计模式的例子

例:股民炒股代码

1.1、首次编写时:

我们编写股票类,对应每一种股票都需要一个实体类

public class Stock1 {
    
    
    /*
     * 股票售出
     */
    public void sell() {
    
    
        System.out.println("股票1卖出");
    }
    /*
     * 股票买进
     */
    public void buy() {
    
    
        System.out.println("股票一买进");
    }
}

public class Stock2 {
    
    
    /*
     * 股票售出
     */
    public void sell() {
    
    
        System.out.println("股票2卖出");
    }
    /*
     * 股票买进
     */
    public void buy() {
    
    
        System.out.println("股票2买进");
    }
}

public class Stock3 {
    
    
    /*
     * 股票售出
     */
    public void sell() {
    
    
        System.out.println("股票3卖出");
    }
    /*
     * 股票买进
     */
    public void buy() {
    
    
        System.out.println("股票3买进");
    }
}

public class NationalDebt1 {
    
    
    /*
     * 股票售出
     */
    public void sell() {
    
    
        System.out.println("房地产1卖出");
    }
    /*
     * 股票买进
     */
    public void buy() {
    
    
        System.out.println("房地产1买进");
    }
}

public class Realty1 {
    
    
    /*
     * 股票售出
     */
    public void sell() {
    
    
        System.out.println("国债1卖出");
    }
    /*
     * 股票买进
     */
    public void buy() {
    
    
        System.out.println("国债1买进");
    }
}

public class Test {
    
    
    /** 
     * @Title: main  
     * @Description: TODO 
     * @return void
     */
    public static void main(String[] args) {
    
    
        Stock1 stock1 = new Stock1();
        Stock2 stock2 = new Stock2();
        Stock3 stock3 = new Stock3();
        Realty1 realty1 = new Realty1();
        NationalDebt1 nationalDebt1 = new NationalDebt1();
        stock1.buy();
        stock2.sell();
        stock3.buy();
        realty1.buy();
        nationalDebt1.sell();
    }
}

而这时我们会发现其实每个类的代码基本大同小异,但是测试类却需要将每一个类进行实例化。

1.2、我们需要增加投资基金

public class Fund {
    
    
    private Stock1 stock1;
    private Stock2 stock2;
    private Stock3 stock3;
    private NationalDebt1 nationalDebt1;
    private Realty1 realty1;
    public Fund() {
    
    
        this.stock1 = new Stock1();
        this.stock2 = new Stock2();
        this.stock3 = new Stock3();
        this.nationalDebt1 = new NationalDebt1();
        this.realty1 = new Realty1();
    }
    /** 
     * @Title: buyFund  
     * @Description: TODO 
     * @return void
     */
    public void buyFund() {
    
    
        stock1.buy();
        stock2.buy();
        stock3.buy();
        nationalDebt1.buy();
        realty1.buy();
    }
    
    /** 
     * @Title: sellFund  
     * @Description: TODO 
     * @return void
     */
    public void sellFund() {
    
    
        stock1.sell();
        stock2.sell();
        stock3.sell();
        nationalDebt1.sell();
        realty1.sell();
    }
    
}

public class Test {
    
    

    /**
     * @Title: main
     * @Description: TODO
     * @return void
     */
    public static void main(String[] args) {
    
    
        Fund fund = new Fund();
        fund.buyFund();
        fund.sellFund();
    }

}

此时整个测试感觉稍好一些,用户只需知道基金,不需要知道内部的构成,但是测试类整体逻辑更清晰。

2、建造者模式

  • 目的:

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

例:

假设造房简化为如下步骤:(1)地基(2)钢筋工程(3)铺电线(4)粉刷

“如果”要盖一座房子,首先要找一个建筑公司或工程承包商(指挥者)。承包商指挥工人(具体建造者)过来造房子(产品),最后验收。

2.1、第一种做法具体步骤

1、创建抽象建造者定义造房步骤
2、创建工人具体实现造房步骤
3、创建承包商指挥工人施工
4、验收,检查是否建造完成

//最后的产品(房屋)
public class Product {
    
    
    private String buildA;
    private String buildB;
    private String buildC;
    private String buildD;
    public String getBuildA() {
    
    
        return buildA;
    }
    public void setBuildA(String buildA) {
    
    
        this.buildA = buildA;
    }
    public String getBuildB() {
    
    
        return buildB;
    }
    public void setBuildB(String buildB) {
    
    
        this.buildB = buildB;
    }
    public String getBuildC() {
    
    
        return buildC;
    }
    public void setBuildC(String buildC) {
    
    
        this.buildC = buildC;
    }
    public String getBuildD() {
    
    
        return buildD;
    }
    public void setBuildD(String buildD) {
    
    
        this.buildD = buildD;
    }
    @Override
    public String toString() {
    
    
        return "Product [buildA=" + buildA + ", buildB=" + buildB + ", buildC=" + buildC + ", buildD=" + buildD + "]";
    }
}

//创建者接口
public interface Builder {
    
    
    //地基
    void bulidA();
    //钢筋工程
    void bulidB();
    //铺电线
    void bulidC();
    //粉刷
    void bulidD();
    //完工-获取产品
    Product getProduct();
}
//具体创建者
public class ConcreteBuilder implements Builder {
    
    
    private Product product;
    public ConcreteBuilder() {
    
    
        product = new Product();
    }
    @Override
    public void bulidA() {
    
    
        product.setBuildA("地基");
    }

    @Override
    public void bulidB() {
    
    
        product.setBuildB("钢筋");
    }

    @Override
    public void bulidC() {
    
    
        product.setBuildC("电线");
    }

    @Override
    public void bulidD() {
    
    
        product.setBuildD("粉刷");
    }

    @Override
    public Product getProduct() {
    
    
        return product;
    }

}
//我们通过指挥者建造
public class Director {
    
    
  //指挥工人按顺序造房
    public Product create(Builder builder) {
    
    
        builder.bulidA();
        builder.bulidB();
        builder.bulidC();
        builder.bulidD();
        return builder.getProduct();
    }
}
//主函数通过自己创建一个具体建造者,并将具体建造者产地给指挥者便可完成建造
public class Test {
    
    
    public static void main(String[] args) {
    
    
        Director director = new Director();
        Product create = director.create(new ConcreteBuilder());
        System.out.println(create.toString());
    }
}

2.2、第二种做法具体步骤

当然我们也可以没有指挥者,直接用户调用,但是细节部分需要加以变化

1、创建建造者定义产品

2、创建具体建造者实现具体产品

3、客户端随意搭配

//Product类没有任何变化,直接粘过来即可
//相对于之前的写法返回值有所变化,否则测试类对任何一个属性赋值都要独立写一行,相对来说比较繁琐   
public interface Builder {
    
    
    //地基
    Builder bulidA();
    //钢筋工程
    Builder bulidB();
    //铺电线
    Builder bulidC();
    //粉刷
    Builder bulidD();
    //完工-获取产品
    Product getProduct();
}
//具体建造者
public class ConcreteBuilder implements Builder {
    
    
    private Product product;
    public ConcreteBuilder() {
    
    
        product = new Product();
    }
    @Override
    public Builder bulidA() {
    
    
        product.setBuildA("地基");
        return this;
    }

    @Override
    public Builder bulidB() {
    
    
        product.setBuildB("钢筋");
        return this;
    }

    @Override
    public Builder bulidC() {
    
    
        product.setBuildC("电线");
        return this;
    }

    @Override
    public Builder bulidD() {
    
    
        product.setBuildD("粉刷");
        return this;
    }

    @Override
    public Product getProduct() {
    
    
        return product;
    }

}
//主函数测试类,同时也相当于指挥者的作用
public class Test {
    
    
    public static void main(String[] args) {
    
    
        Builder concreBuilder = new ConcreteBuilder();
        Product product = concreBuilder
                .bulidA()
                .bulidB()
                .bulidC()
                .bulidD().getProduct();
        System.out.println(product.toString());
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37771811/article/details/103843774
今日推荐