[19/04/24-星期三] GOF23_创建型模式(建造者模式、原型模式)

一、建造者模式

本质:分离了对象子组件的单独构造(由Builder负责)和装配的分离(由Director负责),从而可以构建出复杂的对象,这个模式适用于:某个对象的构建过程十分复杂

好处:由于构建和装配的解耦,不同的构建器和相同的装配可以做出不同的对象,相同的构建器和不同装配顺序也可以组成不同的对象,实现了构建算法和装配算法的解耦,

实现了更好的复用。

【基本模块】

/**** "宇宙飞船"类*/
package cn.sxt.builder;public class Airship {private OrbitalModule orbitalModule;//轨道仓模块private Engine engine;//发动机模块private EscapeTower escapeTower;//逃逸塔模块public OrbitalModule getOrbitalModule() {return orbitalModule;}public void setOrbitalModule(OrbitalModule orbitalModule) {this.orbitalModule = orbitalModule;}public Engine getEngine() {return engine;}public void setEngine(Engine engine) {this.engine = engine;}public EscapeTower getEscapeTower() {return escapeTower;}public void setEscapeTower(EscapeTower escapeTower) {this.escapeTower = escapeTower;}public String toString() {String msg="配置:["+orbitalModule.getName()+engine.getName()+escapeTower.getName()+"]";return msg;}public void launch() {System.out.println(engine.getName()+"点火,5,4,3,2,1,发射!");}
}class OrbitalModule{//"轨道仓"类private String name;public OrbitalModule(String name) {this.name=name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}class Engine{//"发动机"类private String name;public Engine(String name) {this.name=name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}class EscapeTower{//"逃逸塔"类private String name;public EscapeTower(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}    
}

 

【建造者和装配者】接口

/**** "建造类"接口,提供构建3个子类的方法*/
package cn.sxt.builder;public interface AirshipBuilder {OrbitalModule builderOrbitalModule();cn.sxt.builder.Engine builderEngine();EscapeTower builderEscapeTower();
}/**** "装配类"接口, Director:导演,负责人*/
package cn.sxt.builder;public interface AirShipDirector {Airship directorAirship();//组装飞船对象

}

【建造者和装配者】具体实现类

/**** "神7飞船"子组件的建造者*/
package cn.sxt.builder;public class S7AirShipBuilder implements AirshipBuilder { //XML解析中,JDOM库中的类:DOMBuilder也是建造者模式public OrbitalModule builderOrbitalModule() {    System.out.println("--制造天宫牌轨道仓--");return new OrbitalModule("天宫牌轨道仓 ");}public Engine  builderEngine() {System.out.println("--制造盘古牌发动机--");return new Engine("盘古牌发动机 ");    }public EscapeTower builderEscapeTower() {System.out.println("--制造曹操牌逃逸塔--");return new EscapeTower("曹操牌逃逸塔");}}
/**** "神7飞船"装配者*/
package cn.sxt.builder;public class S7AirShipDirector implements AirShipDirector{private AirshipBuilder builder;//要装配的对象,要装配什么组件public S7AirShipDirector(AirshipBuilder builder) {this.builder = builder;}public Airship directorAirship() {OrbitalModule oModule=builder.builderOrbitalModule();Engine engine=builder.builderEngine();EscapeTower eTower=builder.builderEscapeTower();//获得各个组件
        Airship ship=new Airship();//一个具体的飞船对象
        ship.setOrbitalModule(oModule);ship.setEngine(engine);ship.setEscapeTower(eTower);return ship;}}

【客户端】

/**** 客户端*/
package cn.sxt.builder;public class Test_0424_Client {public static void main(String[] args) {AirshipBuilder builder=new S7AirShipBuilder();//飞船建造者AirShipDirector director=new S7AirShipDirector(builder);//飞船装配者
        Airship s7ship=director.directorAirship();System.out.println(s7ship);s7ship.launch();}}

 

