创建者模式定义
创建者模式就是将一个对象的创建和表示分离,使得同样的构建过程可以有不同的表示,而且客户端不需要知道对象的构建细节
在书中第二条提到:遇到多个构造器参数时考虑使用构建器,其实这里的构建器说的就是创建者模式
创建者模式组成角色
1.Builder:为创建一个产品对象的各个部件指定抽象接口
public interface HTMLBuilder{
void buildHead();
void buildBody();
}
2.ConcreteBuilder:实现Builder接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口
public class MainBuilder implements HTMLBuilder {
private HTML html;
public MainBuilder (){
html = new HTML();
}
public HTML getPerson (){
return html;
}
void buildHead(){
html.setHead("..." );
}
void buildBody(){
html.setBody("..." );
}
}
public class MyBuilder implements HTMLBuilder {
private MyHTML html;
public MainBuilder (){
html = new MyHTML();
}
public MyHTML getPerson (){
return html;
}
void buildHead(){
html.setHead("..." );
}
void buildBody(){
html.setBody("..." );
}
}
3.Director:构建一个使用Builder接口的对象,指导构建过程
public class HTMLDirector{
public HTML constructHTML (HTMLBuilder builder){
builder.buildHead();
builder.buildBody();
return builder.html;
}
}
4.Product:表示被构造的复杂对象
public class HTML {
private String head;
private String body;
public void setHead (String head){
this .head = head;
}
public void setBody (String body){
this .body = body;
}
public String getHead (){
return this .head;
}
public String getBody (){
return this .body;
}
}
public class MyHTML extends HTML {
...
}
客户端进行测试
public class Client{
public static void main (String[] args){
HTMLDirector hd = new HTMLDirector();
MyHTML mh = hd.constructHTML(new MyBuilder());
HTML html = hd.constructHTML(new MainBuilder());
}
}
从上面的客户端测试代码中我们可以看到,客户端只需要获得对象并使用,而对象的创建细节客户端不需要知道,而在实现中,将对象的构建和行为表示分离,分别置于Director和Product对应的Builder实现类
创建者模式实现:在薪酬模块中的实际应用
在薪酬模块中,需要对员工的基本工资、奖金、保险、个人所得税依次进行计算,而且需要区分不同的工种,比如劳动工、合同工等,这里如果使用抽象工厂的话,就需要为基本工资、奖金等的计算分别创建一个接口工厂类和两个工种对应的实现类(这里假设只有劳动工和合同工),可想而知其创建的类数量之多,而且如果新增一种薪酬计算,就又需要相应的创建一个接口工厂类和两个工种对应的实现类。
而如果实现创建者模式,我们可以将基本工资、奖金等的计算置于一个抽象工厂中,如下:
public abstract class Factory {
protected abstract BasePay getBasePay ();
protected abstract Assurance getAssurace ();
protected abstract Bonus getBonus ();
protected abstract Tax getTax ();
}
public class ldFactory extends Factory {
...
}
public class htFactory extends Factory {
...
}
接下来,定义Director创建者类,并将对应的行为表示(计算薪酬)定义在该类中
public class Director{
private Factory factory;
public void setFactory (Factory factory){
this .factory = factory;
}
public Factory getFactory (){
return this .factory;
}
public StringBuffer doSalary (Person person){
BasePay basepay = factory.getBasePay();
Assurance assurance = factory.getAssurance();
Bonus bonus = factory.getBonus();
Tax tax = factory.getTax();
StringBuffer sb = new StringBuffer("" );
sb.append("基本工资:" +basepay.doPay(person)+"\n" );
sb.append("奖金:" +bonus.doPay(person)+"\n" );
return sb;
}
}
定义一个产品总类Person,使不同的工种继承它:
public class Person {
private String name;
private String money;
}
public class htPerson extends Person {
public htPerson (){
super ();
this .name = "合同工" ;
this .monry = 0 ;
System.out.println("合同工" );
}
}
public class ldPerson extends Person {
public ldPerson (){
super ();
this .name = "劳动工" ;
this .money = 0 ;
System.out.println("劳动工" );
}
}
定义一个计算抽象类,所有的计算方式都实现该接口:
public interface Builder {
double doPay(Person person);
}
public class BasePay implements Builder {
double doPay(Person person){
}
}
public class Bonus implements Builder {
double doPay(Person person){
}
}
接下来看看客户端测试类:
public class Client{
public static void main (String[] args){
Director dir = new Director();
dir.setFactory(new ldFactory());
String res = dir.doSalary().toString();
System.out .println("劳动工的薪酬为: " +res);
}
}
创建者模式和抽象工厂模式对比
抽象工厂模式侧重于一系列对象的创建,而创建者模式则侧重于一系列对象的组装
在抽象工厂中,工厂类除了常见一系列对象,还进行一系列行为表示的实现,这样不符合工厂类的单一职责原则;而在创建者模式中,工厂类只负责对象的创建,行为则使用director组装类进行组装,它将功能职责进一步划分,相对于抽象工厂模式而言,更进一步的实现了单一职责原则