首页 > 其他分享 >【设计模式】原型模式:猴头,我叫你一声你敢答应吗?

【设计模式】原型模式:猴头,我叫你一声你敢答应吗?

时间:2022-11-21 11:00:48浏览次数:53  
标签:克隆 对象 猴头 Monkey String 原型 设计模式 public monkey


1 原型模式

1.1 概述

原型模式是一种对象创建型模式,用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。原型模式允许一个对象再创建另外一个可定制的对象,无须知道任何创建的细节。

原型模式的基本工作原理是通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象复制原型来实现创建过程。

1.2 结构

原型模式包含三个角色:

  • 抽象原型类:规定了具体原型对象必须实现的clone()方法。
  • 具体原型类:实现抽象原型类的clone方法,它是可被复制的对象。
  • 访问类:使用具体原型类中的clone()方法来复制新的对象。

1.3 用例图

【设计模式】原型模式:猴头,我叫你一声你敢答应吗?_软件工程

2 例子

2.1 浅克隆

2.1.1 解释

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本数据类型属性,仍指向原有属性所指向的对象的内存地址。

Java的基本数据类型有8种,分别是:byte(位)、short(短整数)、int(整数)、long(长整数)、float(单精度)、double(双精度)、char(字符)和boolean(布尔值),那么除此之外的数据类型就是非基本数据类型。

这段话的意思是,如果你克隆的对象里面不含有基本数据类型,那么你克隆的对象2和原来的对象指向同一个地址,一个对象里面的值会随着另一个对象的改变而改变。

这很容易让我们想到西游记里的一个例子:

“猴头,我叫你一声你敢答应吗?”

【设计模式】原型模式:猴头,我叫你一声你敢答应吗?_原型模式_02

银角大王和孙悟空酣战,孙悟空不敌,于是又幻化成者行孙、行者孙前来挑战,不管是者行孙、孙行者、还是行者孙都是孙悟空被尊,所以每一个角色被抓,都意味着真正的孙悟空被抓住了。这和浅克隆非常的类似。

2.1.2 代码

在这个例子里,抽象原型类是就是Cloneable接口,具体原型类就是Monkey类(孙悟空类),至于访问类就是Qazxcdew类(银角大王类)

/* 孙悟空 */
public class Monkey implements Cloneable{
/* 猴子的姓名 */
private String monkeyName;
/* 猴子的情况 */
private Status status = new Status();

public String getMonkeyName() {
return monkeyName;
}

public void setMonkeyName(String monkeyName) {
this.monkeyName = monkeyName;
}

public Status getStatus() {
return status;
}

public void setStatus(Status status) {
this.status = status;
}

/* 我叫你一声你敢答应吗? */
public void call()
{
System.out.println(monkeyName+",我叫你一声你敢答应吗?");
}
/* 回应 */
public void respond()
{
System.out.println("爷爷在此~"+status.getAction());
}

@Override
protected Monkey clone() throws CloneNotSupportedException {
return (Monkey)super.clone();
}
}

状态类

public class Status {
String action;

public String getAction() {
return action;
}

public void setAction(String action) {
this.action = action;
}

@Override
public String toString() {
return "Status{" +
"action='" + action + '\'' +
'}';
}
}

银角大王类

public class Qazxcdew {
public static void main(String[] args) throws CloneNotSupportedException {
/* 1、创建原型对象:孙行者 */
/* 猴子本尊*/
Monkey monkey = new Monkey();
monkey.setMonkeyName("孙行者");
monkey.getStatus().setAction("孙悟空跑掉了");
/* 2、猴子克隆对象 */
/* 者姓孙 */
Monkey monkey1 = monkey.clone();
/* 行者孙 */
Monkey monkey2 = monkey.clone();

monkey1.setMonkeyName("者姓孙");
monkey2.setMonkeyName("行者孙");

monkey1.getStatus().setAction("孙悟空打赢了");
monkey2.getStatus().setAction("孙悟空被抓了");

/* 3、展示对象 */
monkey.call();
monkey.respond();
monkey1.call();
monkey1.respond();
monkey2.call();
monkey2.respond();
System.out.println((monkey==monkey1)+":"+(monkey==monkey2));

}
}

2.1.3 效果图

【设计模式】原型模式:猴头,我叫你一声你敢答应吗?_软件工程_03

为什么先是孙行者逃走了、再是者姓孙打赢了、最后行者孙被抓了,最终的结果却变成了孙行者、者行孙、行者孙都被抓了呢?

这和浅克隆就非常的相似,浅克隆是指的克隆的非基本类型和原型共用一个值,一个改变其他的也都改变。

而行者孙、者行孙、孙行者都是孙悟空一个猴,所以行者孙最后被抓了,也就意味着其他的三个都被抓了。

2.2 深克隆

2.2.1 解释

深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不在指向原有对象地址。

这句话的意思是:深克隆的对象,除了值和原来的一样,其他没有任何关系。

这也可以让我们想到《西游记》里的一个例子:孙悟空吹猴毛

【设计模式】原型模式:猴头,我叫你一声你敢答应吗?_设计模式_04

2.2.2 代码

银角大王类

