设计模式系列--原型&建造者

原型模式与建造者模式都属于创建型的模式,也是比较常见的模式。

1. 原型模式

原型模式常常用于复杂对象的复制,常常将需要用到原型模式的类设计成 Cloneable,这种方式实现的是浅克隆。如果需要实现深克隆,则需要将其成员对应的类也设计成 Cloneable,并进行递归,这种方式比较繁琐,通常我们使用一种简便的方式——序列化和反序列化,采用这种方式要求我们将需要序列化的类及其成员对应的类设计成 Seriable。

public class PrototypeBean implements Cloneable, Serializable {
    private long id;
    private String name;
    private Address address;

    public PrototypeBean() {}

    public PrototypeBean(long id, String name) {
        this(id, name, null);
    }

    public PrototypeBean(long id, String name, Address address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "PrototypeBean{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", address=" + address +
                '}';
    }

	// 浅克隆
    @Override
    public PrototypeBean clone() throws CloneNotSupportedException {
        return (PrototypeBean) super.clone();
    }
	
	// 深克隆
    public PrototypeBean cloneDeeply() throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(baos);
            oos.writeObject(this);
        } finally {
            if (oos != null) oos.close();
        }

        ObjectInputStream ois = null;
        PrototypeBean result;
        try {
            ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
            result = (PrototypeBean) ois.readObject();
        } finally {
            if (ois != null) ois.close();
        }

        return result;
    }

    public static class Address implements Cloneable, Serializable {
        private String nation;
        private String province;
        private String city;
        private String detail;

        public String getNation() {
            return nation;
        }

        public void setNation(String nation) {
            this.nation = nation;
        }

        public String getProvince() {
            return province;
        }

        public void setProvince(String province) {
            this.province = province;
        }

        public String getCity() {
            return city;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public String getDetail() {
            return detail;
        }

        public void setDetail(String detail) {
            this.detail = detail;
        }

        @Override
        protected Address clone() throws CloneNotSupportedException {
            return (Address) super.clone();
        }

        @Override
        public String toString() {
            return "Address{" +
                    "nation='" + nation + '\'' +
                    ", province='" + province + '\'' +
                    ", city='" + city + '\'' +
                    ", detail='" + detail + '\'' +
                    '}';
        }
    }
}

2. 建造者模式

建造者模式将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
经典的应用场景如 StringBuilder 构建 String,MyBatis 中使用 SqlBuilder 构建 SQL,SpringBoot 中使用 SpringApplicationBuilder 构造 SpringApplication。

以下示例中,我们有一个表示运单的类 Waybill,该类对应一个建造者 WaybillBuilder。

public class Waybill {
    // 运单号
    private String billNum;
    // 货物类型
    private String cargoType;
    // 货物名
    private String cargoName;
    // 货物重量
    private String cargoWeight;
    // 货物体积
    private String cargoVolume;
    // 运单费用
    private String fee;
    // 发件人信息
    private EntityInfo sender;
    // 收件人信息
    private EntityInfo recipient;

    public String getBillNum() {
        return billNum;
    }

    public void setBillNum(String billNum) {
        this.billNum = billNum;
    }

    public String getCargoType() {
        return cargoType;
    }

    public void setCargoType(String cargoType) {
        this.cargoType = cargoType;
    }

    public String getCargoName() {
        return cargoName;
    }

    public void setCargoName(String cargoName) {
        this.cargoName = cargoName;
    }

    public String getCargoWeight() {
        return cargoWeight;
    }

    public void setCargoWeight(String cargoWeight) {
        this.cargoWeight = cargoWeight;
    }

    public String getCargoVolume() {
        return cargoVolume;
    }

    public void setCargoVolume(String cargoVolume) {
        this.cargoVolume = cargoVolume;
    }

    public String getFee() {
        return fee;
    }

    public void setFee(String fee) {
        this.fee = fee;
    }

    public EntityInfo getSender() {
        return sender;
    }

    public void setSender(EntityInfo sender) {
        this.sender = sender;
    }

    public EntityInfo getRecipient() {
        return recipient;
    }

    public void setRecipient(EntityInfo recipient) {
        this.recipient = recipient;
    }

    // 收件人/发件人实体信息类
    public static class EntityInfo {
        private String name;
        private String phone;
        private String address;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getPhone() {
            return phone;
        }

