设计模式之建造者模式

前言:

建造者模式(Builder Pattern)是将一个复杂对象的的构建和它的表示分离,使得同样的构建过程可以创建么不同的表示。

一.建造者模式简介:

建造者模式(Builder Pattern)是为解决在软件系统中,对一个复杂对象的创建过程和算法进行封装,隐藏该对象是如何组装的。该模式又称为生成器模式。

二.建造者模式的实例讲解:

案例:通过建造者模式,绘制不同风格人物图像。

1.产品设计UML类图:

这里写图片描述

(图片加载慢,多刷新几下,耐心等待……)

注:指挥者类PersonDirector和建造者抽象类PersonBuilder的是聚合关系。

聚合关系:表示一种弱的拥有关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分。
2.建造者抽象类:

设计分析:所需要绘制的人物,都有共同的特征,比如人都有手有脚。将这些共同的特征抽象为一个抽象接口,用来封装绘制人物的过程,让子类不会丢失任何的步骤。

package com.pattern.builder.buider;

import java.awt.Graphics;

public abstract class PersonBuilder {
    protected Graphics graphics;//绘图

    public PersonBuilder(Graphics graphics) {
        super();
        this.graphics = graphics;
    }

    public PersonBuilder() {
    }
    //绘制头部
    public abstract void BuildHead();
    //绘制身体
    public abstract void BuildBody();
    //绘制左臂
    public abstract void BuildArmLeft();
    //绘制右臂
    public abstract void BuildArmRight();
    //绘制左腿
    public abstract void BuildLegLeft();
    //绘制右腿
    public abstract void BuildLegRight();

}
3.绘制具体人物类:

设计分析: 继承建造者抽象类,并且实现父类的建造人物过程。

①绘制一个胖子类:

package com.pattern.builder.buider;

import java.awt.Graphics;

public class FatPersonBuilder extends PersonBuilder {

    public FatPersonBuilder(Graphics graphics) {
        super(graphics);
    }

    public FatPersonBuilder() {
        super();
    }

    @Override
    public void BuildHead() {
        graphics.drawOval(315, 70, 30, 30);

    }

    @Override
    public void BuildBody() {
        graphics.drawRect(305, 100, 50, 30);

    }

    @Override
    public void BuildArmLeft() {
        graphics.drawLine(305, 100, 275, 120);// 左臂

    }

    @Override
    public void BuildArmRight() {
        graphics.drawLine(355, 100, 380, 120);// 右臂

    }

    @Override
    public void BuildLegLeft() {
        graphics.drawLine(305, 130, 275, 150);// 左腿

    }

    @Override
    public void BuildLegRight() {
        graphics.drawLine(355, 130, 380, 150);// 右腿

    }

    public static void main(String[] args) {
        FatPersonBuilder thinPersonBuilder = new FatPersonBuilder();
        thinPersonBuilder.BuildHead();
    }
}

②绘制一个瘦子类:

package com.pattern.builder.buider;

import java.awt.Graphics;

public class ThinPersonBuilder extends PersonBuilder {

    public ThinPersonBuilder(Graphics graphics) {
        super(graphics);
    }

    public ThinPersonBuilder() {
        super();
    }

    @Override
    public void BuildHead() {
        graphics.drawOval(100, 70, 30, 30);

    }

    @Override
    public void BuildBody() {
        graphics.drawRect(105, 100, 20, 30);

    }

    @Override
    public void BuildArmLeft() {
        graphics.drawLine(105, 100, 75, 120);// 左臂

    }

    @Override
    public void BuildArmRight() {
        graphics.drawLine(125, 100, 150, 120);// 右臂

    }

    @Override
    public void BuildLegLeft() {
        graphics.drawLine(105, 130, 75, 150);// 左腿

    }

    @Override
    public void BuildLegRight() {
        graphics.drawLine(125, 130, 150, 150);// 右腿

    }

