建造者模式

概述

Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种。Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
何时使用:一些基本部件不会变,而其组合经常变化的时候。
如何解决:将变与不变分离开。
关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。
应用实例: 1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

举个例子理解

我们要生产一个Hamburger,假设需要黄油、芥末、番茄酱、沙拉酱、洋葱、黄瓜这些原材料。下面模拟这个生产过程

//Hamburger类

package com.xnn;

/**
 * 类(接口)描述:
 * @author xnn
 * 2018年11月1日下午6:19:51
 */
public class Hamburger {
	//黄油
    private String grease;
    //芥末
    private String mustard;
    //番茄酱
    private String redeye;
    //沙拉酱
    private String mayonnaise;
    //洋葱
    private String onion;
    //黄瓜
    private String  cucumber;
	/**
	 * @return the grease
	 */
	public String getGrease() {
		return grease;
	}
	/**
	 * @param grease the grease to set
	 */
	public void setGrease(String grease) {
		this.grease = grease;
	}
	/**
	 * @return the mustard
	 */
	public String getMustard() {
		return mustard;
	}
	/**
	 * @param mustard the mustard to set
	 */
	public void setMustard(String mustard) {
		this.mustard = mustard;
	}
	/**
	 * @return the redeye
	 */
	public String getRedeye() {
		return redeye;
	}
	/**
	 * @param redeye the redeye to set
	 */
	public void setRedeye(String redeye) {
		this.redeye = redeye;
	}
	/**
	 * @return the mayonnaise
	 */
	public String getMayonnaise() {
		return mayonnaise;
	}
	/**
	 * @param mayonnaise the mayonnaise to set
	 */
	public void setMayonnaise(String mayonnaise) {
		this.mayonnaise = mayonnaise;
	}
	/**
	 * @return the onion
	 */
	public String getOnion() {
		return onion;
	}
	/**
	 * @param onion the onion to set
	 */
	public void setOnion(String onion) {
		this.onion = onion;
	}
	/**
	 * @return the cucumber
	 */
	public String getCucumber() {
		return cucumber;
	}
	/**
	 * @param cucumber the cucumber to set
	 */
	public void setCucumber(String cucumber) {
		this.cucumber = cucumber;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Hamburger [grease=" + grease + ", mustard=" + mustard
				+ ", redeye=" + redeye + ", mayonnaise=" + mayonnaise
				+ ", onion=" + onion + ", cucumber=" + cucumber + "]";
	}
    
}


//客户端

package com.xnn;


/**
 * 类(接口)描述:
 * @author xnn
 * 2018年11月1日下午6:15:52
 */
public class MainClass {
public static void main(String[] args) {
	Hamburger hamburger = new Hamburger();
	hamburger.setCucumber("一根黄瓜");
	hamburger.setGrease("一两黄油");
	/**
	 * .............................这样造对象甚是麻烦,如果属性再多一点,代码量更大,就算提供全参构造器,那也会造成参数很长
	 */
	//这样写,客户端代码省去了很多
	/*BuilderHamburgerImpl builderHamburgerImpl = new BuilderHamburgerImpl();
	BuilderHamburgerImpl1 builderHamburgerImpl1 = new BuilderHamburgerImpl1();
	Directer directer = new Directer();
	Hamburger createHamburger = directer.CreateHamburger(builderHamburgerImpl);
	System.out.println(createHamburger);
	Hamburger createHamburger2 = directer.CreateHamburger(builderHamburgerImpl1);
	System.out.println(createHamburger2);*/
	
}
}

下面用建造者模式去写

Hanburger类
package com.xnn;

/**
 * 类(接口)描述:
 * @author xnn
 * 2018年11月1日下午6:19:51
 */
public class Hamburger {
	//黄油
    private String grease;
    //芥末
    private String mustard;
    //番茄酱
    private String redeye;
    //沙拉酱
    private String mayonnaise;
    //洋葱
    private String onion;
    //黄瓜
    private String  cucumber;
	/**
	 * @return the grease
	 */
	public String getGrease() {
		return grease;
	}
	/**
	 * @param grease the grease to set
	 */
	public void setGrease(String grease) {
		this.grease = grease;
	}
	/**
	 * @return the mustard
	 */
	public String getMustard() {
		return mustard;
	}
	/**
	 * @param mustard the mustard to set
	 */
	public void setMustard(String mustard) {
		this.mustard = mustard;
	}
	/**
	 * @return the redeye
	 */
	public String getRedeye() {
		return redeye;
	}
	/**
	 * @param redeye the redeye to set
	 */
	public void setRedeye(String redeye) {
		this.redeye = redeye;
	}
	/**
	 * @return the mayonnaise
	 */
	public String getMayonnaise() {
		return mayonnaise;
	}
	/**
	 * @param mayonnaise the mayonnaise to set
	 */
	public void setMayonnaise(String mayonnaise) {
		this.mayonnaise = mayonnaise;
	}
	/**
	 * @return the onion
	 */
	public String getOnion() {
		return onion;
	}
	/**
	 * @param onion the onion to set
	 */
	public void setOnion(String onion) {
		this.onion = onion;
	}
	/**
	 * @return the cucumber
	 */
	public String getCucumber() {
		return cucumber;
	}
	/**
	 * @param cucumber the cucumber to set
	 */
	public void setCucumber(String cucumber) {
		this.cucumber = cucumber;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Hamburger [grease=" + grease + ", mustard=" + mustard
				+ ", redeye=" + redeye + ", mayonnaise=" + mayonnaise
				+ ", onion=" + onion + ", cucumber=" + cucumber + "]";
	}
    
}


package com.xnn;

/**
 * 类(接口)描述:创建Hamburger的接口,里面声明了创建Hamburger所需要的各种原料的方法,以及创建一个完整Hamburger的方法
 * @author xnn
 * 2018年11月1日下午6:49:13
 */
public interface IBuilderHamburger {
	
