23种设计模式(第二部分): 1.建造者模式(包含简介相关代码示例) 2. 原型模式(相关代码,思想学习)

it2025-12-28  11

一. 建造者模式

建造者模式也属于创建型模式,他提供了一种创建对象的最佳方式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象用户只要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)例子 工厂(建造者模式): 负责制作汽车(组装过程和细节在工厂里面)汽车购买者(用户): 你只需要说出你需要的型号(对象的类型和内容),然后直接购买就可以使用了,(不需要知道汽车是怎么组装的(车轮,车门,发动机,方向盘等))

角色分析:

既然是建造者模式,那么我们还是继续造房子,假设造房简化为如下步骤: 1.地基,2.钢筋工程,3.铺电线,4.粉刷:如果要盖一座房子,首先要找一个建筑公司或者工程承包商(指挥者),承包商指挥工人(具体建造者)过来造房子(产品),最后验收.

代码实现:

Builder:

package com.qiu.builder; /** * @author qiuzhikang */ //抽象的建造者 public abstract class Builder { //具体的步骤 //地基 abstract void buildeA(); //钢筋工程 abstract void buildeB(); //铺电线 abstract void buildeC(); //粉刷 abstract void buildeD(); //完工:得到产品 abstract Product getProduct(); }

Director:

package com.qiu.builder; //指挥:核心,负责和指挥构建一个工程,工程如何构建,由它决定 /** * @author qiuzhikang */ public class Director { //指挥工人按照顺序建房子 public Product build(Builder builder){ builder.buildeA(); builder.buildeB(); builder.buildeC(); builder.buildeD(); return builder.getProduct(); } }

Product:

package com.qiu.builder; /** * @author qiuzhikang */ //产品:房子 public class Product { private String buildeA; private String buildeB; private String buildeC; private String buildeD; @Override public String toString() { return "Product{" + "buildeA='" + buildeA + '\'' + ", buildeB='" + buildeB + '\'' + ", buildeC='" + buildeC + '\'' + ", buildeD='" + buildeD + '\'' + '}'; } public String getBuildeA() { return buildeA; } public void setBuildeA(String buildeA) { this.buildeA = buildeA; } public String getBuildeB() { return buildeB; } public void setBuildeB(String buildeB) { this.buildeB = buildeB; } public String getBuildeC() { return buildeC; } public void setBuildeC(String buildeC) { this.buildeC = buildeC; } public String getBuildeD() { return buildeD; } public void setBuildeD(String buildeD) { this.buildeD = buildeD; } }

Worker:

package com.qiu.builder; /** * @author qiuzhikang */ //具体的建造者 public class Worker extends Builder{ private Product product; public Worker(){ product = new Product(); } @Override void buildeA() { product.setBuildeA("地基"); System.out.println("地基"); } @Override void buildeB() { product.setBuildeB("钢筋工程"); System.out.println("钢筋工程"); } @Override void buildeC() { product.setBuildeC("铺电线"); System.out.println("铺电线"); } @Override void buildeD() { product.setBuildeD("粉刷"); System.out.println("粉刷"); } @Override Product getProduct() { return product; } }

Test:

package com.qiu.builder; public class Test { public static void main(String[] args) { //指挥 Director director = new Director(); //指挥具体的工厂完成产品 Product build = director.build(new Worker()); System.out.println(build.toString()); } }

运行演示:

上面的实例是builder模式的常规用法,导演类Director在Builder模式中具有很重要的作用,它用于指导具体构建这如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把Director和抽象建造者进行结合

通过静态内部类的方式实现零件无序装配构造,这种方式使用更加灵活,更加符合定义,内部有复杂对象的默认实现,使用时可以根据用户需求自由定义更改内容,并且无需改变具体的构造方式,就可以生产出不同的复杂产品

比如:麦当劳的套餐,服务员(具体建造者)可以随意搭配几种产品(零件)组成一款套餐(产品),然后销售给客户,比第一种方式少了指挥者,主要是因为第二种方式把指挥者交给用户来操作,是的产品的创建更加简单灵活

二. 原型模式

克隆 文件A变成文件B.就是一个copy的过程,而这个A就是原型. 原型模式就是以某个点为原型,后来有些相同的点就只需要拷贝,修改,提高效率 package com.qiu.prototype; import java.util.Date; /** * 1.实现一个接口,cloneable * 2.重写一个方法 * @author qiuzhikang */ public class Video implements Cloneable{ //克隆别人的视频,假如说这是一个原型 private String name; private Date createTime; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } 下面getset,tostring,package com.qiu.prototype; import java.util.Date; /** * 克隆 */ public class BiliBili { public static void main(String[] args) throws CloneNotSupportedException { Date date = new Date(); Video video = new Video("qiuzhikang",date); Video video2 = (Video)video.clone(); System.out.println("video -> "+video); System.out.println("video=>hash"+video.hashCode()); System.out.println("video2 -> "+video2); System.out.println("video2=>hash"+video2.hashCode()); System.out.println("=========================================="); //video2.setName("chengxiaocong"); //当video的时间改了之后,但是两个时间都是一样的的,说明这是一个浅克隆 date.setTime(65161313L); System.out.println("video -> "+video); System.out.println("video=>hash"+video.hashCode()); System.out.println("video2 -> "+video2); System.out.println("video2=>hash"+video2.hashCode()); } /* //video 克隆 video2 //1. Video video2 = new Video("qiuzhikang",date); Video video2 = (Video)video.clone(); video2.setName("chengxiaocong"); System.out.println("video2 -> "+video2); System.out.println("video2=>hash"+video2.hashCode()); */ }

我们会发现,这里的video和video2的时间是一样的 所以就存在一个问题就是,虽然是克隆出来的,但是他们的date指的是同一个引用.所以我们称之为浅克隆

也就是下图的这个:

如果说要转成深克隆的方式的话,我们可以这么做.

@Override protected Object clone() throws CloneNotSupportedException { Object obj = super.clone(); //实现深克隆的一种方式,除此之外就是Io的 Video v = (Video) obj; //将这个对象的属性也进行克隆 v.createTime = (Date) this.createTime.clone(); return obj; }

代码演示: 这样就实现了深克隆.像我们的springBean中:单例模式,原型模式.

最新回复(0)