    public static void main(String[] args) {
        ThinPersonBuilder thinPersonBuilder = new ThinPersonBuilder();
        thinPersonBuilder.BuildHead();
    }
}
4.指挥者类

设计分析: 指挥者类是用来控制建造过程,用它来隔离用户与建造过程的关联。

在本例中,指挥者类可以控制绘制一个人物的过程,可以对过程进行自由调整。如果新增一个绘画产品“绘制残疾人画像”(如:没有右臂的杨过),则不需要改动具体的构造者类,只需要在指挥者中,新增一个绘制残疾人物画像的方法,将绘制“右臂”的过程去掉即可。这就是指挥者的一个用途。

package com.pattern.builder.director;

import com.pattern.builder.buider.PersonBuilder;

/**
 * 指挥者类:控制建造过程
 * 
 * @author 葫芦娃
 *
 */
public class PersonDirector {
    private PersonBuilder pb; // 依赖建造者的抽象类对象

    public PersonDirector(PersonBuilder pb) {
        super();
        this.pb = pb;
    }

    // 绘制人物
    public void creatPerson() {
        pb.BuildHead();
        pb.BuildBody();
        pb.BuildArmLeft();
        pb.BuildArmRight();
        pb.BuildLegLeft();
        pb.BuildLegRight();
    }
}
5.客户端中使用:

设计分析: 客户端需要依赖指挥着类和具体的建造者类,通过指挥者中的方法,控制建造者绘制具体的人物画像,使得建造者类中的代码和客户端的表示层代码分离,降低耦合度。

注:本客户端用到JavaSwing绘图,若不了解如何用Java绘图,请点击参考本人另一篇博文介绍《 Java用JFrame、JPanel、Graphics绘图案例讲解》

package com.pattern.builder.client;

import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;

import com.pattern.builder.buider.FatPersonBuilder;
import com.pattern.builder.buider.ThinPersonBuilder;
import com.pattern.builder.director.PersonDirector;

public class Client {

    public static void main(String[] args) {
        // 创建相框
        JFrame jFrame = new JFrame();
        // 创建画板
        JPanel jpanel = new JPanel() {
            // 序列号(可省略)
            private static final long serialVersionUID = 1L;

            // 重写paint方法
            @Override
            public void paint(Graphics graphics) {
                super.paint(graphics);
                // 瘦子建造者
                ThinPersonBuilder thinPersonBuilder = new ThinPersonBuilder(graphics);
                // 指挥者,根据需求构建小人对象
                PersonDirector personDirectorThin = new PersonDirector(thinPersonBuilder);
                // 根据需求选择过程中的步骤,执行或者跳过
                personDirectorThin.creatPerson();

                // 胖子建造者
                FatPersonBuilder fatPersonBuilder = new FatPersonBuilder(graphics);
                // 指挥者,根据需求构建小人对象
                PersonDirector personDirectorFat = new PersonDirector(fatPersonBuilder);
                // 根据需求选择过程中的步骤,执行或者跳过
                personDirectorFat.creatPerson();
            }
        };
        // 将绘有小人图像的画板嵌入到相框中
        jFrame.add(jpanel);
        // 将画框展示出来。true设置可见,默认为false隐藏
        jFrame.setVisible(true);
        // 设置画框大小(宽度,高度),默认都为0
        jFrame.setSize(500, 300);

    }

}
6.运行结果展示:

这里写图片描述
(图片加载慢,多刷新几下,耐心等待……)

7.源码下载

本文示例代码下载地址:点击下载

三.总结:

1.建造者模式的优点:
  • 隐藏创建复杂对象细节。创建复杂的对象的时候,使得建造代码和表示代码分离,隐藏建造者对产品过程的组装。
  • 方便扩展。新增一个产品只需要新增一个具体的建造者就可以了。
2.建造者模式的缺点:
  • 当具体产品的细节不同的时候,建造者模式就不适用了。
  • 每次产品扩展,都要新增一个具体的建造者类,增大了代码量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值