Java 建造者模式 简单的理解

建造者模式

这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式,使用多个简单的对象一步一步构建成一个复杂的对象。

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

关键代码:建造者-->创建和提供实例,导演-->管理建造出来的实例的依赖关系。

优点:建造者独立、易扩展,便于控制细节风险。

缺点:产品必须有共同点,范围有限制,如果内部变化复杂,会有很多的建造类。

实例:

我们新建一个人的类。

public class Human {
    //构造一个人的基本属性
    private String head;
    private String body;
    private String hand;
    private String foot;

    //这里用于打印通过我们造出一个人的基本属性
    public void show(){
        System.out.println(head);
        System.out.println(body);
        System.out.println(hand);
        System.out.println(foot);
    }
    
    public String getHead() {
        return head;
    }

    public void setHead(String head) {
        this.head = head;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getHand() {
        return hand;
    }

    public void setHand(String hand) {
        this.hand = hand;
    }

    public String getFoot() {
        return foot;
    }

    public void setFoot(String foot) {
        this.foot = foot;
    }
}

 

只要是一个人,都是从这个类出来的。(基本类)

一个人的基本属性我们定下来了,但是造人的话,得要规定一个标准吧。所以我们先写一个接口,定义一个造人标准接口。

public interface IHuman { //构造人的方法
    void buildHead();//构造人的头
    void buildBody();//构造人的身体
    void buildHand();//构造人的手
    void buildFoot();//构造人的脚
    Human createHuman();//返回一个我们想要构造的人
}

 

现在,根据我们定的人的基本属性和造人标准,来造一个胖的人。

public class FatBuildHuman implements IHuman {//这个胖人类实现造人的接口

    Human human;

    public FatBuildHuman (){
        human =new Human();
    }

    @Override
    public void buildHead() {
        human.setHead("胖人的头");
    }

    @Override
    public void buildBody() {
        human.setBody("胖人的身体");
    }

    @Override
    public void buildHand() {
        human.setHand("胖人的手");
    }

    @Override
    public void buildFoot() {
        human.setFoot("胖人的脚");
    }

    @Override
    public Human createHuman() {
        return human;//返回我们构造的人
    }

}

到这里呢,我们已经完成了建造的过程,接下来,就是介绍构建者模式的精髓,director  这个director,就是来执行我们刚才的造人动作,可以简单理解为 指挥员 。

public class Director {

    public Human create(IHuman iHuman){//
        iHuman.buildHead();
        iHuman.buildBody();
        iHuman.buildHand();
        iHuman.buildFoot();
        return iHuman.createHuman();
    }
}

这个Director类,重点在于create方法的参数是我们刚才定义的造人标准接口,只要是实现了我们的这个接口的类,就都可以作为参数

现在我们来看看Director是如何发挥它的指挥能力的。

public class Test {

    public static void main(String[] args) {
        Director director = new Director();
        Human human = director.create(new FatBuildHuman());
        human.show();
    }

}

结果:

1 胖人的头
2 胖人的身体
3 胖人的手
4 胖人的脚

 现在我们再来造一个 高智商头脑、强壮的身体、灵活的小手、有点肥的脚 的人出来。

先建一个名为TestHuan的类出来,并且实现 我们刚刚 定义的  造人标准接口。

public class TestHuman implements IHuman {

    Human human;

    public TestHuman(){
        human = new Human();
    }

    @Override
    public void buildHead() {
        human.setHead("高智商的头脑");
    }

    @Override
    public void buildBody() {
        human.setBody("强壮的身体");
    }

    @Override
    public void buildHand() {
        human.setHand("灵活的小手");
    }

    @Override
    public void buildFoot() {
        human.setFoot("有点肥的脚");
    }

    @Override
    public Human createHuman() {
        return human;
    }
}

 同样的通过Director类 来 指挥:

public class Test {

    public static void main(String[] args) {
  
        Human human1 = director.create(new TestHuman());
        human1.show();

    }

}

 结果:

1 高智商的头脑
2 强壮的身体
3 灵活的小手
4 有点肥的脚

Director类,重点在于create方法的参数我们刚才定义的造人标准接口只要是实现了我们的这个接口,就都可以作为参数

建造者模式就是这样。那到最后,我们必须要思考一下为什么这么做?学而不思则罔,我们纵观全部代码,其实我们就会发现,在最后的Test类中,我们其实根本就不会知道具体是怎么造人的,因为这个过程让Director给代劳了。然后,我们的FatBuildHuman类中才是真正的造人方法。Director其实只是执行了这个过程。这样子,达到了分离模块的功能。造人的过程,启动造人的过程,和最后选择哪种人来造。都分的清清楚楚。就有了一些模块化的感觉,这样维护和扩展都是很方便的。

另一个示例代码:

package mass.resultDemo;

import com.github.pagehelper.Page;

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

public class ResultVo<T>{
    private int code;
    private String errMsg;
    private T data;
    private Page<T> pager;

