0
点赞
收藏
分享

微信扫一扫

Java学习笔记49-【建造者模式,原型模式】

邯唐情感 2022-04-22 阅读 21
java

23种设计模式(2)

一、建造者模式

1. 适用场景

(1)如果需要创建的各种形式的产品,它们的制造过程相似且仅有细节上的差异。
【1】例如建造房屋,由于不同配置的房屋配置不一样,所以重载了构造器后,依旧会有大部分代码重复部分

class House {
    House(int size) { ... }
    House(int size, boolean cheese) { ... }
    House(int size, boolean cheese, boolean pepperoni) { ... }
    // ...

【2】或是一个构造器中注入建造房屋需要的所有参数,当时在使用时,会出现大量参数未使用的情况。
在这里插入图片描述

(2)建造者模式可以分步骤生成对象, 而且允许使用必须的步骤。 应用该模式后, 再也不需要将几十个参数塞进构造函数里了。

2. 实现部分

(1)产品 (Products):是最终生成的产品对象。里面包含建造一个产品所需要的所有属性。但是生产出来的每个产品,不一定都用到全部属性。
(2)建造者接口(Builder):声明构造一个产品所需要的所有步骤。以及返回一个产品的方法。可用接口或者抽象类。
(3)具体的建造类 (Concrete Builders):实现Builder接口,提供构造过程的不同实现。注意在该类中实例化一个产品对象。
(4)主管类(Director):定义调用构造产品的步骤顺序。这样就可以创建和复用特定的产品配置。

在这里插入图片描述

3. 代码实现

(1)产品:FoodProducts类

package builder_module.demo1;

/**
 * @Package: builder_module
 * @ClassName: FoodProducts
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2022/4/18 16:39
 * @Description: 产品 (Products):是最终生成的对象。
 * 食物产品
 */
public class FoodProducts {
    private String rice;
    private String drinks;
    private String table;
    private int people;

    public int getPeople() {
        return people;
    }

    public void setPeople(int people) {
        this.people = people;
    }

    public String getRice() {
        return rice;
    }

    public void setRice(String rice) {
        this.rice = rice;
    }

    public String getDrinks() {
        return drinks;
    }

    public void setDrinks(String drinks) {
        this.drinks = drinks;
    }

    public String getTable() {
        return table;
    }

    public void setTable(String table) {
        this.table = table;
    }

    @Override
    public String toString() {
        return "FoodProductst套餐{" +
                "rice='" + rice + '\'' +
                ", drinks='" + drinks + '\'' +
                ", table='" + table + '\'' +
                ", people=" + people +
                '}';
    }
}


(2)建造者接口:Builder接口

package builder_module.demo1;

/**
 * @Package: builder_module
 * @ClassName: Builder
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2022/4/18 16:25
 * @Description: 建造者接口(Builder)
 *               声明构造一个产品所需要的所有步骤。
 * 干饭人
 */
public interface Builder {
    void selectRice(); //选择米饭
    void selectDrinks(); //选择饮料
    void selectTable(); //选择餐桌
    void selectPeople(); //选择就餐人数

    FoodProducts getProducts();
}


(3)具体的建造类:work类

package builder_module.demo1;

/**
 * @Package: builder_module
 * @ClassName: work
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2022/4/18 16:52
 * @Description: 实现Builder接口
 * 厨师
 */
public class work implements Builder {

    private FoodProducts foodProducts;

    public work() {
        foodProducts = new FoodProducts();
    }

    @Override
    public void selectRice() {
        foodProducts.setRice("选择米饭");
        System.out.println("选择米饭");
    }

    @Override
    public void selectDrinks() {
        System.out.println("选择饮料");
        foodProducts.setDrinks("选择饮料");
    }

    @Override
    public void selectTable() {
        System.out.println("选择桌子");
        foodProducts.setTable("选择餐桌");
    }

    @Override
    public void selectPeople() {
        System.out.println("选择就餐人数");
        foodProducts.setPeople(4);
    }

