设计模式(3) - 创建型模式 - 建造者模式 (& 链式编程)

1. 传统建造者模式功能

1.1介绍

下面的这句话 是我抄的,忘了哪里的了。我发现,怎么说的都有,我的也不一定对。最主要的还是灵活运用吧,毕竟规则是死的,人是活的。

这里我也没有对比 使用建造者模式与不使用建造者的区别。所以看不出来为何要使用建造者模式。

  • 分离了对象子组件的单独构造(由Builder来负责)装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于:某个对象的构建过程复杂的情况下使用。
  • 由于实现了构建和装配的解耦。不同的构建器,相同的装配,也可以做出不同的对象;
  • 相同的构建器,不同的装配顺序也可以做出不同的对象。也就是实现了构建算法、装配算法的解耦,实现了更好的复用。

1.2 个人理解

  • 客户端(使用 程序 )不必知道产品内部组成的细节,将本身与创建过程解 耦,使得相同的创建过程可以创建不同的产品对象
  • 一般是指挥者不用变。就是不同的建造者,可以建造一个产品的不同表现(也就是不同的形式)。比如你让一个指挥者,指挥建造电脑,如果一个建造者有高级的cpu。很高级的显卡,那么这个建造者所生产出来的,就是一个高配电脑。如果换一个建造者,这个建造者给的cpu不行,显卡不行。那么这个指挥者来指挥这个建造者,建造出来的东西,肯定比指挥上一个建造者要差一些。

1.3 与工厂模式的区别

  • 工厂模式不注重这个对象实例化的细节。一般 创建的对象,比建造者模式创建出来的要简单,
  • 一般这个工厂模式可以与建造者模式来搭配使用,工厂模式可以给建造者模式来提供组件。

1.3 涉及到的角色

  1. Product: 产品,呸,说白了,就是你要创建的那个对象(创建这个对象比较复杂)。
  2. Builder: 建造者(接口or抽象类),说白了,就是用来规定构建这个Object 所需要的组件的。
  3. BuilderImpl: 建造者的实现,也就是说,前面的Builder已经制定了标准了,这个用来实现它的标准,当然可能有多个,每一个建造者,建造出来的东西是不同的。如果想建造这个产品的不同的表现(不同的类型),那就在扩展一个,符合了开闭原则。
  4. Director: 指挥者,它代替用户来操作建造者(builder)。个人感觉可以有多个。比如: 炒 一个 鱼香肉丝, 这个厨师拿到一个做菜的这个材料,要求它都要放,顺序随意, 这个厨师喜欢先放酱油,后放盐,另一个厨师喜欢先放盐,后放酱油。 这个厨师可以理解为指挥者, 指挥不同,那么做出来的菜的味道一般也是不一样的。所以,同样的构建者,被不同的指挥者进行指挥,最后的结果可能也是不一样的。

1.4 类图

在这里插入图片描述

1.5 代码(可不看)

  • Product
/**
 * @author immortal
 * 这个是我们的产品Product(要构建的那个非常复杂的对象):
 * 		手机
 * 里面有: cpu,screen,camera
 * 		:中央处理器, 屏幕  相机
 */
class Phone {
	// 你假定它不是string类型的。而是Cpu类型的
	private String cpu;

	// 屏幕,理由同上
	private String screen;
	
	// 相机, 理由同上
	private String camera;

	// set方法 略。。。。。。。。。。。。。
	
}

  • Builder: 接口or抽象类
/**
 * @author immortal
 * 这个时候,需要一个构建者来构建我们的手机
 * 但是在这之前呢。还需要一个接口来制定规定。
 * 来规定这个手机都需要什么组件。为的是以后
 * 扩展的构建者 都要遵循这个规则,这也是面向接口
 * 编程的好处
 */
interface Builder {
	
	void setCpu();
	
	void setScreen();
	
	void setCamera();
	
	/**
	 * 构建
	 */
	Phone BuildProduct();
}
  • BuilerImplement(接口的实现之一)
/**
 * @author immortal
 * 这个时候来一个具体的构建者:
 * 	小米手机的构建者
 */
class XiaoMiBuilder implements Builder {

	Phone phone = new Phone();
	
	@Override
	public void setCpu() {
		phone.setCpu("晓龙865");
	}

	@Override
	public void setScreen() {

		phone.setScreen("三星曲面屏");
	}

	@Override
	public void setCamera() {
		phone.setCamera("索尼高级相机");
	}

	@Override
	public Phone BuildProduct() {
		return this.phone;
	}
	
}
  • BuilerImplement(接口的实现之二)
/**
 * @author immortal
 * 这个时候来一个具体的构建者:
 * 	华为手机的构建者
 */
class HuaWeiBuilder implements Builder {
	
	Phone phone = new Phone();
	
	@Override
	public void setCpu() {
		phone.setCpu("海思麒麟9x0");
	}
	
	@Override
	public void setScreen() {
		
		phone.setScreen("三星曲面屏");
	}
	
	@Override
	public void setCamera() {
		phone.setCamera("徕卡特别厉害的相机");
	}
	