    private List<ErrorDetail> errors;
    private long dataTimestamp;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getErrMsg() {
        return errMsg;
    }

    public void setErrMsg(String errMsg) {
        this.errMsg = errMsg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Page<T> getPager() {
        return pager;
    }

    public void setPager(Page<T> pager) {
        this.pager = pager;
    }

    public List<ErrorDetail> getErrors() {
        return errors;
    }

    public void setErrors(List<ErrorDetail> errors) {
        this.errors = errors;
    }

    public long getDataTimestamp() {
        return dataTimestamp;
    }

    public void setDataTimestamp(long dataTimestamp) {
        this.dataTimestamp = dataTimestamp;
    }


    // director
    public static ResultBuilder status(int code){
        ResultBuilder builder = new DefaultBuilder<>();
        builder.status(code);
        return builder;
    }

    public static ResultBuilder addError(String type, String message) {
        ResultBuilder builder = new DefaultBuilder<>();
        builder.addError(type, message);
        return builder;
    }

    public static ResultVo ok(Object data){
        ResultBuilder builder = new DefaultBuilder<>();
        return builder.data(data);
    }

    public static ResultVo ok(Object data, Page page){
        ResultBuilder builder = new DefaultBuilder<>();
        return builder.data(data);
    }

    public static ResultVo err(int code,String errMsg){
        return null;
    }

    @Override
    public String toString() {
        return "ResultVo{" +
                "code=" + code +
                ", errMsg='" + errMsg + '\'' +
                ", data=" + data +
                ", pager=" + pager +
                ", errors=" + errors +
                ", dataTimestamp=" + dataTimestamp +
                '}';
    }

    // 函数的类型签名
    public interface ResultBuilder<T> {
        ResultBuilder addError(String type, String message);
        ResultBuilder status(int status);

        ResultVo<T> data(T data);
        ResultVo<T> data(int status, T data);
        ResultVo<T> err(int status);
        ResultVo<T> err(int status, String emsg);
    }

    public static class DefaultBuilder<T> implements ResultBuilder<T> {
        private ResultVo<T> resultVo;

        public DefaultBuilder() {
            this.resultVo = new ResultVo<T>();
        }

        @Override
        public ResultBuilder addError(String type, String message) {
            if(resultVo.getErrors() == null) {
                resultVo.setErrors(new ArrayList<>());
            }
            ErrorDetail detail = new ErrorDetail();
            detail.setType(type);
            detail.setMessage(message);
            resultVo.getErrors().add(detail);
            return this;
        }

        @Override
        public ResultBuilder status(int status) {
            resultVo.setCode(status);
            return this;
        }

        @Override
        public ResultVo<T> data(T data) {
            return null;
        }

        @Override
        public ResultVo<T> data(int status, T data) {
            // status 200
            this.status(status);
            resultVo.setData(data);
            return resultVo;
        }

        @Override
        public ResultVo<T> err(int status) {
            return null;
        }

        @Override
        public ResultVo<T> err(int status, String emsg) {
            return null;
        }
    }
}

class ErrorDetail {
    private String type;
    private String message;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

 

测试:

package mass.resultDemo;

import com.github.pagehelper.Page;

import java.util.ArrayList;

public class TestResult {

    public static void main(String[] args) {

        ResultVo resultVo_1 = ResultVo.ok("正常返回");

        ResultVo resultVo = new ResultVo();
        ArrayList<ErrorDetail> list = new ArrayList<>();
        list.add(new ErrorDetail());
        list.add(new ErrorDetail());
        list.add(new ErrorDetail());
        list.add(new ErrorDetail());
        list.add(new ErrorDetail());
        list.add(new ErrorDetail());
        resultVo.setErrors(list);




        ResultVo resultVo_2 = ResultVo.ok("带分页信息返回", new Page());

        ResultVo resultVo_3 = ResultVo.status(201).data("正常返回");

        ResultVo resultVo_4 = ResultVo.err(400, "数据错误");

        ResultVo resultVo_5 = ResultVo.status(400).err("数据错误");

        ResultVo resultVo_6 = ResultVo
                .addError(new ErrorDetail("RunTimeException",555))
                .addError("RunTimeException",500)
                .addError(new ErrorDetail())
                .err(411);
    }
}

 

posted @ 2018-12-06 20:38  追梦滴小蜗牛  阅读(832)  评论(0编辑  收藏  举报