	//创建黄油
    public void builderGrease();
    //创建芥末
    public void builderMustard();
    //创建番茄酱
    public void builderRedeye();
    //创建沙拉酱
    public void mayonnaise();
    //创建洋葱
    public void builderOnion();
    //创建黄瓜
    public void builderCucumber();
    //创建汉堡包
    public Hamburger createHamburger();
    
}



package com.xnn;

/**
 * 类(接口)描述:IBuilderHamburger接口的具体实现类,负责创建具体的Hamburger
 * @author xnn
 * 2018年11月1日下午6:57:13
 */
public class BuilderHamburgerImpl implements IBuilderHamburger{
	
      private Hamburger hamburger;
     //在构造方法中创建出一个hamburger对象
	public BuilderHamburgerImpl() {
		super();
		hamburger = new Hamburger();
	}


	public void builderGrease() {
		hamburger.setGrease("一两黄油的");
	}

	
	public void builderMustard() {
		hamburger.setMustard("一两芥末的");
	}

	
	public void builderRedeye() {
		hamburger.setRedeye("一两番茄酱的");
	}

	public void mayonnaise() {
		hamburger.setMayonnaise("一两沙拉酱的");
	}

	
	public void builderOnion() {
		hamburger.setOnion("一个洋葱的");	
		}

	public void builderCucumber() {
		hamburger.setCucumber("一根黄瓜的");
	}

	
	public Hamburger createHamburger() {
		System.out.println("创造出来了一个原料全是一两的hamburger");
		return hamburger;
	}
 
}



package com.xnn;

/**
 * 类(接口)描述:IBuilderHamburger接口的另一个具体实现类,负责创建具体的Hamburger
 * @author xnn
 * 2018年11月1日下午8:07:26
 */
public class BuilderHamburgerImpl1 implements IBuilderHamburger {
    private Hamburger hamburger;
   //在构造方法中创建出一个hamburger对象
	public BuilderHamburgerImpl1() {
		super();
		hamburger = new Hamburger();
	}


	public void builderGrease() {
		hamburger.setGrease("二两黄油的");
	}

	
	public void builderMustard() {
		hamburger.setMustard("二两芥末的");
	}

	
	public void builderRedeye() {
		hamburger.setRedeye("二两番茄酱的");
	}

	public void mayonnaise() {
		hamburger.setMayonnaise("二两沙拉酱的");
	}

	
	public void builderOnion() {
		hamburger.setOnion("二个洋葱的");	
		}

	public void builderCucumber() {
		hamburger.setCucumber("二根黄瓜的");
	}

	
	public Hamburger createHamburger() {
		System.out.println("创造出来了一个原料全是二两的hamburger");
		return hamburger;
	}
}



package com.xnn;


/**
 * 类(接口)描述:客户端类
 * @author xnn
 * 2018年11月1日下午6:15:52
 */
public class MainClass {
public static void main(String[] args) {
	/*Hamburger hamburger = new Hamburger();
	hamburger.setCucumber("一根黄瓜");
	hamburger.setGrease("一两黄油");*/
	/**
	 * .............................这样造对象甚是麻烦,如果属性再多一点,代码量更大
	 */
	//这样写,客户端代码省去了很多,隐藏了很多创建对象的细节。
	BuilderHamburgerImpl builderHamburgerImpl = new BuilderHamburgerImpl();
	BuilderHamburgerImpl1 builderHamburgerImpl1 = new BuilderHamburgerImpl1();
	Directer directer = new Directer();
	Hamburger createHamburger = directer.CreateHamburger(builderHamburgerImpl);
	System.out.println(createHamburger);
	Hamburger createHamburger2 = directer.CreateHamburger(builderHamburgerImpl1);
	System.out.println(createHamburger2);
	
}
}

对应的类图:

运行结果:

创造出来了一个原料全是一两的hamburger
Hamburger [grease=一两黄油的, mustard=一两芥末的, redeye=一两番茄酱的, mayonnaise=null, onion=一个洋葱的, cucumber=一根黄瓜的]
创造出来了一个原料全是二两的hamburger
Hamburger [grease=二两黄油的, mustard=二两芥末的, redeye=二两番茄酱的, mayonnaise=null, onion=二个洋葱的, cucumber=二根黄瓜的]
原文地址:https://www.cnblogs.com/nnxud/p/9892941.html