做网站书,网站制作的部分,整站seo排名要多少钱,青岛seo外包公司文章目录 建造者模式概述经典的建造者模式建造者模式的变种总结 建造者模式概述
建造者模式是一种广泛使用的设计模式#xff0c;在三方开源库和各种SDK中经常见到。建造者设计模式在四人帮的经典著作《设计模式#xff1a;可复用面向对象软件基础》中被提及#xff0c;它的… 文章目录 建造者模式概述经典的建造者模式建造者模式的变种总结 建造者模式概述
建造者模式是一种广泛使用的设计模式在三方开源库和各种SDK中经常见到。建造者设计模式在四人帮的经典著作《设计模式可复用面向对象软件基础》中被提及它的定义为将一个复杂对象的构建与它的表示分离使得同样的构建过程可以创建不同的表示。建造者模式目前主要有两种一种是经典的建造者模式另外一种是变种的建造者模式。本文就是介绍建造者模式的两种形态的Java实现
经典的建造者模式 我们学过Java都知道当我们需要一个对象的时候直接new一个就行了我们new对象的时候需要给其传递一些属性最后就能得到一个可以使用的对象啦比如构建一个简单的车轮子对象我们只需要new 车轮子属性就行但是当我们要构造一个车的对象时就没那么简单了因为一辆车的这个大对象又包含了车轮子引擎车身等小对象这些对象需要我们单独new出了然后再组合到一起最终形成一辆车。这个过程如果还是使用我们程序员手动new就会很麻烦了所以出现了经典的建造者模式。 经典的建造者模式主要有四个参与者
复杂对象复杂对象就是被构造的的对象例如一辆车Car,实现抽象建造者接口的时候会引用这个对象然后定义其构造的过程抽象建造者接口 定义创建复杂对象的各个组成部件的操作例如CarBuilder,定义构建车的各个组成部件的操作抽象建造者接口的具体实现 可以定义多个这个实现是实际构建复杂对象的地方在这个类中会提供一个方法返回构建的复杂对象抽象建造者接口的构造者和使用者 在这里面调用对应的建造者接口方法构造组装得到复杂对象。
接下来我们使用一个造车的简单例子介绍经典的建造者模式 首先我们需要确定要构造的复杂对象这里的复杂对象就是我们要造的车我们定义一个类表示要造的车。
public class Car {private String wheel;private String body;private String engine;private String color;private String name;public Car() {}public String getWheel() {return wheel;}public void setWheel(String wheel) {this.wheel wheel;}public String getBody() {return body;}public void setBody(String body) {this.body body;}public String getEngine() {return engine;}public void setEngine(String engine) {this.engine engine;}public String getColor() {return color;}public void setColor(String color) {this.color color;}public String getName() {return name;}public void setName(String name) {this.name name;}Overridepublic String toString() {return Car{ wheel wheel \ , body body \ , engine engine \ , color color \ , name name \ };}
}接下来我们需要定义一个建造者接口定义造车的各个操作即定义抽象建造者接口。代码如下所示
public interface CarBuilder {// 构建轮子void buildWheel();// 构建车身void buildBody();// 构建引擎void buildEngine();// 构建车身颜色void buildColor();// 构建名字void buildName();// 返回造好的车Car getCar();
}
定义好造车的操作后我们就可以准备开始造车了我们接下来分别定义造一辆奔驰和一辆宝马这两种车的大致部件其实都差不多无非都是轮子车身引擎颜色名字等但是不同的就是各个部件中包含的技术所以我们需要定义不同的类表示当前造的车代码如下所示 首先是宝马类
public class BMWBuilder implements CarBuilder{private final Car mCar new Car();Overridepublic void buildWheel() {System.out.println(构建宝马的轮子);mCar.setWheel(宝马轮子);}Overridepublic void buildBody() {System.out.println(构建宝马的车身);mCar.setBody(宝马车身);}Overridepublic void buildEngine() {System.out.println(构建宝马的引擎);mCar.setEngine(宝马引擎);}Overridepublic void buildColor() {System.out.println(构建宝马的颜色);mCar.setColor(黑色);}Overridepublic void buildName() {System.out.println(构建宝马的名字);mCar.setName(宝马X5);}Overridepublic Car getCar() {return mCar;}
}奔驰车类
public class BenzBuilder implements CarBuilder{private final Car mCar new Car();Overridepublic void buildWheel() {System.out.println(构建奔驰的轮子);mCar.setWheel(奔驰轮子);}Overridepublic void buildBody() {System.out.println(构建奔驰的车身);mCar.setBody(奔驰车身);}Overridepublic void buildEngine() {System.out.println(构建奔驰的引擎);mCar.setEngine(奔驰引擎);}Overridepublic void buildColor() {System.out.println(构建奔驰的颜色);mCar.setColor(粉色);}Overridepublic void buildName() {System.out.println(构建奔驰的名字);mCar.setName(奔驰);}Overridepublic Car getCar() {return mCar;}
}
构造完上面的对象后我们需要提供一个类来将这些构造的操作步骤组合到一起最终形成我们要构建的复杂对象代码如下所示
public class Director {private CarBuilder carBuilder;public Director(CarBuilder carBuilder){this.carBuilder carBuilder;}public Car buildCar(){carBuilder.buildName();carBuilder.buildColor();carBuilder.buildWheel();carBuilder.buildBody();carBuilder.buildEngine();return carBuilder null ? null : carBuilder.getCar();}
}
有了Director类使用方只需要new一个Director对象传入想要构建的车的Builder调用buildCar方法就可以得到一个车的对象了。使用方法如下所示
public class Client {public static void main(String[] args) {BMWBuilder bmwBuilder new BMWBuilder();Director bmwDirector new Director(bmwBuilder);Car bmwCar bmwDirector.buildCar();System.out.println(构建了一辆宝马: bmwCar.toString());BenzBuilder benzBuilder new BenzBuilder();Director benzDirector new Director(benzBuilder);Car benzCar benzDirector.buildCar();System.out.println(构建了一辆奔驰: benzCar.toString());}
}运行结果
建造者模式的变种
建造者模式的变种是目前用得比较多的各大SDK初始化的时候基本都会使用建造者模式。经典的建造者模式重点在于抽象出对象创建的步骤并通过调用不同的具体实现从而得到不同的结果。而变种的建造者模式目的在于减少对象在创建过程中引入的多个重载构造函数可选参数以及Set方法的过度使用导致的不必要复杂性变种的建造者模式更加适用于参数多的对象并且这些参数中有部分参数是可选的有部分参数是必传的。下面我们就以构建一个人(Person)的例子介绍变种的建造者模式。
public class Person {private final String mName; // 姓名,必填private final String mGender; // 性别必填private final int mAge; // 年龄可选private final String mPhoneNo; // 电话可选private final String mWeight;// 体重可选public Person(String mName,String mGender,int mAge,String mPhoneNo,String mWeight) {this.mName mName;this.mGender mGender;this.mAge mAge;this.mPhoneNo mPhoneNo;this.mWeight mWeight;}public Person(String mName,String mGender,int mAge,String mPhoneNo) {this(mName, mGender, mAge, mPhoneNo, );}public Person(String mName,String mGender,int mAge) {this(mName, mGender, mAge, , );}
}在上面的类中我们的姓名和性别是必选项其他是可选项为了能够实现必选和可选的功能我们需要在类中定义多个重载构造函数来满足我们的需求或者是给提供set和get方法让必选项的参数通过构造函数传递但是参数很多的时候就会很复杂了传递参数的时候特别头痛。所以出现了变种的建造者模式。代码如下
public class PersonB {private final String mName; // 姓名private final String mGender; // 性别private final int mAge; // 年龄private final String mPhoneNo; // 电话private final String mWeight;// 体重private PersonB(PersonBuilder builder){mName builder.name;mGender builder.gender;mAge builder.age;mPhoneNo builder.phoneNo;mWeight builder.weight;}public String getName() {return mName;}public String getGender() {return mGender;}public int getAge() {return mAge;}public String getPhoneNo() {return mPhoneNo;}public String getWeight() {return mWeight;}Overridepublic String toString() {return PersonB{ mName mName \ , mGender mGender \ , mAge mAge , mPhoneNo mPhoneNo \ , mWeight mWeight \ };}public static class PersonBuilder {private final String name; // 姓名private final String gender; // 性别private int age; // 年龄private String phoneNo; // 电话private String weight;// 体重public PersonBuilder(String name,String gender){this.name name;this.gender gender;}public PersonBuilder age(int age){this.age age;return this;}public PersonBuilder phone(String phoneNo){this.phoneNo phoneNo;return this;}public PersonBuilder weight(String weight){this.weight weight;return this;}public PersonB build(){return new PersonB(this);}}
}观察上面的类我们可以发现首先我们需要构造的对象PersonB的构造函数是私有的意味着调用者无法直接通过实例化获取PersonB 的对象其次PersonB类里面的属性是final的并且在构造函数中设置对外只提供get方法即调用者只能用不能改。最后通过PersonBuilder的构造函数接收必选参数其他的属性可以通过PersonBuilder提供的方法设置其中每个方法都会返回当前的PersonBuilder对象这样可以让我们设置参数的时候使用链式调用如下所示 public PersonBuilder age(int age){this.age age;return this;}最后我们可以看下如何使用变种的建造者模式
public class Client {public static void main(String[] args) {// 构建一个PersonPersonB personB new PersonB.PersonBuilder(职场007,male).age(28).phone(1234567890).weight(83kg).build();System.out.println(构建者模式构建出的对象: personB);}
}运行结果
总结
以上就是建造者模式的内容本文分别介绍了两种形式的建造者模式以及Java的实现其中用得最多的就是变种的建造者模式建造者模式其实有个缺点就是需要编写很多的样板代码但是我认为尽管这样还是不影响建造者模式的优雅并且在Android Studio也有自动化生成变种建造者模式的插件但是我不建议使用除非读者已经对建造者模式很了解了。不然还是得仔细的看下建造者模式的设计思想这样在看优秀库的源码时才会感觉到事半功倍。