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();
} }
结果:
胖人的头
胖人的身体
胖人的手
胖人的脚
现在我们再来造一个 高智商头脑、强壮的身体、灵活的小手、有点肥的脚 的人出来。
先建一个名为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(); } }
结果:
高智商的头脑
强壮的身体
灵活的小手
有点肥的脚
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);
}
}
Java 建造者模式 简单的理解的更多相关文章
- OSI七层模式简单通俗理解
OSI七层模式简单通俗理解 这个模型学了好多次,总是记不住.今天又看了一遍,发现用历史推演的角度去看问题会更有逻辑,更好记.本文不一定严谨,可能有错漏,主要是抛砖引玉,帮助记性不好的人.总体来说,OS ...
- 今儿直白的用盖房子为例,给你讲讲Java建造者模式
摘要:建造者模式(Builder Pattern)又叫生成器模式,是一种对象构建模式.它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象. 本 ...
- Java建造者模式
建造者模式 建造者模式适用场景: 建造一个复杂的对象适用,将构建对象的过程分开,每个类单独构造对象的一部分,最后组装起来,返回我们需要的对象. 下面的例子主要讲解构造一个飞船 Demo: //要获得的 ...
- java 建造者模式
package de.bvb.test3; /** * 建造者模式: 假如一个类有4个字段,每个字段或者每几个字段的组合都需要设置为构造函数,构造函数就比较麻烦 * 而且如果再加一个字段进去也不好拓展 ...
- Java建造者模式(思维导图)
图1 建造者模式[点击查看大图] 基本的知识点已在思维导图中,下面是demo 1,Builder 为创建一个产品对象的各个部件指定抽象接口 public interface PersonBuilder ...
- Java设计模式—建造者模式
建造模式: 将一个复杂的对象的构建与它的表示分离,使得同样的构建 过程可以创建不同的. 建造模式表示是将复杂的内部创建封装在内部,对于外部调用的人来说,只需要传入建造者和建造工具,对于内 ...
- 用建造者模式实现一个防SQL注入的ORM框架
本文节选自<设计模式就该这样学> 1 建造者模式的链式写法 以构建一门课程为例,一个完整的课程由PPT课件.回放视频.课堂笔记.课后作业组成,但是这些内容的设置顺序可以随意调整,我们用建造 ...
- Java Builder 模式,你搞明白了么?
Builder 模式定义 Builder 模式中文叫作建造者模式,又叫生成器模式,它属于对象创建型模式,是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.建造者模式是一步一步 ...
- JAVA设计模式之简单粗暴学建造者模式
文章由浅入深,先用简单例子说明建造者,然后分析模式的优缺点,最后结合优秀开源框架Mybatis,说明该模式的用处. 1.先定义一个机器人模型 package com.jstao.model; publ ...
随机推荐
- python3.4 + pycharm安装与使用
因个人是windows的环境,所以本文只讲windows环境下的python安装. 作为初用python的盆友,强烈建议只在电脑上装一个python版本就好了,不然就进了各种坑里了. Python安装 ...
- Spring Cloud Bus 自动更新配置
---恢复内容开始--- Spring Cloud Config 结合 Spring Cloud bus 实现 git 仓库提交配置文件 触发消息队列 应用自动更新配置 1. config 服务端 添 ...
- select poll epoll之间的区别
1.select poll每次循环调用时都需要将文件描述符和事件拷贝到内核空间,epoll只需要拷贝一次: (这种情况在对于描述符数量不大的情况下还可以,但是当描述符的数量达到十几万甚至上百万的时候, ...
- 2019icpc南昌邀请赛F(线段树)
题目链接:https://nanti.jisuanke.com/t/40258 题意:给长为n的数组a,有m次操作,包括单点修改和查询F(l,r),其值为所有f(i,j)的异或和,l<=i< ...
- JS小知识--获取当前日期的时间和上周五时间
获取当前日期的时间和上周五时间 var today=new Date();//获取当前时间var weekday=today.getDay();//获取星期几 var monday=new Da ...
- 面试40-一个数组,有2个数字出现奇数次,其余都是偶数次,求这两个数字O(n) O(1)
#include<iostream> using namespace std; // 题目:数组中只有不多于两个数字出现次数是奇数次,其他都是偶数次,求出出现奇数次的数字(不含0的数组) ...
- HDU 4253-Two Famous Companies(二分+最小生成树)
Description In China, there are two companies offering the Internet service for the people from all ...
- Known Notation括号匹配类问题(2014年ACM/ICPC 亚洲区域赛牡丹江)
题意: 给你数字或 * 的串,你可以交换一个*和数字.在最前面添1.在一个地方插入*,问你使串满足入栈出栈的(RNP)运算法则. 思路: 引用:https://blog.csdn.net/u01158 ...
- js跳转页面的方法
js跳转页面的几种方法 第一种:(跳转到b.html) <script language="javascript" type="text/javascript&qu ...
- C++ 标准库字符串类使用
标准库中的字符串类 C++语言直接支持C语言所有概念. C++中没有原生的字符串类型. 由于C++中没有原生的字符串类型,C++标准库提供了string类型. 1.string 直接支持字符串链接 2 ...