    @Override
    public FoodProducts getProducts() {
        return foodProducts;
    }
}

(4)主管类:Director类

package builder_module.demo1;

/**
 * @Package: builder_module
 * @ClassName: Director
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2022/4/18 20:08
 * @Description: 指挥类:定义调用构造步骤的顺序
 * 前台服务员
 */
public class Director {
    // 前台服务员收到干饭人的点餐需求(先选就餐人数,再选桌子,再选米饭,最后选饮料)
    // 然后返回一个食品套餐
    public FoodProducts build(Builder builder){
        builder.selectPeople(); //1.选择就餐人数
        builder.selectTable(); //2. 先选桌子
        //builder.selectRice();  //3. 再选米饭
        builder.selectDrinks(); //4. 最后选饮料

        return builder.getProducts();
    }
}

(5)测试类

package builder_module.demo1;

/**
 * @Package: builder_module
 * @ClassName: test
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2022/4/18 20:32
 * @Description:  测试类
 */
public class test {
    public static void main(String[] args) {
        //1. 前台服务员
        Director director = new Director();
        //2. 前台服务员 指挥具体的厨师 建造产品
        FoodProducts build = director.build(new work());
        System.out.println(build);
    }
}

二、原型模式(亦称: 克隆、Clone、Prototype)

1. 作用

能够复制已有对象, 而又无需使代码依赖它们所属的类。

2. 适用场景

当要大量复制一个对象,或者不想创建一个很复杂的对象,可用原型模式

3. 实现

(1)原型接口(Prototype):在其中声明克隆方法。该接口可用使用自带的cloneable接口。
(2)原型类(Concrete Prototype):将实现克隆方法。 将原始对象的数据复制到克隆体中。

【1】浅克隆
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

【2】深克隆
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 代码

  1. 形状的原型接口
package prototype.demo1;

/**
 * @Package: prototype
 * @ClassName: ShapePrototype
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2022/4/22 10:11
 * @Description:  形状的原型接口
 */
public interface ShapePrototype {
    ShapePrototype clone();
}

  1. 具体的原型类 —— 矩形
package prototype.demo1;

/**
 * @Package: prototype
 * @ClassName: RectangleConcretePrototype
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2022/4/22 10:14
 * @Description: 具体的原型类 —— 矩形
 */
public class RectangleConcretePrototype implements ShapePrototype{
    private int x;
    private int y;
    private String color;
    private RectangleConcretePrototype re;

    public RectangleConcretePrototype() {
    }

    public RectangleConcretePrototype(int x, int y, String color) {
        this.x = x;
        this.y = y;
        this.color = color;
    }

    @Override
    public ShapePrototype clone() {
        //深克隆
        re = new RectangleConcretePrototype();
        re.x = this.x;
        re.y = this.y;
        re.color = this.color;
        return re;
        
        //浅克隆
        //re = this;
        //return re;
    }

    @Override
    public String toString() {
        return "x=" + x +
                ", y=" + y +
                ", color='" + color + '\'';
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}


  1. 测试类
package prototype.demo1;

/**
 * @Package: prototype
 * @ClassName: test
 * @Author: 爱吃凉拌辣芒果
 * @CreateTime: 2022/4/22 10:18
 * @Description: 测试类
 */
public class test {
    public static void main(String[] args) {
        RectangleConcretePrototype prototype =
                new RectangleConcretePrototype(1, 2, "黄色");
        ShapePrototype clone = prototype.clone();
        System.out.println("原型-> "+prototype.hashCode());
        System.out.println("克隆-> "+clone.hashCode());
        System.out.println("原型-> "+prototype);
        System.out.println("克隆-> "+clone);
        prototype.setColor("绿色");
        System.out.println("原型-> "+prototype);
        System.out.println("克隆-> "+clone);
    }
}

package prototype.demo1;

public class RectangleConcretePrototype1 implements Cloneable{
    private int x;
    private int y;
    private String color;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        RectangleConcretePrototype1 clone =
                (RectangleConcretePrototype1) super.clone();
        return clone;
    }

    public RectangleConcretePrototype1(int x, int y, String color) {
        this.x = x;
        this.y = y;
        this.color = color;
    }

    @Override
    public String toString() {
        return "x=" + x +
                ", y=" + y +
                ", color='" + color + '\'';
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

在这里插入图片描述

举报

相关推荐

0 条评论