博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
建造者(Builder)模式
阅读量:4037 次
发布时间:2019-05-24

本文共 4295 字,大约阅读时间需要 14 分钟。

当一个对象有很多属性,对属性赋值时,有两种方式,一种是set,一种是构造函数。 通过构造函数的话,属性越多,构造函数不同的场景下需要不同的参数,也就可能会有越多。这个时候,通过建造者模式会比较方面,不同的对象需要不同的属性,只对需要的属性赋值即可。

实现建造者模式的方式有很多种。在此介绍其中两种。

第一种:通用生成器+主管方式

实现步骤:

1、创建通用生成器接口,接口中声明对象属性赋值的方法。

2、创建具体对象类

3、创建具体对象生成器类,实现通用生成器接口。

       3.1 在类中,声明属性,并实现接口方法进行赋值属性。

       3.2 在类中,创建个public方法用来生成具体的对象,返回类型就是要实例化的对象类,这个方法通过调用对象类的构造函数来实现实例化并返回。

4、创建主管类,在主管类中创建生成对象的方法,方法参数是通用生成器接口对象,方法内容就是调用通用生成器接口里的方法进行赋值。

5、创建测试类,测试类中,实例化主管类①,实例化具体对象生成器类②, 调用主管类中的创建生成对象方法,把②作为参数传入。 具体对象的实例化对象,是②调用3.2的方法来创建的。

 

优点:

  • 你可以分步创建对象, 暂缓创建步骤或递归运行创建步骤。
  •  生成不同形式的产品时, 你可以复用相同的制造代码。
  •  单一职责原则。 你可以将复杂构造代码从产品的业务逻辑中分离出来

缺点:由于该模式需要新增多个类, 因此代码整体复杂程度会有所增加

示例代码:

/***用生成器接口*/public interface Builder {    void setType(String type);    void setSeats(int seats);}/***汽车对象生成器类*/public class CarBuilder implements Builder {    private String type;    private int seats;    @Override    public void setType(String type) {        this.type = type;    }    @Override    public void setSeats(int seats) {        this.seats = seats;    }    public Car getResult() {        return new Car(type, seats);    }}/***汽车对象*/public class Car {    private final String type;    private final int seats;    public Car(String type, int seats) {        this.type = type;        this.seats = seats;    }    public String getType() {        return type;    }    public int getSeats() {        return seats;    }}/***主管,控制着构造顺序*/public class Director {    public void constructSportsCar(Builder builder) {        builder.setType("跑车");        builder.setSeats(2);    }    public void constructSUV(Builder builder) {        builder.setType("奔驰SUV");        builder.setSeats(5);    }}/***测试执行类*/public class Demo {    public static void main(String[] args) {        Director director = new Director();        CarBuilder builder = new CarBuilder();		        director.constructSportsCar(builder);        Car car = builder.getResult();        System.out.println("Car built:\n" + car.getType());				director.constructSUV(builder);        Car car2 = builder.getResult();        System.out.println("Car built:\n" + car2.getType());    }}

 

第二种:自构建方式(暂且叫这个吧)

实现步骤:

1、创建对象类,声明属性。在类中创建静态内部生成器类。

2、内部生成器类中,声明跟对象一样的属性。创建给属性赋值的方法,但是方法的返回类型不是void,而是内部生成器类本身,方法返回this,意思是谁调用这个方法就返回谁。

3、内部生成器类中创建public方法,返回类型为对象类,在这个方法中进行实例化对象类。

4、在对象类中,声明有参的私有构造函数,参数是内部生成器类。并把生成器类对象的属性赋值给对象类中的属性。

示例代码:

public class User {    private String name;    private int age;    private String sex;    public static class UserBuilder{        private String name;        private int age;        private String sex;        public UserBuilder setName(String name) {            this.name = name;            return this;        }        public UserBuilder setAge(int age) {            this.age = age;            return this;        }        public UserBuilder setSex(String sex) {            this.sex = sex;            return this;        }        public User build(){            return new User(this);        }    }    private User(UserBuilder userBuilder){        this.age = userBuilder.age;        this.name = userBuilder.name;        this.sex = userBuilder.sex;    }    public String toString() {        return "User{" +        "name='" + name + '\'' +        ", age=" + age +        ", sex='" + sex + '\'' +        '}';    }}public class TestUser {    public static void main(String[] args) {        User user = new User.UserBuilder().setName("张三").setAge(18).setSex("女").build();        System.out.println(user.toString());    }}

第二种方式的实现步骤其实还有一种实现方式。就是不使用内部类的方式,直接修改对象类本身的属性赋值方法,返回类型是对象类本身。

示例代码:

public class UserSelf {    private String name;    private int age;    private String sex;    public UserSelf setName(String name) {        this.name = name;        return this;    }    public UserSelf setAge(int age) {        this.age = age;        return this;    }    public UserSelf setSex(String sex) {        this.sex = sex;        return this;    }    public UserSelf build(){        return this;    }    public String toString() {        return "User{" +                "name='" + name + '\'' +                ", age=" + age +                ", sex='" + sex + '\'' +                '}';    }}public class TestUserSelf {    public static void main(String[] args) {        UserSelf userSelf = new UserSelf().setName("甄姬").setAge(16).setSex("女").build();        System.out.println(userSelf.toString());    }}

 

 

转载地址:http://sqcdi.baihongyu.com/

你可能感兴趣的文章
SQL 多表联合查询
查看>>
Visual Studio 2010:C++0x新特性
查看>>
drwtsn32.exe和adplus.vbs进行dump文件抓取
查看>>
cppcheck c++静态代码检查
查看>>
在C++中使用Lua
查看>>
C++中使用Mongo执行count和distinct运算
查看>>
一些socket的编程经验
查看>>
socket编程中select的使用
查看>>
关于AIS编码解码的两个小问题
查看>>
GitHub 万星推荐:黑客成长技术清单
查看>>
可以在线C++编译的工具站点
查看>>
关于无人驾驶的过去、现在以及未来,看这篇文章就够了!
查看>>
所谓的进步和提升,就是完成认知升级
查看>>
昨夜今晨最大八卦终于坐实——人类首次直接探测到了引力波
查看>>
如何优雅、机智地和新公司谈薪水?
查看>>
为什么读了很多书,却学不到什么东西?
查看>>
长文干货:如何轻松应对工作中最棘手的13种场景?
查看>>
如何用好碎片化时间,让思维更有效率?
查看>>
No.147 - LeetCode1108
查看>>
No.174 - LeetCode1305 - 合并两个搜索树
查看>>