揭秘设计模式:建造者模式(Builder)的理解和学习

    链接地址:http://www.xx566.com/detail/108.html

    一直以来,在程序员这个领域,每到找工作的季节,我们总能在企业招聘的简章中看到:熟练使用常用设计模式、精通设计模式之类的字眼,每次看到这些信息,心 里总会一咯噔,似乎设计模式离自己好远,这种高大上的东西自己怎么可能熟练使用甚至精通,其实不然,在平常的工作和学习中,我们可能已经使用到了多种设计 模式,只是没有对其进行详细的剖析和理解,所以总会有些茫然,现在,我们就来一点点开始设计模式的学习和揭秘。

    最近在重读EffectiveJava的时候,看到了建造者模式(Builder Pattern),决定先从它开始学习。建造者模式的英文定义为:Separate the construction of a complex object from its representation so that the same construction process can create different representations。意思就是把一个复杂对象的构造和它的表示分开,这样同样的构造过程就可以创建不同的表示。

 

    翻译过来有点不太懂,举个例子:就是建房子时候,把建房子的过程(设计图纸啊什么的)和房子的组件(铁门啊铁窗铁锁链)分开,目的就是为了解耦合(又一个高大上的词汇),下面举一个现实中的例子,可能更好理解,本篇的代码也是对其的实现。

 

    我 (HouseOwner)现在要建造一所房子(House),于是我找了个包工头(WorkerLeader),工头手下有两个工人(WorkerA 和 WorkerB),我们签订了合同,他负责指挥两个工人共建造两个房间(RoomA 和 RoomB),同时完成后负责验收和交付房屋,工头指挥WorkerA建造RoomA,指挥WorkerB建造RoomB。


   下面我们把上面的故事通过代码来实现,首先是房屋对象,有roomA和roomB,房屋对象由于是唯一的,这里使用了单例(更多单例请参阅:三种方式实现类的单例),代码如下:

package javase.builder;
 
/**
 * 房屋本身
 * 
 * @Package javase.builder
 * @ClassName: House
 * @author Realfighter
 * @date 2014-7-24 下午01:58:12
 */
public enum House {
 
    INSTANCE;
 
    boolean roomA;// A屋
 
    boolean roomB;// B屋
 
    /**
     * 建造RoomA
     * 
     * @Title: setRoomA
     * @author Realfighter
     * @date 2014-7-24 下午02:01:28 void
     */
    public void setRoomA(boolean roomA) {
        this.roomA = roomA;
    }
 
    /**
     * 建造RoomB
     * 
     * @Title: setRoomB
     * @author Realfighter
     * @date 2014-7-24 下午02:02:14 void
     */
    public void setRoomB(boolean roomB) {
        this.roomB = roomB;
    }
 
    public boolean getRoomA() {
        return roomA;
    }
 
    public boolean getRoomB() {
        return roomB;
    }
 
}

    其次,由于WorkerA和WorkerB的工作相同,但是工作内容不同,我们首先抽象出一个工作接口,如下:

package javase.builder;
 
/**
 * 工作接口
 * 
 * @Package javase.builder
 * @ClassName: Worker
 * @author Realfighter
 * @date 2014-7-24 下午02:04:53
 */
public interface Worker {
 
    /**
     * 建造Room
     * 
     * @Title: buildRoom
     * @author Realfighter
     * @date 2014-7-24 下午02:04:42 void
     */
    public void buildRoom();
 
    /**
     * 交付Room
     * 
     * @Title: deliverRoom
     * @author Realfighter
     * @date 2014-7-24 下午02:32:32
     * @return boolean
     */
    public boolean deliverRoom();
 
}

        然后需要寻找一个合适的包工头对象帮助建造房屋,包工头负责命令工人和交付房屋,代码如下:

package javase.builder;
 
/**
 * 包工头
 * 
 * @Package javase.builder
 * @ClassName: Leader
 * @author Realfighter
 * @date 2014-7-24 下午01:56:24
 */
public class Leader {
 
    /**
     * 命令工人
     * 
     * @Title: order
     * @author Realfighter
     * @date 2014-7-24 下午02:51:27
     * @param worker
     *            void
     */
    public void order(Worker worker) {
        worker.buildRoom();
        worker.deliverRoom();
    }
 
    /**
     * 验收交付房屋
     * 
     * @Title: deliverHouse
     * @author Realfighter
     * @date 2014-7-24 下午02:51:36
     * @return House
     */
    public House deliverHouse() {
        if (House.INSTANCE.getRoomA() && House.INSTANCE.getRoomB()) {
            return House.INSTANCE;
        }
        return null;
    }
 
}

    之后包工头就需要寻找两个工人分别开始建造了,工人负责建造room和交付room,代码如下:

package javase.builder;
 
/**
 * 工人实例A
 * 
 * @Package javase.builder
 * @ClassName: WorkerA
 * @author Realfighter
 * @date 2014-7-24 下午01:58:24
 */
public class WorkerA implements Worker {
     
    /**
     * 建造RoomA
     * 
     * @Title: buildRoomA
     * @author Realfighter
     * @date 2014-7-24 下午02:11:04
     */
    public void buildRoom() {
        House.INSTANCE.setRoomA(true);
    }
 
    /**
     * 交付RoomA
     * 
     * @Title: deliverRoomA
     * @author Realfighter
     * @date 2014-7-24 下午02:11:12
     * @return
     */
    public boolean deliverRoom() {
        return House.INSTANCE.roomA;
    }
 
}
package javase.builder;
 
/**
 * 工人实例B
 * 
 * @Package javase.builder
 * @ClassName: WorkerB
 * @author Realfighter
 * @date 2014-7-24 下午01:58:24
 */
public class WorkerB implements Worker {
 
    /**
     * 建造RoomB
     * 
     * @Title: buildRoom
     * @author Realfighter
     * @date 2014-7-24 下午02:11:04
     */
    public void buildRoom() {
        House.INSTANCE.setRoomB(true);
    }
 
    /**
     * 交付RoomB
     * 
     * @Title: deliverRoom
     * @author Realfighter
     * @date 2014-7-24 下午02:11:12
     * @return
     */
    public boolean deliverRoom() {
        return House.INSTANCE.roomB;
    }
 
}

    时间一分一秒的过去,终于有一天,房屋主人来找包工头了,代码如下:

package javase.builder;
 
/**
 * 房屋主人,负责接收房子
 * 
 * @Package javase.builder
 * @ClassName: HouseOwner
 * @author Realfighter
 * @date 2014-7-24 下午01:51:44
 */
public class HouseOwner {
 
    /**
     * @Title: main
     * @author Realfighter
     * @date 2014-7-24 下午01:51:34
     * @param args
     *            void
     */
    public static void main(String[] args) {
        // 找一个包工头
        Leader leader = new Leader();
        // 包工头找两个工人
        Worker workerA = new WorkerA();
        Worker workerB = new WorkerB();
        // 包工头指挥两个工人
        leader.order(workerA);
        leader.order(workerB);
        // 包工头将验收后的房屋交付屋主人
        leader.deliverHouse();
    }
 
}

   到此,建造者模式已经实现完成,有没有很简单,最后我们来看一下此模式的通用类图:

暂无图片

    不难发现,本例中的Leader类似于上图中的Director,Worker抽象类类似于Builder接口,House则类似于 Product,WorkerA和WorkerB都是ConcreteBuilder,现在回头再看,设计模式其实并不复杂,只要做到了理解,很快就能熟 练应用了。

转载于:https://my.oschina.net/realfighter/blog/349713

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值