前言

在上一篇中我们学习了工厂模式,介绍了简单工厂模式、工厂方法和抽象工厂模式。本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式。

建造者模式

简介

建造者模式是属于创建型模式。建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 简单的来说就是将一个复杂的东西抽离出来,对外提供一个简单的调用,可以在同样的构建过程创建不同的表示。和工厂模式很相似,不过相比而言更加注重组件的装配。

这里用一个示例来进行说明。 我们一天吃的食物有这些,煎饼、盒饭、拉面、豆浆、牛奶和果汁。分为三餐、早餐、午餐和晚餐,餐点主要包含吃的(俗称饭)和喝的(豆浆,果汁之类的),那么我们可以把煎饼和豆浆作为早餐,盒饭和果汁作为午餐,这样我们可以清楚的知道要吃早餐和午餐包含什么食物。

首先我们定义一个食物类,有两个属性,吃的和喝的。

class Meal{private String food;private String drinks;public String getFood() {return food;}public void setFood(String food) {this.food = food;}public String getDrinks() {return drinks;}public void setDrinks(String drinks) {this.drinks = drinks;}
}
复制代码

定义了食物时候,我们在定义一个食物的标准接口,一份食物包含什么,其实也就是吃的和喝的。

interface IBuilderFood{void buildFood();void buildDrinks();Meal createMeal();
}
复制代码

食物接口定义一个吃的和一个喝的组件,然后通过**createMeal()**方法返回我们需要的食物。 那么现在我们便可以定义一份早餐和午餐。 代码示例:

class Breakfast implements IBuilderFood{Meal meal;public Breakfast(){meal=new Meal();}@Overridepublic void buildFood() {meal.setFood("煎饼");}@Overridepublic void buildDrinks() {meal.setDrinks("豆浆"); }@Overridepublic Meal createMeal() {return meal;}
}class Lunch implements IBuilderFood{Meal meal;public Lunch(){meal=new Meal();}@Overridepublic void buildFood() {meal.setFood("盒饭");}@Overridepublic void buildDrinks() {meal.setDrinks("果汁");   }@Overridepublic Meal createMeal() {return meal;}
}
复制代码

定义完之后,建造早餐和午餐的的过程已经完毕了。但是这并不是建造者模式,它有个核心的Director(导演者),它用来创建复杂对象的部分,对该部分进行完整的创建或者按照一定的规则进行创建。那么这里我们可以创建一个Director,用来创建一份餐点。至于创建的是什么餐点,它不用知道,这一点由调用者来进行决定。

这里我们就可以定义一个饭店,可以创建一份餐点,创建什么餐点有顾客决定。 代码示例:

class FoodStore{public Meal createBreakfast(IBuilderFood bf){bf.buildDrinks();bf.buildFood();return bf.createMeal();}
}
复制代码

创建完成这个Director之后,我们再来进行调用测试。

代码示例:


public class BuilderTest {public static void main(String[] args) {FoodStore foodStore=new FoodStore();Meal meal=foodStore.createBreakfast(new Breakfast());Meal meal2=foodStore.createBreakfast(new Lunch());System.out.println("小明早上吃的是:"+meal.getFood()+",喝的饮料是:"+meal.getDrinks());System.out.println("小明中午吃的是:"+meal2.getFood()+",喝的饮料是:"+meal2.getDrinks());  }}复制代码

输出结果:

小明早上吃的是:煎饼,喝的饮料是:豆浆
小明中午吃的是:盒饭,喝的饮料是:果汁
复制代码

简单的介绍了下建造者模式的运作原理,可以概况为这4点:

  1. Builder:指定一个抽象的接口,规定该产品所需实现部件的创建,并不涉及具体的对象部件的创建。

  2. ConcreteBuilder:需实现Builder接口,并且针对不同的逻辑,进行不同方法的创建,最终提供该产品的实例。

  3. Director:用来创建复杂对象的部分,对该部分进行完整的创建或者按照一定的规则进行创建。

  4. Product:示被构造的复杂对象。