        public void setPhone(String phone) {
            this.phone = phone;
        }

        public String getAddress() {
            return address;
        }

        public void setAddress(String address) {
            this.address = address;
        }
    }
}
public class WaybillBuilder {
    private Waybill waybill;

    public WaybillBuilder() {
        this.waybill = new Waybill();
        this.waybill.setSender(new Waybill.EntityInfo());
        this.waybill.setRecipient(new Waybill.EntityInfo());
    }

    public WaybillBuilder setBillNum(String billNum) {
        this.waybill.setBillNum(billNum);

        return this;
    }

    public WaybillBuilder setCargoType(String cargoType) {
        this.waybill.setCargoType(cargoType);

        return this;
    }

    public WaybillBuilder setCargoName(String cargoName) {
        this.waybill.setCargoName(cargoName);

        return this;
    }

    public WaybillBuilder setCargoWeight(String cargoWeight) {
        this.waybill.setCargoWeight(cargoWeight);

        return this;
    }

    public WaybillBuilder setCargoVolume(String cargoVolume) {
        this.waybill.setCargoVolume(cargoVolume);

        return this;
    }

    public WaybillBuilder setFee(String fee) {
        this.waybill.setFee(fee);

        return this;
    }

    public WaybillBuilder setSenderName(String senderName) {
        this.waybill.getSender().setName(senderName);

        return this;
    }

    public WaybillBuilder setSenderPhone(String senderPhone) {
        this.waybill.getSender().setPhone(senderPhone);

        return this;
    }

    public WaybillBuilder setSenderAddress(String senderAddress) {
        this.waybill.getSender().setAddress(senderAddress);

        return this;
    }

    public WaybillBuilder setRecipientName(String recipientName) {
        this.waybill.getRecipient().setName(recipientName);

        return this;
    }

    public WaybillBuilder setRecipientPhone(String recipientPhone) {
        this.waybill.getRecipient().setPhone(recipientPhone);

        return this;
    }

    public WaybillBuilder setRecipientAddress(String recipientAddress) {
        this.waybill.getRecipient().setAddress(recipientAddress);

        return this;
    }

    public Waybill build() {
        return this.waybill;
    }
}

3. 对比

这两种设计模式都用于复杂对象的创建,前者通过对象的复制来提高对象的创建效率。后者是通过隐藏对象的创建细节(通常是比较复杂,涉及一系列固定的算法,而非简单的对成员的赋值),降低用户创建对象的难度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java设计模式是一组经过实践验证的面向对象设计原则和模式,可以帮助开发人员解决常见的软件设计问题。下面是常见的23种设计模式: 1. 创建型模式(Creational Patterns): - 工厂方法模式(Factory Method Pattern) - 抽象工厂模式(Abstract Factory Pattern) - 单例模式(Singleton Pattern) - 原型模式(Prototype Pattern) - 建造者模式(Builder Pattern) 2. 结构型模式(Structural Patterns): - 适配器模式(Adapter Pattern) - 桥接模式(Bridge Pattern) - 组合模式(Composite Pattern) - 装饰器模式(Decorator Pattern) - 外观模式(Facade Pattern) - 享元模式(Flyweight Pattern) - 代理模式(Proxy Pattern) 3. 行为型模式(Behavioral Patterns): - 责任链模式(Chain of Responsibility Pattern) - 命令模式(Command Pattern) - 解释器模式(Interpreter Pattern) - 迭代器模式(Iterator Pattern) - 中介者模式(Mediator Pattern) - 备忘录模式(Memento Pattern) - 观察者模式(Observer Pattern) - 状态模式(State Pattern) - 策略模式(Strategy Pattern) - 模板方法模式(Template Method Pattern) - 访问者模式(Visitor Pattern) 4. 并发型模式(Concurrency Patterns): - 保护性暂停模式(Guarded Suspension Pattern) - 生产者-消费者模式(Producer-Consumer Pattern) - 读写锁模式(Read-Write Lock Pattern) - 信号量模式(Semaphore Pattern) - 线程池模式(Thread Pool Pattern) 这些设计模式可以根据问题的特点和需求来选择使用,它们提供了一些可复用的解决方案,有助于开发高质量、可维护且易于扩展的软件系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值