二、原型模式(克隆模式、原型模式。prototype:原型、雏形)

    通过new产生一个对象需要非常繁琐的数据准备或者访问权限,则可以使用原型模式。JavaScript中的继承中使用过。

    就是Java中的克隆技术,以某个对象为原型。new创建新的对象采用默认值。克隆出的对象的属性值完全和原型相同,并且克隆出的新对象改变不会影响原型对象。

然后,再修改克隆对象的值。

 实现:通过Cloneable接口和clone方法,帮我们进行内存的复制操作。常常与工厂模式结合起来

用途:如果短时间需要创建大量对象,并且new的时候比较耗时间,可以用原型模式,效率大概是普通方法的100倍

【原型羊】

/**** 原型"羊"类*/
package cn.sxt.prototype;
import java.util.Date;public class Sheep implements Cloneable {private String name;private Date birthday;@Override //重写父类中的clone方法protected Object clone() throws CloneNotSupportedException {Object obj=super.clone();//直接调用Object类对象的clone方法/*    //添加如下代码2行实现深克隆Sheep s=(Sheep)obj;s.birthday=(Date)this.birthday.clone();//把属性(出生日期)也进行克隆
*/        return obj;}public Sheep() {super();}public Sheep(String name, Date birthday) {super();this.name = name;this.birthday = birthday;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}}

【克隆羊】

