建造者模式:
建造者模式将一个复杂对象的构建与它的表示分离,可以使一个建造过程生成具有不同内部表示的产品对象。用户不需要知道具体建造的过程和细节,只需要指定建造的类型就可以得到它们。
什么情况适用建造者模式:产品都必须由基本的几个零件组成缺一不可,但其他零件不固定时。产品的组装有一定顺序,不可写错顺序时。
本质:分离整体构建算法和部件构造算法。
1.问题引入:(建造小人)
1)建造一个瘦小人

package computer;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Test {
	public static void main(String[] args) {
		DrawPerson person = new DrawPerson();
		person.launchFrame();
	}
}

class DrawPerson extends Frame {
	// 继承的函数,且自动被调用
	public void paint(Graphics g) {
		Color c = g.getColor();
		g.setColor(Color.BLACK);

		g.fillOval(50, 50, 30, 30);
		g.fillRect(60, 80, 10, 50);
		g.drawLine(60, 80, 40, 130);
		g.drawLine(70, 80, 90, 130);
		g.drawLine(60, 130, 45, 180);
		g.drawLine(70, 130, 85, 180);

		g.setColor(c);
	}

	public void launchFrame() {
		this.setLocation(400, 300);
		this.setSize(800, 600);
		// 关闭窗口后,结束窗口所在的应用程序
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		this.setBackground(Color.WHITE);
		setVisible(true);
	}
}

2)建造一个胖小人

package computer;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Test {
	public static void main(String[] args) {
		DrawPerson person = new DrawPerson();
		person.launchFrame();
	}
}

class DrawPerson extends Frame {
	// 修改paint()为画胖小人
	public void paint(Graphics g) {
		Color c = g.getColor();
		g.setColor(Color.BLACK);

		g.fillOval(50, 50, 30, 30);
		g.fillOval(45, 80, 40, 50);
		g.drawLine(60, 80, 40, 130);
		g.drawLine(70, 80, 90, 130);
		g.drawLine(60, 130, 45, 180);
		g.drawLine(70, 130, 85, 180);

		g.setColor(c);
	}

	public void launchFrame() {
		this.setLocation(400, 300);
		this.setSize(800, 600);
		// 关闭窗口后,结束窗口所在的应用程序
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		this.setBackground(Color.WHITE);
		setVisible(true);
	}
}

2.改进:分别建胖人类瘦人类
把建造胖人和瘦人的语句独立出来两个类:

package computer;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Test {
	public static void main(String[] args) {
		DrawPerson person = new DrawPerson();
		person.launchFrame();
	}
}

class PersonThinBuilder{
	private Graphics g;
	public PersonThinBuilder(Graphics g) {
		this.g=g;
	}
	
	public void build() {
		Color c = g.getColor();
		g.setColor(Color.BLACK);

		g.fillOval(50, 50, 30, 30);
		g.fillRect(60, 80, 10, 50);
		g.drawLine(60, 80, 40, 130);
		g.drawLine(70, 80, 90, 130);
		g.drawLine(60, 130, 45, 180);
		g.drawLine(70, 130, 85, 180);

		g.setColor(c);
	}
}

class PersonFatBuilder{
	private Graphics g;
	public PersonFatBuilder(Graphics g) {
		this.g=g;
	}
	
	public void build() {
		Color c = g.getColor();
		g.setColor(Color.BLACK);

		g.fillOval(50, 50, 30, 30);
		g.fillOval(45, 80, 40, 50);
		g.drawLine(60, 80, 40, 130);
		g.drawLine(70, 80, 90, 130);
		g.drawLine(60, 130, 45, 180);
		g.drawLine(70, 130, 85, 180);

		g.setColor(c);
	}
}

class DrawPerson extends Frame{
	//自动调用:
	public void paint(Graphics g) {
		//建造瘦小人只需修改此句:
		PersonFatBuilder p=new PersonFatBuilder(g);
		p.build();
	}
	
	public void launchFrame() {
		this.setLocation(400,300);
		this.setSize(800,600);
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		this.setBackground(Color.WHITE);
		this.setVisible(true);
	}
}

达到了可以复用画小人的程序的目的。
缺点:若要增加一个高小人,也可能会不小心缺胳膊少腿。

3.改进:(建造者模式)

增加一个小人抽象类,胳膊、腿等分别是一个个的方法,让具体小人类继承该抽象类,这样小人就必须胳膊腿等全部写完后才能编译通过,避免了缺胳膊少腿问题。

用java编程画人 用java绘制小人_用java编程画人

package computer;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class Test {
	public static void main(String[] args) {
		DrawPerson person = new DrawPerson();
		person.launchFrame();
	}
}

//小人的抽象建造类
abstract class PersonBuilder{
	protected Graphics g;
	public PersonBuilder(Graphics g) {
		this.g=g;
	}
	