public class Qazxcdew {
public static void main(String[] args) throws CloneNotSupportedException {
/* 1、创建原型对象:孙行者 */
/* 猴子本尊*/
Monkey monkey = new Monkey();
monkey.setMonkeyName("孙行者");
monkey.getStatus().setAction("孙悟空跑掉了");
/* 2、猴子克隆对象 */
/* 者姓孙 */
Monkey monkey1 = monkey.clone();
/* 行者孙 */
Monkey monkey2 = monkey.clone();

monkey1.setMonkeyName("孙悟空一号");
monkey2.setMonkeyName("孙悟空二号");

monkey1.getStatus().setAction(monkey1.getMonkeyName()+"打赢了");
monkey2.getStatus().setAction(monkey2.getMonkeyName()+"被抓了");


/* 3、展示对象 */
monkey.call();
monkey.respond();
monkey1.call();
monkey1.respond();
monkey2.call();
monkey2.respond();
System.out.println((monkey==monkey1)+":"+(monkey==monkey2));

}
}

孙悟空类

/* 孙悟空 */
public class Monkey implements Cloneable{
/* 猴子的姓名 */
private String monkeyName;
/* 猴子的情况 */
private Status status = new Status();

public String getMonkeyName() {
return monkeyName;
}

public void setMonkeyName(String monkeyName) {
this.monkeyName = monkeyName;
}

public Status getStatus() {
return status;
}

public void setStatus(Status status) {
this.status = status;
}

/* 我叫你一声你敢答应吗? */
public void call()
{
System.out.println(monkeyName+",我叫你一声你敢答应吗?");
}
/* 回应 */
public void respond()
{
System.out.println("爷爷在此~"+status.getAction());
}

@Override
protected Monkey clone() throws CloneNotSupportedException {

Object object = super.clone();
Monkey m = (Monkey)object;
/* 将属性也克隆一遍 */
m.status = (Status) this.status.clone();


return m;
}
}

状态类

public class Status implements Cloneable{
String action;

public String getAction() {
return action;
}

public void setAction(String action) {
this.action = action;
}

@Override
public String toString() {
return "Status{" +
"action='" + action + '\'' +
'}';
}

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

2.2.3 效果图

【设计模式】原型模式:猴头,我叫你一声你敢答应吗?_软件工程_05

猴毛脱离猴子身上之后,就变成了一个独立的个体,虽然幻化出来的猴子和孙悟空有着相同的特点、属性,但是猴毛怎么样,和孙悟空是无关的。

2.2.4 深克隆的方法

  1. 序列化、反序列化
  2. 克隆的时候,连同属性一块克隆(本例使用,方便实现)

3 优缺点

3.1 优点

  • 创建新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程。通过一个已有实例可以提高新实例的创建效率;
  • 可以动态增加或减少产品类;
  • 提供了简化的创建结构;
  • 可以用深克隆的方式保存对象的状态

3.2 缺点

  • 需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行全盘考虑。
  • 改造已有的类变得复杂,而且需要改变其源代码,违法了开闭原则。
    怎么样,和孙悟空是无关的。


标签:克隆,对象,猴头,Monkey,String,原型,设计模式,public,monkey
From: https://blog.51cto.com/u_15807146/5873037

相关文章

  • 设计模式
    一、创建型模式01.简单工厂模式抽象产品类:将要批量生产的对象实体进行一个抽象提取,便于扩展更多实体,比如手机类;具体产品类:继承抽象产品,将产品实例化。比如小米手机、......
  • 设计模式学习篇-Observer观察者模式
    观察者模式:定义对象间一对多相依关系;使得每当一个对象改变状态则其相关的对象皆得到通知并自动更新。本质:触发联动。属于行为模式。观察者(Observer)模式又名发布-订阅(Publish......
  • 谈谈我工作中的23个设计模式
      序从基础的角度看,设计模式是研究类本身或者类与类之间的协作模式,是进行抽象归纳的一个很好的速成思路。后面阅读设计模式后,为了加深理解,对相关图片进行了描绘和微......
  • 【博学谷学习记录】超强总结,用心分享 | 单例设计模式总结
    单例设计模式单例模式(SingletonPattern)涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不......
  • Java进阶篇——设计模式
    设计模式一、代理模式使用代理类对真实对象进行代理,包括真实对象方法的调用、功能的扩展等。访问的时候也只能访问到代理对象,既保护了真实对象同时可以在原始对象上进行......
  • 04.从架构层面看设计模式(2)
                                     ......
  • 软件设计模式白话文系列(十三)模版方法模式
    1、模式描述模版方法模式属于类行为型模式,在父类中定义业务框架,并将某些步骤的实现延迟到子类实现,允许子类在不影响框架接口的的情况下,重写某些步骤。2、模式结构模版......
  • 03.从架构层面看设计模式(1)
                                工厂模式底层就是if判断然后创建不同的产品           ......
  • 前端设计模式
    1.什么是设计模式?设计模式是一套被反复使用、多数人知晓、经过分类编目的、代码设计经验的总结。它是为了可重用代码,让代码更容易的被他人理解并保证代码的可靠性。就像......
  • 软件设计模式白话文系列(十二)组合模式
    1、模式描述组合模式属于结构型模式,把多个对象组成树状结构来表示局部与整体,这样用户可以以相同的方式对待单个对象和组合对象。需要注意的是这里的组合和之前系列中,我们......