使用场景: 适用一些基本组件不便,但是组合经常变化的时候。比如超市促销的大礼包。

优点:

  1. 建造者独立,易扩展。
  2. 便于控制细节风险。

缺点

  1. 内部结构复杂,不易于理解。
  2. 产品直接需要有共同点,范围有控制。

原型模式

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

一般来说我们在创建对象的时候是直接创建的,但是创建该对象的代价很大的时候,重复的二次创建就有些不划算,这时我们就可以使用原型模式。 打个比方,我们都发送过邮件,在节日的时候一般发送的是祝福语句,在这些祝福语句中,一般除了名字不一样之外,大部分都是一样的。这时我们就可以利用该模式来进行相应出创建。

这里还是用一个的简单的示例来说明。 小明和小红在同一天生日,然后我们需要给他们发送邮件进行祝福,但是由于比较懒,祝福语除了名字之外都是一样的。这时我们就可以先完成祝福语的编写,然后克隆该祝福语,最后根据不同的名称进行发送。不过这里就从简了,只是简单的打印下而已。

代码示例:

public class PrototypeTest {public static void main(String[] args) {Mail mail=new Mail();mail.setMsg("生日快乐!");Mail mail2=(Mail) mail.clone();mail.setName("小明");mail2.setName("小红");System.out.println(mail.toString());System.out.println(mail2.toString());}
}class Mail implements Cloneable {private String name;private String msg;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Object clone() {Object clone = null;try {clone = super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return clone;}@Overridepublic String toString() {return name + ":" + msg ;}}
复制代码

输出结果:

小明:生日快乐!
小红:生日快乐!
复制代码

看完原型模式的创建,是不是感觉就是和Java中克隆即为类似呢? 实际上它的核心也就是克隆。 克隆有两种,浅克隆和深克隆,本文主要介绍的是浅克隆。 浅克隆:

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。 简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。 实现Cloneable接口并重写Object类中的clone()方法;

深克隆:

在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。

简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

使用场景:

  1. 类初始化的时候需要消耗大量资源的时候;
  2. 获取数据库连接繁琐的时候;
  3. 一个对象,有很多个修改者的时候;

优点: 1.可以提升性能;

缺点: 1.因为必须实现Cloneable 接口,所以用起来可能不太方便。

其它

音乐推荐

原创不易,如果感觉不错,希望给个推荐!您的支持是我写作的最大动力! 版权声明: 作者:虚无境 博客园出处:www.cnblogs.com/xuwujing CSDN出处:blog.csdn.net/qazwsxpcm     个人博客出处:www.panchengming.com 原创不易,转载请标明出处,谢谢!

Java进阶篇设计模式之三 ----- 建造者模式和原型模式相关推荐

  1. Java进阶篇设计模式之十三 ---- 观察者模式和空对象模式

    前言 在上一篇中我们学习了行为型模式的备忘录模式(Memento Pattern)和状态模式(Memento Pattern).本篇则来学习下行为型模式的最后两个模式,观察者模式(Observer P ...

  2. Java进阶篇设计模式之九----- 解释器模式和迭代器模式

    前言 在上一篇中我们学习了行为型模式的责任链模式(Chain of Responsibility Pattern)和命令模式(Command Pattern).本篇则来学习下行为型模式的两个模式, 解 ...

  3. Java进阶篇设计模式之十三——观察者模式和空对象模式

    简介 观察者模式又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependents)模式. ...

  4. Java进阶篇设计模式之十一 ---- 策略模式和模板方法模式

    前言 在上一篇中我们学习了行为型模式的访问者模式(Visitor Pattern)和中介者模式(Mediator Pattern).本篇则来学习下行为型模式的两个模式,策略模式(Strategy Pa ...

  5. Java进阶篇设计模式之十二 ---- 备忘录模式和状态模式

    前言 在上一篇中我们学习了行为型模式的策略模式(Strategy Pattern)和模板模式(Template Pattern).本篇则来学习下行为型模式的两个模式,备忘录模式(Memento Pat ...

  6. Java进阶篇设计模式之一 ----- 单例模式

    前言 在刚学编程没多久就听说过设计模式的大名,不过由于当时还是个彻彻底底的菜鸟,并没有去触碰.直到在开始工作中对简单的业务代码较为熟悉之后,才正式的接触设计模式.当时最早接触的设计模式是工厂模式,不过 ...

  7. Java基础篇--设计模式

    目录 前言 设计模式 创建型模式 单例模式 工厂方法模式 抽象工厂模式 建造者模式 原型模式 结构型模式 适配器模式 桥接模式 组合模式 装饰模式 外观模式 亨元模式 代理模式 行为型模式: 访问者模 ...

  8. Java设计模式之创建型:原型模式

    一.什么是原型模式: 原型模式主要用于对象的创建,使用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.UML类图如下: 原型模式的核心是就是原型类 Prototype,Prototype ...

  9. Java进阶之设计模式正则表达式

    Java进阶之设计模式&正则表达式 一.设计模式 1.1 设计模式概述 1.2 单例模式 1.2.1 单例模式衍生--多例模式 1.2.2 单例模式衍生--枚举 1.3 工厂模式 二.正则表达 ...

  10. Java设计模式(工厂模式>抽象工厂模式和原型模式)

    Java设计模式Ⅱ 1.工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 2.抽象工厂模式 3.总结 4.原型模式 4.1 原型模式 4.2 浅拷贝 4.3 深拷贝 5.建造者模式 1.工厂模式 ...

最新文章

  1. html 样式的几种实现方法
  2. 企业智能化升级之路:CSDN《2017-2018中国人工智能产业路线图V1.0》重磅发布
  3. 虚拟机用户配置root权限
  4. Jmeter之解决烦人的中文乱码问题
  5. mysql 强制索引循序_mysql 强制走索引
  6. java学习笔记30(IO :缓冲流)
  7. PAT 1079. Total Sales of Supply Chain
  8. 如何应对云爆发架构?四种方法替你解忧
  9. 点击打印出现IE已经阻止此站点用不安全方式使用 ActiveX 控件解决方
  10. 使用DistroTweaks复制您的自定义Linux设置
  11. 【识记】Nginx 访问控制
  12. python网络通信传输的数据类型_Python网络编程中的网络数据和网络错误。
  13. 用python把excel中的数据变成字典(复制代码即可用)
  14. 嵌入式和fpga哪个好前景_二建考试选哪个专业比较好?其市场需求和就业前景如何? - 二级建造师...
  15. Android BroadcastReceiver(二)
  16. 锂电池充电管理芯片ic XSC01支持筋膜枪8.4V12.6V16.8充电
  17. android 定位 指南针,Android 实现指南针效果
  18. 计算机强制关机后无法正常启动,电脑强制关机后无法正常启动,一直黑屏,这是为什么呢?...
  19. 最近公共祖(LCA)模板_祖先深度_区域祖先_(欧拉序列+标准RMQ+四毛子)O(n)-O(1)
  20. Chromium Portable实时更新github下载 最新版本Chromium Portable(谷歌浏览器) 下载

热门文章

  1. [转] 基于C#的波形显示控件的实现
  2. Oracle 12C -- native left outer join的加强
  3. 在线编程 - PyPool小站启动记
  4. asterisk app命令中文翻译
  5. .net框架笔记(四)
  6. 4月28日上午学习日志
  7. ZH奶酪:PHP中添加HTML代码的三种方法
  8. hybris Models
  9. C# 将已有程序封装为DLL文件,供其他程序调用
  10. 接口返回buffer的16进制数据如何转换