【Java设计模式】原型模式、建造者模式

原型模式

概述

用一个已经创建的实例体为原型,通过复制该原型对象来创建一个和原型对象相同的对象。

结构

原型模式包含如下角色:

  • 抽象原型类:规定了具体原型对象必须实现的的clone ()方法。
  • 具体原型类:实现抽象原型类的clone ()方法,它是可被复制的对象。
  • 访问类:使用具体原型类中的clone ()方法来复制新的对象。

接口类图如下:
在这里插入图片描述

实现

原型模式的克隆分为浅克隆和深克隆。

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

Java中的object类中提供了clone()方法来实现浅克隆。Cloneable接口是上面的类图中的抽象原型类,而实现了Cloneable接口的子实现类就是具体的原型类。代码如下:

Realizetype(具体的原型类):

public class Realizetype implements Cloneable{

    public Realizetype() {
        System.out.println("具体的原型对象创建完成");
    }

    @Override
    public Realizetype clone() throws CloneNotSupportedException {
        System.out.println("具体原型复制成功");
        return (Realizetype) super.clone();
    }
}

测试类:

public class client {
    public static void main(String[] args) throws CloneNotSupportedException {
        //创建一个原型对象
        Realizetype realizetype = new Realizetype();

        Realizetype clone = realizetype.clone();

        System.out.println("原型对象和克隆出来的是否是同一个对象?"+(realizetype == clone));
    }
}

案例

用原型模式生成"三好学生"奖状

同一学校的"三好学生"奖状除了获奖人姓名不同,其他都相同,可以使用原型模式复制多个"三好学生奖状出来,然后在修改奖状上的名字即可。

类图如下:
在这里插入图片描述
学生类

public class Student implements Cloneable{
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public Student clone() throws CloneNotSupportedException {
        return (Student) super.clone();
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

奖状类

public class Citation implements Cloneable{
    private Student student;

    public void setStudent(Student student) {
        this.student = student;
    }

    public Student getStudent() {
        return student;
    }

    @Override
    public Citation clone() throws CloneNotSupportedException {
        Citation citation = (Citation) super.clone();
        citation.student = student.clone();
        return citation;
    }

    public void show(){
        System.out.println(student.getName()+ "同学:在2021学年第一学期中表现优秀被评为三好学生,特发此状!");
    }
}

测试类

public class client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Citation citation = new Citation();
        Student student1 = new Student("李洛", 18);
        citation.setStudent(student1);

        Citation clone = citation.clone();
        clone.getStudent().setName("牧尘");


        citation.show();
        clone.show();
    }
}

建造者模式

概述

  • 分离了部件的构造(由Builder来负责)和装配(由Director负责)。从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况。
  • 由于实现了构建和装配的解耦。不同的构建器,相同的装配,也可以做出不同的对象;相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算法的解耦,实现了更好的复用。
  • 建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节。

结构

建造者(Builder)模式包含如下角色:

  • 抽象建造者类(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的对象部件的创建。
  • 具体建造者类(ConcreteBuilder):实现Builder接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供产品的实例。
  • 产品类(Product)︰要创建的复杂对象。
  • 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。

类图如下:
在这里插入图片描述

实例

创建共享单车

生产自行车是一个复杂的过程,它包含了车架,车座等组件的生产。而车架又有碳纤维,铝合金等材质的,车座有橡胶,真皮等材质。对于自行车的生产就可以使用建造者模式。

这里Bike是产品,包含车架,车座等组件; Builder是抽象建造者,MobikeBuilder和ofoBuilder是具体的建造者; Director是指挥者。类图如下:
在这里插入图片描述
产品类

//产品对象
public class Bike {
    private String frame;//车架
    private String seat;//车座

    public String getFrame() {
        return frame;
    }

    public void setFrame(String frame) {
        this.frame = frame;
    }

    public String getSeat() {
        return seat;
    }

    public void setSeat(String seat) {
        this.seat = seat;
    }
}

抽象建造者类

public abstract class Builder {

    //声明Bike类型的变量,并进行赋值
    protected Bike bike = new Bike();

    public abstract void builderFrame();

    public abstract void builderSeat();

    //构建自行车的方法
    public abstract Bike createBike();


}

具体建造者类

public class MobileBuilder extends Builder{
    @Override
    public void builderFrame() {
        bike.setFrame("碳纤维");

    }

    @Override
    public void builderSeat() {
        bike.setSeat("真皮");

    }

    @Override
    public Bike createBike() {
        return bike;
    }
}
public class OfoBuilder extends Builder{
    @Override
    public void builderFrame() {
        bike.setFrame("铝合金");
    }

    @Override
    public void builderSeat() {
        bike.setSeat("橡胶车座");
    }

    @Override
    public Bike createBike() {
        return bike;
    }
}

** 指挥者类**

//指挥者类
public class Director {
    private Builder builder;

    public Director() {
    }

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void setBuilder(Builder builder) {
        this.builder = builder;
    }

    //组装自行车
    public Bike construct(){
        builder.builderFrame();
        builder.builderSeat();
        return builder.createBike();

    }
}

客户端

public class Client {
    public static void main(String[] args) {
        Director director = new Director();
        director.setBuilder(new MobileBuilder());

        Bike bike = director.construct();
        System.out.println(bike.getFrame());
        System.out.println(bike.getSeat());
    }
}

模式扩展

public class Phone {
    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;

    public static final class Builder{
        private String cpu;
        private String screen;
        private String memory;
        private String mainboard;

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

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

        public Builder memory(String memory){
            this.memory = memory;
            return  this;
        }
        public Builder mainboard(String mainboard){
            this.mainboard = mainboard;
            return this;
        }

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

    public Phone() {
    }

    private Phone(Builder builder){
        this.cpu = builder.cpu;
        this.screen = builder.screen;
        this.memory = builder.memory;
        this.mainboard = builder.mainboard;
    }

    public Phone(String cpu, String screen, String memory, String mainboard) {
        this.cpu = cpu;
        this.screen = screen;
        this.memory = memory;
        this.mainboard = mainboard;
    }

    public String getCpu() {
        return cpu;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public String getScreen() {
        return screen;
    }

    public void setScreen(String screen) {
        this.screen = screen;
    }

    public String getMemory() {
        return memory;
    }

    public void setMemory(String memory) {
        this.memory = memory;
    }

    public String getMainboard() {
        return mainboard;
    }

    public void setMainboard(String mainboard) {
        this.mainboard = mainboard;
    }

    @Override
    public String toString() {
        return "Phone{" +
                "cpu='" + cpu + '\'' +
                ", screen='" + screen + '\'' +
                ", memory='" + memory + '\'' +
                ", mainboard='" + mainboard + '\'' +
                '}';
    }
}

客户端

public class Client {
    public static void main(String[] args) {
        Phone phone = new Phone.Builder()
                .cpu("intel")
                .screen("三星")
                .memory("金士顿")
                .mainboard("华硕")
                .build();

        System.out.println("链接编程风格====="+phone);

        Phone phone1 = new Phone("intel", "三星", "金士顿", "华硕");
        System.out.println("常规赋值风格====="+phone1);



    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值