	public abstract void buildHead();
	public abstract void buildBody();
	public abstract void buildArmLeft();
	public abstract void buildArmRight();
	public abstract void buildLegLeft();
	public abstract void buildLegRight();
}

class PersonThinBuilder extends PersonBuilder{
	public PersonThinBuilder(Graphics g) {
		//注意:调用父类构造:
		super(g);
	}
	public void buildHead() {
		g.fillOval(50, 50, 30, 30);
	}
	public void buildBody() {
		g.fillRect(60, 80, 10, 50);
	}
	public void buildArmLeft() {
		g.drawLine(60, 80, 40, 130);
	}
	public void buildArmRight() {
		g.drawLine(70, 80, 90, 130);
	}
	public void buildLegLeft() {
		g.drawLine(60, 130, 45, 180);
	}
	public void buildLegRight() {
		g.drawLine(70, 130, 85, 180);
	}
}

class PersonFatBuilder extends PersonBuilder{
	public PersonFatBuilder(Graphics g) {
		//注意:调用父类构造:
		super(g);
	}
	public void buildHead() {
		g.fillOval(50, 50, 30, 30);
	}
	public void buildBody() {
		g.fillOval(45, 80, 40, 50);
	}
	public void buildArmLeft() {
		g.drawLine(60, 80, 40, 130);
	}
	public void buildArmRight() {
		g.drawLine(70, 80, 90, 130);
	}
	public void buildLegLeft() {
		g.drawLine(60, 130, 45, 180);
	}
	public void buildLegRight() {
		g.drawLine(70, 130, 85, 180);
	}
}

//指导者类
class PersonDirector{
	private PersonBuilder pb;
	public PersonDirector(PersonBuilder pb) {
		this.pb=pb;
	}
	
	public void createPerson() {
		pb.buildHead();
		pb.buildBody();
		pb.buildArmLeft();
		pb.buildArmRight();
		pb.buildLegLeft();
		pb.buildLegRight();
	}
}

class DrawPerson extends Frame{
	//自动调用:
	public void paint(Graphics g) {
		Color c=g.getColor();
		g.setColor(Color.BLACK);
		
		//要修改为画胖人只需修改这一句:
		PersonThinBuilder p=new PersonThinBuilder(g);
		PersonDirector pd=new PersonDirector(p);
		pd.createPerson();
		
		g.setColor(c);
	}
	
	public void launchFrame() {
		this.setLocation(400,300);
		this.setSize(800,600);
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		this.setBackground(Color.WHITE);
		this.setVisible(true);
	}
}

4.建造者模式的基本代码:

用java编程画人 用java绘制小人_java_02

package computer;

import java.util.ArrayList;
import java.util.List;

public class Test {
	public static void main(String[] args) {
		//指挥者
		Director director=new Director();
		
		//具体建造者
		Builder b1=new ConcreteBuilder1();
		Builder b2=new ConcreteBuilder2();
		
		//指挥者用具体建造者b1构建产品
		director.Construct(b1);
		//获取刚构建的产品1
		Product p1=b1.GetResult();
		//列举刚构建的产品部件部件
		p1.Show();
		
		//指挥者用具体建造者b2构建产品
		director.Construct(b2);
		//获取刚构建的产品2
		Product p2=b2.GetResult();
		//列举刚构建的产品部件部件
		p2.Show();
	}
}

//产品类
class Product{
	List<String> parts=new ArrayList<String>();
	//添加产品部件
	public void Add(String part) {
		parts.add(part);
	}
	//列举产品部件
	public void Show() {
		System.out.println("产品 创建 ----");
		for(String part:parts) {
			System.out.println(part);
		}
	}
}

//抽象建造者类(产品由两个部件A、B组成)
abstract class Builder{
	public abstract void BuildPartA();
	public abstract void BuildPartB();
	//得到产品创建后结果的方法:(注意:返回值类型为产品类)
	public abstract Product GetResult();
}

//具体的建造者类(有多个)
class ConcreteBuilder1 extends Builder {
	//注意:产品类的对象
	private Product product=new Product();
	
	public void BuildPartA() {
		product.Add("部件A");
	}
	public void BuildPartB() {
		product.Add("部件B");
	}
	public Product GetResult() {
		return product;
	}
}

//具体的建造者类(有多个)
class ConcreteBuilder2 extends Builder {
	//注意:产品类的对象
	private Product product=new Product();
	
	public void BuildPartA() {
		product.Add("部件AA");
	}
	public void BuildPartB() {
		product.Add("部件BB");
	}
	public Product GetResult() {
		return product;
	}
}

//指挥者类
class Director{
	public void Construct(Builder builder) {
		builder.BuildPartA();
		builder.BuildPartB();
	}
}