创建型模式--建造者模式

  • 模式的定义和特点
  • 模式的结构于实现
  • 模式的应用实例
  • 应用场景
  • 模式的扩展


模式的定义和特点

建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。
优点:
(1)各个具体的建造者相互独立,有利于系统的扩展。
(2)客户端不必知道产品内部组成的细节,便于控制细节风险。
缺点:
(1)产品的组成部分必须相同,限制了其使用范围。
(2)如果产品的内部变化复杂,该模式会增加很多建造者类。
建造者模式注重零部件的组装零部件的组装过程,工厂方法模式更注重零部件的创建过程。

模式的结构于实现

模式的结构
(1)产品角色(Product):包含多个组成部件的复杂对象,由具体建造者来创建其各个组成部件。
(2)抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法getResult()。
(3)具体建造者(Concrete Builder):实现Builder接口,完成复杂产品的各个部件的具体创建方法。
(4)指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
模式的实现
(1)产品角色:包含多个组成部件的复杂对象。

class Product{
	private String partA;
	private String partB;
	private String partC;
	public void setPartA(String partA){
		this.partA = partA;
	}
	public void setPartB(String partB){
		this.partB = partB;
	}
	public void setPartC(String partC){
		this.partC = partC;
	}
	public void show(){
		//显示产品的特性
	}
}

(2)抽象建造者:包含创建产品各个子部件的抽象方法。

abstract class Builder{
	//创建产品对象
	protected Product product = new Product();
	public abstract void buildPartA();
	public abstract void buildPartB();
	public abstract void buildPartC();
	//返回产品对象
	public Product getResult(){
		return product;
	}
}

(3)具体建造者:实现了抽象建造者接口

public class ConcreteBuilder extends Builder{
	public void buildPartA(){
		product.setPartA("建造PartA");
	}
	public void buildPartB(){
		product.setPartB("建造PartB");
	}
	public void buildPartC(){
		product.setPartC("建造PartC");
	}
}

(4)指挥者:调用建造者中的方法完成复杂对象的创建

class Director{
	private Builder builder;
	public Director(Builder builder){
		this.builder = builder;
	}
	public Product construct(){
		builder.BuildPartA();
		builder.BuildPartB();
		builder.BuildPartC();
		return builder.getResult();
	}
}

(5)客户类

public class Client{
	public static void main(String[] args){
		Builder builder = new ConcreteBuilder();
		Director director = new Director(builder);
		Product product = dircetor.construct();
		product.show();
	}
}
模式的应用实例
package Builder;
import java.awt.*;
import javax.swing.*;

public class ParlourDecorator {
	public static void main(String[] args) {
		try {
			Decorator d = (Decorator) ReadXML.getObject();
			ProjectManager m = new ProjectManager(d);
			Parlour p = m.decorate();
			p.show();
		}catch(Exception e) {
			System.out.println(e.getMessage());
		}
	}
}
//产品:客厅
class Parlour{
	private String wall; //墙
	private String TV; //电视
	private String sofa; //沙发
	public void setWall(String wall) {
		this.wall = wall;
	}
	public void setTV(String tV) {
		TV = tV;
	}
	public void setSofa(String sofa) {
		this.sofa = sofa;
	}
	public void show() {
		JFrame jf = new JFrame("建造者模式测试");
		Container contentPane = jf.getContentPane();
		JPanel p = new JPanel();
		JScrollPane sp = new JScrollPane(p);
		String parlour = wall+TV+sofa;
		JLabel l = new JLabel(new ImageIcon("src/"+parlour+".jpg"));
		p.setLayout(new GridLayout(1,1));
		p.setBorder(BorderFactory.createTitledBorder("客厅"));
		p.add(l);
		contentPane.add(sp,BorderLayout.CENTER);
		jf.pack();
		jf.setVisible(true);
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}
//抽象建造者:装修工人
abstract class Decorator{
	//创建产品对象
	protected Parlour product = new Parlour();
	public abstract void buildWall();
	public abstract void buildTV();
	public abstract void buildsOFA();
	//返回产品对象
	public Parlour getResult() {
		return product;
	}
}
//具体建造者:具体装修工人1
class ConcreteDecorator1 extends Decorator{
	@Override
	public void buildWall() {
		product.setWall("w1");
	}
	@Override
	public void buildTV() {
		product.setTV("TV1");
	}
	@Override
	public void buildsOFA() {
		product.setSofa("sf1");
	}
}
//具体建造者:具体装修工人2
class ConcreteDecorator2 extends Decorator{
	@Override
	public void buildWall() {
		product.setWall("w2");
	}
	@Override
	public void buildTV() {
		product.setTV("TV2");
	}
	@Override
	public void buildsOFA() {
		product.setSofa("sf2");
	}
}
//指挥者:项目经理
class ProjectManager{
	private Decorator builder;
	public ProjectManager(Decorator builder) {
		this.builder = builder;
	}
	//产品构建与组装方法
	public Parlour decorate() {
		builder.buildWall();
		builder.buildTV();
		builder.buildsOFA();
		return builder.getResult();
	}
}
package Builder;
import javax.xml.parsers.*;
import org.w3c.*;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.*;

public class ReadXML {
	public static Object getObject() {
		try {
			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = dFactory.newDocumentBuilder();
			Document doc;
			doc = builder.parse(new File("src/Builder/config.xml"));
			NodeList nl = doc.getElementsByTagName("className");
			Node calssNode = nl.item(0).getFirstChild();
			String cName = "Builder." + calssNode.getNodeValue();
			System.out.println("新类名:" + cName);
			Class<?> c = Class.forName(cName);
			Object obj = c.newInstance();
			return obj;
		}catch(Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
应用场景

(1)创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构建的建造顺序是稳定的。
(2)创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。

模式的扩展

建造者模式在应用过程中可以根据需要改变,如果创建的产品种类只有一种,只要一个具体建造者,这时可以省略掉抽象建造者,甚至可以省略掉指挥者角色。
本篇为读书笔记,概念和代码均出自书籍《软件设计模式(Java版)》作者:程细柱,人民邮电出版社。请自觉支持正版!