将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
①一个对象会有一些重要的性质,在它没有恰当的值之前,对象不能作为一个完整的产品使用。
②一个对象的一些性质必须按照某个顺序赋值才有意义。
一、用程序画一个小人,要求小人有头、身体、两手、两脚。
基本代码
import java.awt.*;
import java.awt.event.*;
class DrawPerson extends Frame{
public void paint(Graphics g) {//从Frame中继承的paint方法在程序运行时会自动调用
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 lauchFrame() {
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);
}
}
public class Main{
public static void main(String[] args){
DrawPerson person=new DrawPerson();
person.lauchFrame();
}
}
画一个身体比较胖的小人,将身体的参数改一下就可以了。
二、现在的代码全写在窗体里面,要是需要在别的地方用这些画小人的程序怎么办?
import java.awt.*;
import java.awt.event.*;
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 lauchFrame() {
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);
}
}
public class Main{
public static void main(String[] args){
DrawPerson drawperson=new DrawPerson();
drawperson.lauchFrame();
}
}
三、画小人要有头有手有脚,要先不遗忘任何一个,如何做到不遗忘呢?
需要建一个抽象的构造人类的。
import java.awt.*;
import java.awt.event.*;
//画人的抽象类
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);
}
@Override
public void buildHead() {
// TODO Auto-generated method stub
g.fillOval(50, 50, 30, 30);//头
}
@Override
public void buildBody() {
// TODO Auto-generated method stub
g.fillRect(60, 80, 10, 50);//身体
}
@Override
public void buildArmLeft() {
// TODO Auto-generated method stub
g.drawLine(60, 80, 40, 130);//左手 四个数确定两个点
}
@Override
public void buildArmRight() {
// TODO Auto-generated method stub
g.drawLine(70, 80, 90, 130);//右手
}
@Override
public void buildLegLeft() {
// TODO Auto-generated method stub
g.drawLine(60, 130, 45, 180);//左腿
}
@Override
public void buildLegRight() {
// TODO Auto-generated method stub
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 pdThin=new PersonDirector(p);
pdThin.createPerson();
g.setColor(c);
}
public void lauchFrame() {
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);
}
}
public class Main{
public static void main(String[] args){
DrawPerson drawperson=new DrawPerson();
drawperson.lauchFrame();
}
}
四、建造者模式的基本代码
建造者( Builder)角色:定义创建一个Product对象所需的各个部件的操作。
具体建造者(Concrete Builder)角色:实现Builder角色提供的接口,一步步完成创建产品实例的过程。在建造过程完成后,提供产品的实例。
指导者( Director)角色:主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象。
产品(Product) 角色:产品便是建造中的复杂对象。
import java.util.ArrayList;
import java.util.List;
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);
}
}
}
abstract class Builder{//抽象建造者类,必须规定实现的三个部分
public abstract void BuildPartA();
public abstract void BuildPartB();
public abstract Product GetResult();
}
class ConcreteBuilder1 extends Builder{//具体建造者类1
private Product product=new Product();
@Override
public void BuildPartA() {
// TODO Auto-generated method stub
product.Add("部件A");
}
@Override
public void BuildPartB() {
// TODO Auto-generated method stub
product.Add("部件B");
}
@Override
public Product GetResult() {
// TODO Auto-generated method stub
return product;
}
}
class ConcreteBuilder2 extends Builder{//具体建造者类2
private Product product=new Product();
@Override
public void BuildPartA() {
// TODO Auto-generated method stub
product.Add("部件X");
}
@Override
public void BuildPartB() {
// TODO Auto-generated method stub
product.Add("部件Y");
}
@Override
public Product GetResult() {
// TODO Auto-generated method stub
return product;
}
}
class Director{//指挥类
public void Construct(Builder builder) {
builder.BuildPartA();
builder.BuildPartB();
}
}
public class Main{
public static void main(String[] args){
Director director=new Director();//指导者
Builder b1=new ConcreteBuilder1();//具体建造者
Builder b2=new ConcreteBuilder2();//具体建造者
director.Construct(b1);//指挥者用Builder1构建产品
Product p1=b1.GetResult();//获取构建的产品
p1.Show();
director.Construct(b2);//指挥者用Builder2构建产品
Product p2=b2.GetResult();//获取构建的产品
p2.Show();
}
}
在什么情况下可以使用建造者模式?
①相同的方法,不同的执行顺序,产生不同的事件结果。
②多个部件或零件都可以装配到一个对象中,但是产生的运行结果又不相同。
③产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能。