建造者模式
这是我给大家介绍的8个面试必问的设计模式的第四类:建造者模式.学完这8类必会的那么面试就不会有什么问题了,其余的无非都是多态的演变.好的开始讲解第四类:
我将通过两个案例给大家讲解,第一个案例起码70%以上的人看了都理解了,如果还不理解,请继续看第二个案例,看完后95%的人都会理解,还剩5%的人睡个觉起来就理解了.
大家不要只需要理解成:比工厂模式多了个”指挥者”角色.
通俗理解:
建造者模式,就是用户只和指挥者交谈拿产品,指挥者也只和建造者拿产品,制造过程由建造者具体去做好.
具体的方法参数:
1.产品”类”product
2.建造者接口Builder
建造的各种方法123,还有一个获取(返回)产品的方法
3.具体”建造者类ConcreateBuilder”继承接口.
各种具体的方法4.指挥者”类”Director
里面有一个获取产品的方法-传入接口实例,返回值”产品类”的,为了指向子类.调用所有的接口的方法,最后返回的是接口最后获取产品的方法即可.
1.详细概念
1.将一个复杂的构建(方法内容)与其表示(方法)相分离,使得同样的构建过程可以创建不同的表示。 [构建与表示分离,同构建不同表示]
2.与抽象工厂的区别:在建造者模式里,有个指导者,由指导者来管理建造者,用户是与指导者联系的,指导者联系建造者最后得到产品。即建造模式可以强制实行一种分步骤进行的建造过程。
3.建造模式是将复杂的内部创建封装在内部,对于外部调用的人来说,只需要传入建造者和建造工具,对于内部是如何建造成成品的,调用者无需关心。
4.举个简单的例子,如汽车,有很多部件,车轮,方向盘,发动机还有各种小零件等等,部件很多,但远不止这些,如何将这些部件装配成一部汽车,这个装配过程也很复杂(需要很好的组装技术), builder模式就是为了将部件和组装分开。
例子1,造人
/**
* 建造者模式必备内容(按模板来才是标准的):
*
* 1.产品"类"-Product
* 2.建造者Builer"接口"-Builder
1.多个制造产品部分的方法
2.返回一个完整的"产品"的方法
* 3.建造者的"具体实现"-"类"-ConcreteBuilder
* 1.完成具体的造部分的方法
* 2.把所有部分组合成"产品"的方法
* 4.指挥者"类"-Director,获取产品
* 1.传入一个建造者接口的实例对象(用户只要传入想要的,用户只和指挥者接触)
* 2.对象调用方法(符合多态)
* 3.返回产品即可
* 5.用户就是Test
* 1.直接通过指挥者,指定创建的类型即可获取产品
*/
/*--------------Product--------------*/
/**
* 人,产品"类"
*/
class Person{
private String head;
private String body;
private String foot;
public void setHead(String head) {
this.head = head;
}
public void setBody(String body) {
this.body = body;
}
public void setFoot(String foot) {
this.foot = foot;
}
@Override
public String toString() {
return head+"\n\r"+body+"\n\r"+foot;
}
public void detail() {
System.out.println(toString());
}
}
/*--------------Builder--------------*/
/**
* 建造者"接口"
* 1.多个制造产品部分的方法
* 2.返回一个完整的"产品"
*/
interface PersonBuilder {
//造人器官的方法
void buildHead();
void buildBody();
void buildfoot();
//造人,得到人方法
Person builPerson();
}
/*--------------ConcreatBuilder--------------*/
/**
* 建造者接口的具体实现"类"
* 比如建的是男人类,继承建造者接口
*/
class ManPersonBuilder implements PersonBuilder {
//创建一个产品,然后下面加工
Person person = new Person();
@Override
public void buildHead() {
person.setHead("建造头部");
}
@Override
public void buildBody() {
person.setBody("建造了身体");
}
@Override
public void buildfoot() {
person.setFoot("建造了脚");
}
//返回完整的一个产品类
@Override
public Person builPerson() {
return person;
}
}
/*--------------Director--------------*/
/**
* 指挥者类:
* 1.传入一个建造者接口的实例对象(用户只要传入想要的,用户只和指挥者接触),并返回类型是产品的方法,等下直接给用户
* 2.对象调用方法(符合多态)
* 3.返回产品即可
*/
class PersonDirector {
public Person constructPerson(PersonBuilder builder) {
builder.buildHead();
builder.buildBody();
builder.buildfoot();
return builder.builPerson();//返回产品
}
}
/**//测试代码:就是用户
* 1.直接通过指挥者,指定创建的类型即可获取产品
*/
public class Test {
public static void main(String[] args) {
PersonDirector director = new PersonDirector();
Person person = director.constructPerson(new ManPersonBuilder());
person.detail();
}
}
打印结果:
建造头部
建造了身体
建造了脚
如果大家觉得不过瘾,那么再通过一个例子帮你完全理解
例子2,造汽车
//1.产品"类"
class Car{
String name;
int wheel;
int seat;
String color;
boolean isOpenTop;//开天窗
public void setName(String name) {
this.name = name;
}
public void setWheel(int wheel) {
this.wheel = wheel;
}
public void setSeat(int seat) {
this.seat = seat;
}
public void setColor(String color) {
this.color = color;
}
public void setIsOpenTop(boolean isOpenTop) {
this.isOpenTop = isOpenTop;
}
@Override
public String toString() {
return "车名 : "+name + "\r\n"
+"轮胎数 : "+wheel+"\r\n"
+"座位数 : "+seat + "\r\n"
+"颜色 : "+color+"\r\n"
+"是否敞篷 : "+isOpenTop+"\r\n"
;
}
public void detail() {
System.out.println(toString());
}
}
//建造者"接口",统一用build,好理解
interface Builder {
void builName();//取名方法
void buildWheel();
void buildSeat();
void buildColor();
void buildTopOpen();
//获取一个产品-车的方法,关键*******
Car buildCart();
}
/**
* 具体建造者接口的实现"类"
*/
class ConcreatBuilder implements Builder {
//创建产品
Car car = new Car();
String name;
public ConcreatBuilder(String name) {
this.name = name;
if (!isOdiOrBance()) {
System.out.println("抱歉,不接受此车型订单");
}
}
public boolean isOdiOrBance() {
if (!name.equals("奥迪")&&!name.equals("奔驰")) {//不是这型号的不接受订单
return false;
}
return true;
}
@Override
public void builName() {
if(isOdiOrBance())
car.setName(name);
}
@Override
public void buildWheel() {
if(isOdiOrBance())
car.setWheel(4);
}
@Override
public void buildSeat() {
if(!isOdiOrBance())
return;
//奥迪8座,奔驰6座
if (name.equals("奥迪")) {
car.setSeat(8);
}
else if (name.equals("奔驰")) {
car.setSeat(6);
}
}
@Override
public void buildColor() {
if(!isOdiOrBance())
return;
//奥迪红色
if (name.equals("奥迪")) {
car.setColor("read");
} else if (name.equals("奔驰")) {
car.setColor("black");
}
}
@Override
public void buildTopOpen() {
if(!isOdiOrBance())
return;
//奥迪不敞篷
if (name.equals("奥迪")) {
car.setIsOpenTop(false);
}
else if (name.equals("奔驰")) {
car.setIsOpenTop(true);
}
}
@Override
public Car buildCart() {
return car;
}
}
//指挥者"类"
class Director {
//一个获取(返回)产品的方法,传入的是"接口"的具体实现类对象,符合多态,并调用接口的方法,返回值也是
public Car constructBuilder(Builder builder) {
builder.builName();
builder.buildColor();
builder.buildWheel();
builder.buildSeat();
builder.buildTopOpen();
return builder.buildCart(); //关键,和上述的同步
}
}
/**
* 用户,只和指挥者交谈
* 就是只拿商品
*/
public class User {
public static void main(String[] args) {
//用户通过指挥者获取产品
Director director = new Director();
Car car = director.constructBuilder(new ConcreatBuilder("奥迪"));
car.detail();
System.out.println("------------------------------------------");
Car car2 = director.constructBuilder(new ConcreatBuilder("奔驰"));
car2.detail();
Car car3 = director.constructBuilder(new ConcreatBuilder("奇瑞"));
car3.detail();
}
}
打印结果:
车名 : 奥迪
轮胎数 : 4
座位数 : 8
颜色 : read
是否敞篷 : false
------------------------------------------
车名 : 奔驰
轮胎数 : 4
座位数 : 6
颜色 : black
是否敞篷 : true
抱歉,不接受此车型订单
车名 : null
轮胎数 : 0
座位数 : 0
颜色 : null
是否敞篷 : false