	@Override
	public Phone BuildProduct() {
		return this.phone;
	}

}
  • 指挥者Director(个人感觉可以有多个指挥者)
/**
 * 高级指挥者,这人指挥出来的品控  就是牛
 * @author immortal
 */
class HightDirector {

	// 要指挥的构建者
	private Builder builder;
	public HightDirector(Builder builder) {
		this.builder = builder;
	}
	
	/**
	 * 构建
	 * @return
	 */
	public Phone buildPhone() {
	
		// 这个指挥者先装屏幕
		builder.setScreen();
		builder.setCpu();
		builder.setCamera();
		return builder.BuildProduct();
	}
}
  • 如何使用?
public class Test {

	public static void main(String[] args) {
		
		// 找个建造者
		XiaoMiBuilder builder = new XiaoMiBuilder();
		// 找一个指挥者
		HightDirector director = new HightDirector(builder);
		
		// 把建造者交给指挥者指挥,你歇着等给结果
		Phone phone = director.buildPhone();
		System.out.println(phone.getCpu());
		
		
	}
}

1.6 扩展是否满足要求?

在这里插入图片描述

1.7 总结

其实啊,看上面的东西,可能根本理解不了建造者的好处,为什么使用建造者?这东西还是给我自己看的把。。。。

2. 无指挥者建造者(链式编程)

2.1 介绍

在很多地方我们都见过。譬如很多地方都见过这样的方式, 我最近因为课程原因,大概去学了一下Android,比如Android有一个图片的框架,叫Glide。还有一个封装了okHttp的工具类名为: okhttp-utils

  • okhttp-utils 框架例子
String url = "http://www.csdn.net/";
RequestCall build = OkHttpUtils
     .get()
     .url(url)
     .addParams("username", "root")
     .addParams("password", "123")
     .build();

这样写的好处是什么呢? 很明显,我们在构造这个复杂对象的时候,我们可以随意舍去一些不需要的参数。可以非常轻便的构造这个对象。比如这个,我们在发送请求的时候,可以把addParams 去掉,随意搭配。

前几个打点. 都是给这个对象设置值。最后一个build()方法就把你前面所构成的对象返回给你。

2.2 使用的场景

  • 对象属性多。构造复杂。
  • 这个对象有一些按需求所设置的属性,有时候可以不设置,有时候需要设置

2.3 使用的好处

  • 如果你不这样使用。你就得用set方法,或者用很多个构造方法。这显然比链式编程麻烦的多,自行体会😂

2.4 例子代码

最主要还是灵活运用,这玩意儿是死的,人是活的。写法也有很多,这里我模拟发送请求的utils

很明显也算是建造者模式 ,只不过是自己充当了 指挥者

  1. Client端代码,这个对象是如何用的呢。可以看到,下面运用了链式编程
public class Client {

	public static void main(String[] args) {
		// 模拟发送post请求
		String url = "www.baidu.com";
		Post post = RequestUtils
			.post(url)
			// 设置各种值
			// 参数可选:比如我不设置head 注掉也没问题。灵活控制
//			.addHead("application/json; charset=utf-8")
			.addParam("username", "lzy")
			.addParam("password", "123213")
			.addParam("type", 1)
			// 比如我不设置超时时间,就注掉, 很灵活
//			.connTimeOut(10000)
			// 最后设置完了,就build返回对象
			.build();
		
		System.out.println(post);
	}
}

  1. RequestUtils代码,其实也可以不用,可以直接构造PostBuilder对象
/**
 * 请求工具类,假设里面有get。post等
 * @author immortal
 */
public class RequestUtils {

	/**
	 * post
	 * @param url
	 * @return
	 */
	public static PostBuilder post(String url) {
		return new PostBuilder(url);
	}
	
	// 。。。。。。。。。。。put delete get ...........
}

  1. Post 其实就是我们要构造的
public class Post {

	// 必选
	private String url;
	
	// 可选
	private String head;
	private Map<String, Object> param = new HashMap<>();
	private long connTimeOut;
	
	// 。。。。。。。get & set 方法 略。。。。。。
	
}
  1. PostBuilder: 构造Post的builder
public class PostBuilder {

	private Post post = new Post();
	
	public PostBuilder(String url) {
		this.post.setUrl(url);
	}
	
	/**
	 * 设置head,
	 * @param head
	 * @return 返回设置好的自己。方便自己下次在打点设置
	 */
	public PostBuilder addHead(String head) {
		this.post.setHead(head);
		return this;
	}
	
	/**
	 * 设置parameter
	 * @param key key
	 * @param value value
	 * @return 返回构造好的
	 */
	public PostBuilder addParam(String key, Object value) {
		this.post.getParam().put(key, value);
		return this;
	}
	
	/**
	 * 设置连接超时时间
	 * @param time 毫秒
	 * @return 返回构造好的
	 */
	public PostBuilder connTimeOut(long time) {
		this.post.setConnTimeOut(time);
		return this;
	}
	
	/**
	 * 最后返回自己
	 * @return 返回构造好Post
	 */
	public Post build() {
		return this.post;
	}

	
}

2.5 总结

看着玩玩吧, 自己记录的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值