/*** 测试取克隆一只"羊"(浅克隆和深克隆)*/
package cn.sxt.prototype;import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;public class Test_0424_Client01 {public static void main(String[] args) throws Exception {Date date=new Date(1000000L);Sheep s1=new Sheep("羊一代",date);//要克隆出新羊,需要原型"羊",这就是原型"羊"
        System.out.println(s1);System.out.println(s1.getName());System.out.println(s1.getBirthday());Sheep s2=(Sheep)s1.clone();//新建一个对象,但不是通过new,而是直接调用原型"羊"的clone方法System.out.println(s2);//输出结果显示s1与s2对象在内存中的值不同,但是属性信息等一模一样
        System.out.println(s2.getName());System.out.println(s2.getBirthday());s2.setName("羊二代");//修改s2的属性值,完全不影响s1的值
        System.out.println(s2.getName());//修改原型"羊"的出生日期,看看克隆羊的出生日期/**    浅克隆:把原型羊的出生日期改了,但是影响克隆羊的出生日期*  深克隆:把原型羊的出生日期改了,但是不影响克隆羊的出生日期* 原理:* 浅克隆:s1----->data对象<-----s2(s1和s2的出生日期均执行同一时间对象data,s1一改动,s2也受影响)* 深克隆:s1----->data对象。data对象的复制品<-----s2,s1改动与s2没有关系,s2的出生日期不会动* */date.setTime(40000000L);System.out.println(s1.getBirthday());System.out.println(s2.getBirthday());}
}

 【深克隆方式之二】

/**** 用序列化和反序列化实现深克隆*/
package cn.sxt.prototype;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;public class Test_0424_Client02 {public static void main(String[] args) throws Exception {Date date=new Date(1000000L);Sheep s1=new Sheep("羊一代",date);//要克隆出新羊,需要原型"羊",这就是原型"羊"
        System.out.println(s1);System.out.println("原型羊:"+s1.getBirthday());//Sheep s2=(Sheep)s1.clone();//新建一个对象,但不是通过new,而是直接调用原型"羊"的clone方法//深克隆方法之二:使用序列化和反序列化克隆一只羊ByteArrayOutputStream bos=new ByteArrayOutputStream();ObjectOutputStream oos=new ObjectOutputStream(bos);oos.writeObject(s1);byte[] buf=bos.toByteArray();ByteArrayInputStream bis=new ByteArrayInputStream(buf);ObjectInputStream ois=new ObjectInputStream(bis);Sheep s2=(Sheep)ois.readObject();System.out.println(s2);System.out.println("克隆羊:"+s2.getBirthday());//修改原型"羊"的出生日期,看看克隆羊的出生日期date.setTime(40000000L);System.out.println("修改原型羊的出生日期后:");System.out.println("原型羊:"+s1.getBirthday());System.out.println("克隆羊:"+s2.getBirthday());}}

 

转载于:https://www.cnblogs.com/ID-qingxin/p/10749672.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249091.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解vue中的slot与slot-scope

写在前面 vue中关于插槽的文档说明很短&#xff0c;语言又写的很凝练&#xff0c;再加上其和methods&#xff0c;data&#xff0c;computed等常用选项在使用频率、使用先后上的差别&#xff0c;这就有可能造成初次接触插槽的开发者容易产生“算了吧&#xff0c;回头再学&#…

js 转义

1. JavaScript 特殊字符 2. 正反斜杠互相替换 a/b/c.replace(/\//g,\\) // "a\b\c" $0.value.replace(/\\/g,\/) // a/b/c 获取到 而不提取出 某个值后进行直接处理 \ 有转义功能&#xff0c;所以一旦解析必然转义&#xff0c;通常是直接获取到数据源…

关于Java抽象类,接口与实现接口及派生类继承基类

1. 抽象类 抽象类就是有一个或多个方法只被声明而未被实现。 抽象方法的声明以分号结束&#xff0c;并且用关键字abstract来说明它以标识它为抽象方法。 格式&#xff1a; public abstract class 类名{ 定义变量// 抽象方法// } 2. 接口是抽象类的一种&#xff0c;之包含常量…

ie兼容响应式布局的实现总结

虽然说响应式设计的理想状态是&#xff0c;需对pc/移动各种终端进行响应&#xff1b;但是现实是高分辨率的pc端与手机终端屏幕相差太大&#xff0c;像电商这样有大量图片和文字 信息的同时排版要求精准的页面&#xff0c;设计一个同时适应高分辨率pc又适合小尺寸的手机终端是挑…

Luogu P1471 方差

题目传送门 开了十倍空间才过是什么鬼&#xff1f;该不会我线段树炸了吧……细思极恐 平均数都会求&#xff0c;维护区间和&#xff0c;到时候除一下就好了。 方差的求法如下(用的Luogu的图片) 因为要维护一个平方&#xff0c;我们可以考虑使用van♂完全平方公式将它拆开&#…

python学习day17 递归函数

递归函数 http://www.cnblogs.com/Eva-J/articles/7205734.html def age(n):if n 4:return 40elif n >0 and n < 4:return age(n1) 2print(age(1)) # 46 只要写递归函数&#xff0c;必须要有结束条件。 二分法查找 l [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,5…

2018年最好用的20个Bootstrap网站模板

Bootstrap是目前最受欢迎也是最简洁的建站方式之一&#xff0c;尤其是伴随移动端的发展&#xff0c;响应式设计已经毫无疑问成为了网页设计的趋势&#xff0c;网站建设要求兼容手机端已经是一种刚需&#xff0c;也成为提升用户体验的一种必要方式。但这无疑会加大设计师和前端人…

bit、byte、位、字节、汉字、字符之间的区别

package com.suypower.chengyu.test; public class ByteTest { /** * byte 8 bits -128 - 127 * 1 bit 1 二进制数据 * 1 byte 8 bit * 1 字母 1 byte 8 bit(位) * 1 汉字 2 byte 16 bit */ public static void main(String[] args) { // TODO Auto-generated method st…

Android SDK 2.3/3.0/4.0/4.2 下载与安装教程

Eclipse下搭建Android开发环境教程&#xff1a;http://dev.son1c.com/show/1253.html Google已经发布了Android SDK 4.2版本.下面给朋友们介绍一下安装 Android 模拟器 Emulator模拟器的方法: 1、首先确定安装了Java JDK&#xff0c;如果没有&#xff0c;可以去http://www.ora…

PMP:4.项目整合管理

内容中包含 base64string 图片造成字符过多&#xff0c;拒绝显示转载于:https://www.cnblogs.com/mapanguan/p/9916902.html

浏览器渲染原理与过程

一、浏览器如何渲染网页 要了解浏览器渲染页面的过程&#xff0c;首先得知道一个名词——关键路径渲染。关键渲染路径&#xff08;Critical Rendering Path&#xff09;是指与当前用户操作有关的内容。例如用户在浏览器中打开一个页面&#xff0c;其中页面所显示的东西就是当前…

css框架:五大css流行框架的总结-css教程-PHP中文网

本篇文章给大家带来的内容是关于css框架&#xff1a;五大css流行框架的总结&#xff0c;有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对你有所帮助。 如今&#xff0c;CSS框架越来越受欢迎&#xff0c;可以说已经应用到每一个网站上了。作为开发工具…

第十四天

###数组&#xff1a;面向对象的方式创建&#xff1a;var arr01 new Array(1,2,3,"abc");直接创建&#xff1a;var arr02 [1,2,3,"abc"]alert (arr02.length);alert(arr02[3]);var arr03 [[1,2,3],["a","b","c","d&q…

【English Email】CIP payouts now in Workday

simplification简化的[ˌsɪmplɪfɪˈkeɪʃn] quota配额[ˈkwoʊtə] regional区域的[ˈriːdʒənl] mechanics技工[məˈknɪks] annual年度的 [ˈnjuəl] mid-year年中 [mɪd jɪr] bridge桥接[brɪdʒ] Incentive激励 [ɪnˈsentɪv] Due to the simplification of …

爬取网页的通用代码框架

import requests def getHTMLText(url)try:r requests.get(url,timeout30)r.raise_for_status()r.encoding r.apparent_encodingreturn r.textexcept:return "产生异常"if__name__ "__main__"url "http://www.baidu.com"print(getHTMLText(ur…

深入理解CSS盒模型 - 程序猿的程 - 博客园

深入理解CSS盒模型 本文是学习中传思客在慕课网开的课程《前端跳槽面试必备技巧》的学习笔记。课程地址&#xff1a;https://coding.imooc.com/class/evaluation/129.html#Anchor。 如果你在面试的时候面试官让你谈谈对盒模型的理解&#xff0c;你是不是不知从何谈起。这种看似…

蓝桥杯——机器人行走

某少年宫引进了一批机器人小车。可以接受预先输入的指令&#xff0c;按指令行动。小车的基本动作很简单&#xff0c;只有3种&#xff1a;左转&#xff08;记为L&#xff09;&#xff0c;右转&#xff08;记为R&#xff09;&#xff0c;向前走若干厘米&#xff08;直接记数字&am…

JavaWeb:脚本标识

脚本标识 一、JSP表达式 1、介绍 用于向页面中输出信息 2、语法格式 <% 表达式%>3、注意 在"<%"和""之间不允许有空格&#xff0c;但是在""后面的表达式之间可以有空格不仅可以插入到网页中&#xff0c;还可以插入到HTML标记中&#xf…

线程死锁问题

1 package com.demo.bingfa;2 3 /**4 * java并发编程中&#xff0c;死锁的概念5 *6 * 我们启用了两个线程&#xff0c;分别抢占2个资源&#xff0c;但这两个资源又分别被不同的对象&#xff08;字符串&#xff09;锁住了。7 * 当第一个线程调用 resource1 方法&#xff0c;…

CSS的4个简写

CSS的4个简写 2010-12-13 18:50 聂微东 阅读(1547) 评论(3) 编辑 收藏 1.background 简写属性在一个声明中设置所有的背景属性: background-colorbackground-imagebackground-repeatbackground-attachmentbackground-position 例如: background: #444444 url(image.png…