开始写设计模式系列,希望自己可以坚持下来.
第二篇:建造者模式
建造者模式是一步一步创建一个复杂对象,允许用户不了解细节的情况下精细的控制对象的构造过程。使得复杂对象的构建与他的表示相分离,同样的构造过程可以创建不同的表示。
在生活中我们经常买票,各种各样的票,我们这里要创建一个可以售卖多种票的程序。
首先是产品Product,他是一个抽象类,他有各种票都有的特征,以及票在购买当中会经历的状态,check,检测这张票的信息是否可靠(如生成时间,设备,渠道等),pay,对这张票进行支付,query,查询这张票的支付状态(如,金额是否一致等)
package top.huyuxin.builder;
public abstract class Ticket {
protected String ticketname;
protected boolean isCheck=false;
protected boolean isPayed=false;
protected boolean isQuery=false;
public Ticket() {
super();
}
public abstract void setTicketname();
public void setCheck(boolean isCheck) {
this.isCheck = isCheck;
}
public void setPayed(boolean isPayed) {
this.isPayed = isPayed;
}
public boolean isQuery() {
return isQuery;
}
public void setQuery(boolean isQuery) {
this.isQuery = isQuery;
}
@Override
public String toString() {
return "Ticket [ticketname=" + ticketname + ", isCheck=" + isCheck + ", isPayed=" + isPayed + ", isQuery="
+ isQuery + "]";
}
}
现在这个程序出售两种票,一种火车票,一种汽车票
package top.huyuxin.builder;
/**
*火车票
**/
public class TrainTicket extends Ticket {
public TrainTicket() {
super();
}
@Override
public void setTicketname() {
ticketname=TrainTicket.class.getSimpleName();
}
}
package top.huyuxin.builder;
/**
*汽车票
**/
public class BusTicket extends Ticket {
public BusTicket() {
super();
}
@Override
public void setTicketname() {
ticketname=BusTicket.class.getSimpleName();
}
}
处理两种票的逻辑应该是一致的。
package top.huyuxin.builder;
public abstract class TicketSeller {
public abstract void createTicket(); //创建票
public abstract void checkTicket(); //检查票的生成信息
public abstract void payTicket(); //支付
public abstract void queryTicket(); //查询
public abstract void drawTicket(); //出票
}
但是细节肯定是不一致的,所以我们创建两个不同的Builder
package top.huyuxin.builder;
public class TrainTicketSeller extends TicketSeller {
private TrainTicket ticket;
@Override
public void createTicket() {
ticket=new TrainTicket();
ticket.setTicketname();
}
@Override
public void checkTicket() {
ticket.isCheck=true;
}
@Override
public void payTicket() {
ticket.isPayed=true;
}
@Override
public void queryTicket() {
ticket.isQuery=true;
}
@Override
public void drawTicket() {
System.out.println(ticket.toString());
}
}
package top.huyuxin.builder;
public class BusTicketSeller extends TicketSeller {
private BusTicket busticket;
@Override
public void createTicket() {
busticket=new BusTicket();
busticket.setTicketname();
}
@Override
public void checkTicket() {
busticket.isCheck=true;
}
@Override
public void payTicket() {
busticket.isPayed=true;
}
@Override
public void queryTicket() {
busticket.isQuery=true;
}
@Override
public void drawTicket() {
System.out.println(busticket.toString());
}
}
当在完成票的生成到出票的过程,顺序应该是一定的,不能还没生成票就去支付,还没支付就去查询。所以需要一个指挥者(Director)来控制他们的进程
package top.huyuxin.builder;
public class TicketProgram {
public static void sellTicket(TicketSeller ticketSeller){
ticketSeller.createTicket();
ticketSeller.checkTicket();
ticketSeller.payTicket();
ticketSeller.queryTicket();
ticketSeller.drawTicket();
}
}
这样我们就可以安心售票了
package top.huyuxin.builder;
public class Main {
public static void main(String[] args) {
TrainTicketSeller ticketSeller =new TrainTicketSeller();
BusTicketSeller busTicketSeller=new BusTicketSeller();
TicketProgram.sellTicket(ticketSeller);
TicketProgram.sellTicket(busTicketSeller);
TicketProgram.sellTicket(ticketSeller);
}
}
结果:
Ticket [ticketname=TrainTicket, isCheck=true, isPayed=true, isQuery=true]
Ticket [ticketname=TrainTicket, isCheck=true, isPayed=true, isQuery=true]
Ticket [ticketname=BusTicket, isCheck=true, isPayed=true, isQuery=true]
当我们的程序需要买别的票的时候,只需要再次继承抽象类Ticket,并创建处理对应票的Builder就可以了,在TicketProgram 里我们通过依赖注入的方式,使得即使有新的票出售只要逻辑一致,也能正常控制票的出售。
在经典的建造者模式当中Director的控制流程应该是可变的,创建多个不同的sellTicket()方法,通过调动builder的执行顺序产生不同的结果。这就是建造者模式。
填充模式,你可能没听过,因为这是我自己起的名字。很多时候对象的构建伴随着很多很多参数的初始化,并且这些参数又不得不先初始化好,大量的setter和getter需要一个管理者来管理一波。比如刚刚的买票,买票可以但是现在的票都是实名制的,在购票前应先获取购票人信息。
于是就有了下面的代码:
package top.huyuxin.builder;
public abstract class Ticket {
protected String ticketname;
protected boolean isCheck=false;
protected boolean isPayed=false;
protected boolean isQuery=false;
protected String holdername;
protected String sex;
protected int age;
protected String birthday;
protected String address;
public Ticket() {
super();
}
public abstract void setTicketname();
public void setCheck(boolean isCheck) {
this.isCheck = isCheck;
}
public void setPayed(boolean isPayed) {
this.isPayed = isPayed;
}
public boolean isQuery() {
return isQuery;
}
public void setQuery(boolean isQuery) {
this.isQuery = isQuery;
}
public String getTicketname() {
return ticketname;
}
public void setTicketname(String ticketname) {
this.ticketname = ticketname;
}
public String getHoldername() {
return holdername;
}
public void setHoldername(String holdername) {
this.holdername = holdername;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public boolean isCheck() {
return isCheck;
}
public boolean isPayed() {
return isPayed;
}
@Override
public String toString() {
return "Ticket [ticketname=" + ticketname + ", isCheck=" + isCheck + ", isPayed=" + isPayed + ", isQuery="
+ isQuery + "]";
}
}
这使得原来逻辑清晰的Ticket类变得杂乱不堪,由于setter和getter过多可能在初始化的时候你可能漏了用户的sex或则age没有填上。
(翻不完的setter和getter)
于是我们创建一个对象信息的建造者,用来构建对象,在setter的时候我们return this这样使得可以链式调用,
package top.huyuxin.builder;
public class PersonInfo {
private String holdername;
private String sex;
private int age;
private String birthday;
private String address;
public static class Builder{
private String holdername;
private String sex;
private int age;
private String birthday;
private String address;
public Builder setHoldername(String holdername) {
this.holdername = holdername;
return this;
}
public Builder setSex(String sex) {
this.sex = sex;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setBirthday(String birthday) {
this.birthday = birthday;
return this;
}
public Builder setAddress(String address) {
this.address = address;
return this;
}
public PersonInfo create(){
PersonInfo personInfo=new PersonInfo();
personInfo.holdername=this.holdername;
personInfo.sex=this.sex;
personInfo.age=this.age;
personInfo.birthday=this.birthday;
personInfo.address=this.address;
return personInfo;
}
}
@Override
public String toString() {
return "PersonInfo [holdername=" + holdername + ", sex=" + sex + ", age=" + age + ", birthday=" + birthday
+ ", address=" + address + "]";
}
}
在Ticket类初始化的时候便写入的购票人信息
package top.huyuxin.builder;
public abstract class Ticket {
protected String ticketname;
protected boolean isCheck=false;
protected boolean isPayed=false;
protected boolean isQuery=false;
protected PersonInfo personInfo;
public Ticket(PersonInfo personInfo) {
super();
this.personInfo=personInfo;
}
public abstract void setTicketname();
public void setCheck(boolean isCheck) {
this.isCheck = isCheck;
}
public void setPayed(boolean isPayed) {
this.isPayed = isPayed;
}
public boolean isQuery() {
return isQuery;
}
public void setQuery(boolean isQuery) {
this.isQuery = isQuery;
}
@Override
public String toString() {
return "Ticket [ticketname=" + ticketname + ", personInfo=" + personInfo.toString() +", isCheck=" + isCheck + ", isPayed=" + isPayed + ", isQuery="
+ isQuery + "]";
}
}
在调用的时候也十分的清晰
PersonInfo xiaoshuangInfo=new PersonInfo.Builder()
.setHoldername("小双")
.setSex("women")
.setAge(18)
.setBirthday("2000-01-01")
.setAddress("旮旯")
.create();
TicketProgram.sellTicket(ticketSeller,xiaoshuangInfo);
TicketProgram.sellTicket(busTicketSeller,xiaoshuangInfo);
结果:
Ticket [ticketname=BusTicket, personInfo=PersonInfo [holdername=小双, sex=women, age=18, birthday=2000-01-01, address=旮旯], isCheck=true, isPayed=true, isQuery=true]
Ticket [ticketname=TrainTicket, personInfo=PersonInfo [holdername=小双, sex=women, age=18, birthday=2000-01-01, address=旮旯], isCheck=true, isPayed=true, isQuery=true]
通过使用这个填充参数的填充模式使得Ticket对象的构建与表示分离。在填充模式中没有指挥官(Director)但是用于对象的构建还是搓搓有余。