设计模式之建造者模式

我们考虑这么一个问题:建房子。假设建房子有三个步骤:修地基,砌墙,砌屋顶。有很多种类的房子,但是建造的过程是相同的:那么假设想用一个传统方式进行建房子:

首先定义一个commonHouse继承自基类AbstractHouse并且重写修房子的三种方法。然后有一个客户端去调用这个commonhouse的方法实现:

package com.builder;

public abstract class AbstractHouse {
    //打地基
    public abstract void buildBasic();
    //砌墙
    public abstract void buildWalls();
    //封顶
    public abstract void roofed();

    //整个过程如下
    public void build(){
        buildBasic();
        buildWalls();
        roofed();
    }
}

对于某一个具体的房子的修建:

package com.builder;

public class CommonHouse extends AbstractHouse{
    @Override
    public void buildBasic() {
        System.out.println("给普通房子打地基");
    }

    @Override
    public void buildWalls() {
        System.out.println("给普通房子砌墙");
    }

    @Override
    public void roofed() {
        System.out.println("给普通房子封顶");
    }

}

那么当我们建造房子的时候调用客户端进行修建房子:

package com.builder;

public class Client {
    public static void main(String[] args){
        CommonHouse commonHouse = new CommonHouse();
        commonHouse.build();
    }
}

从传统的角度,这是一个非常容易理解和简单的操作。但是不利于程序的拓展维护,也就是说,产品(房子)和创建产品的过程(build下面调用的三个函数)封装在了一起,也就是这两个东西耦合性过强了。所以要用到建造者模式,将产品和产品的构建过程解耦。建造者模式把复杂对象的过程抽象出来,使这个抽象过程的不同实现方式可以构造出不同属性的对象。

                                                         

        在这个建造者模式中,House是一个产品,他和HouseBuilder聚合。HouseBuilder本身是一个抽象类,他抽象了整个盖房子的过程,包括了最后的返回的结果build返回了一个产品House. 然后底下有两个与HouseBuilder泛化关系的具体实现类CommonHouse和HighBuilding。HouseDirector是和HouseBuilder是聚合关系,它负责控制什么时候调用HouseBuilder建房子。Client作为主程序去调用HouseDirector.

首先来看看产品house:

package com.builder.improve;

public class House {
    private String base;
    private String wall;
    private String roofed;

    public String getBase() {
        return base;
    }

    public void setBase(String base) {
        this.base = base;
    }

    public String getWall() {
        return wall;
    }

    public void setWall(String wall) {
        this.wall = wall;
    }

    public String getRoofed() {
        return roofed;
    }

    public void setRoofed(String roofed) {
        this.roofed = roofed;
    }
}

House这个产品就是有他自己的属性。之后定义一个抽象类HouseBuilder这个类里面定义了建房子的全过程:

package com.builder.improve;

//抽象建造者,需要把建造的流程规定清楚
public abstract class HouseBuilder {

    protected House house = new House();

    public abstract void buildBasic();
    public abstract void buildWalls();
    public abstract void roofed();

    //建造房子好后,将产品返回
    public House buildHouse(){
        return house;
    }
}

然后就是抽象类的两种具体实现:

package com.builder.improve;

public class CommonHouse extends HouseBuilder{
    @Override
    public void buildBasic() {
        System.out.println("普通房子打地基5m");
    }

    @Override
    public void buildWalls() {
        System.out.println("普通房子砌墙10cm");
    }

    @Override
    public void roofed() {
        System.out.println("普通房子砌普通房顶");
    }
}
package com.builder.improve;

public class HighBuilding extends HouseBuilder{
    @Override
    public void buildBasic() {
        System.out.println("高楼打地基100m");
    }

    @Override
    public void buildWalls() {
        System.out.println("高楼砌墙20cm");
    }

    @Override
    public void roofed() {
        System.out.println("高楼砌透明屋顶");
    }
}

之后定义一个HouseDirector来负责具体建房子的具体流程:

package com.builder.improve;

public class HouseDirector {
    HouseBuilder houseBuilder = null;

    public HouseDirector(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }
    //如何处理建造房子的流程交给指挥者HouseDirector
    public House constructHouse(){
        houseBuilder.buildBasic();
        houseBuilder.buildWalls();
        houseBuilder.roofed();
        return houseBuilder.buildHouse();
    }
}

最后就是一个客户端决定什么时候盖房子了:

package com.builder.improve;

public class Client {
    public static void main(String[] args){
        CommonHouse commonHouse = new CommonHouse();
        HouseDirector houseDirector = new HouseDirector(commonHouse);
        House house = houseDirector.constructHouse();

        HighBuilding highBuilding = new HighBuilding();
        HouseDirector houseDirector1 = new HouseDirector(highBuilding);
        houseDirector1.constructHouse();
    }
}

从这个Client可以看出,当想调用一个建造者进行建房子的时候只需要先构建一个HouseBuilder完成盖房子的步骤,然后调用具体的HouseDirector来完成盖房子已经定义好的动作即可。

当如果有一个新的OtherHouse类型想要添加的时候,我们只需要做两件事情:首先在抽象类HouseBuilder上面继承新的房子类,然后在Client上面调用这个新的类即可,非常方便,易于拓展,符合开闭原则。但是需要注意的是,如果产品之间差异很大,则不适合建造者模式。

建造者模式核心是把修房子的三个步骤的定义,和修房子的创建过程constructHouse这个步骤分离出来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值