设计模式自学笔记007_Real(命令模式、备忘录模式、桥接模式)

一、命令模式

在软件设计的过程中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道请求的操作是哪个。我们只需要在程序运行的时候指定具体的请求接收者即可,此时,可以使用命令模式进行设计。

命令模式使得请求发送者与请求接收者解除彼此的耦合关系,让对象之间的调用关系更加灵活,实现解耦。

在命令模式中,会将一个请求封装为一个对象,以便使用不同的参数来表示不同的请求,同时命令模式也必须支持支持撤销的操作。

Invoker是调用者,Receiver是被调用者,MyCommand是命令,实现了Command接口,持有接收对象。


那么我们现在举一个例子,用遥控器打开和关闭电视,分别有两个按钮,一个是打开电视的按钮,一个是关闭电视的按钮。然后我们要让遥控器遍的可以拓展,就是遥控器上可以有别的按钮,能够打开和关闭其他的电器。代码如下:

//命令接口类
public interface Command {void execute();void undo();
}
public class TVReceiver {public void on(){System.out.println("电视打开了");}public void off(){System.out.println("电视关闭了");}
}
//打开电视的实现类
public class TVOnCommand implements Command{private TVReceiver tvReceiver;public TVOnCommand(TVReceiver tvReceiver) {this.tvReceiver = tvReceiver;}@Overridepublic void execute() {tvReceiver.on();}@Overridepublic void undo() {tvReceiver.off();}
}
//关闭电视的实现类
public class TVOffCommand implements Command{private TVReceiver tvReceiver;public TVOffCommand(TVReceiver tvReceiver) {this.tvReceiver = tvReceiver;}@Overridepublic void execute() {tvReceiver.off();}@Overridepublic void undo() {tvReceiver.on();}
}
//空命令实现类,用于按钮的初始化
public class NoCommand implements Command{@Overridepublic void execute() {}@Overridepublic void undo() {}
}
//遥控器的类
public class RemoteController {private Command[] OnCommands;private Command[] OffCommands;//执行后撤销操作的命令Command undoCommand;public RemoteController() {OnCommands = new Command[5];OffCommands = new Command[5];for(int i = 0; i < OnCommands.length; i++){OnCommands[i] = new NoCommand();OffCommands[i] = new NoCommand();}}//给每一个按钮设置需要的命令public void setCommand(int no, Command onCommand, Command offCommand){OnCommands[no] = onCommand;OffCommands[no] = offCommand;}//按下开的按钮,则打开电视public void OnButtonClicked(int no){OnCommands[no].execute();//同时记录下这个按钮,以便之后进行撤销操作undoCommand = OnCommands[no];}//按下关的按钮,则关闭电视public void OffButtonClicked(int no){OffCommands[no].execute();//同时记录下这个按钮,以便之后进行撤销操作undoCommand = OffCommands[no];}//按下撤销按钮,进行操作的撤销public void undoButtonClicked(){undoCommand .undo();}
}
public class Client {public static void main(String[] args) {//创建电视的对象TVReceiver TV = new TVReceiver();//创建打开和关闭电视机的按钮对象TVOnCommand tvOnButton = new TVOnCommand(TV);TVOffCommand tvOffButton = new TVOffCommand(TV);//创建遥控器的对象RemoteController controller = new RemoteController();//给遥控器设置按键,假设第一个按键时关于电视的controller.setCommand(0, tvOnButton, tvOffButton);//遥控器的使用//打开电视controller.OnButtonClicked(0);//关闭电视controller.OffButtonClicked(0);//撤销操作controller.undoButtonClicked();}
}

总结:
(1)将发送请求的对象和执行请求的对象解耦,发起请求的对象时调用者,调用者只要调用命对象的excute()方法就可以让接收者工作,而不必知道具体的接收者对象是谁,是如何实现的,命令对象会负责让接收者执行请求的命令。
(2)容易设置一个命令队列,只要把,命令对象放到队列中,就可以多线程的执行命令。
(3)容易实现请求的撤销和重做。
(4)不足:很容易让系统中出现较多的具体命令类使得系统变得极其复杂。
(5)空命令也是一种设计模式,他为我们省去了判空的操作。

二、原型设计模式(克隆对象)

在软件设计中,有的时候我们需要用到多个相同的实例化对象,那么原型设计模式就是用用原型实例指定创建对象的种类,并且通过拷贝这些圆形,创建新的对象。

原型设计模式是一种创建型设计模式,允许一个对象再创建一个可定制的对象,无需知道任何创建的细节。

原理:通过将一个原型对象穿个那个发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝他们自己来实施创建

那么假设我们现在有一只羊,我们想要克隆四只一样的羊的话,应该让羊的类事先CloneAble接口,重写Clone()方法来实现,代码如下:

public class Sheep implements Cloneable{private String name;private int age;private String color;public Sheep(String name, int age, String color) {this.name = name;this.age = age;this.color = color;}@Overridepublic String toString() {return "Sheep{" +"name='" + name + '\'' +", age=" + age +", color='" + color + '\'' +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}@Overrideprotected Object clone(){Sheep sheep = null;try {sheep = (Sheep) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return sheep;}
}public class ProtoTypeDesign1 {public static void main(String[] args) {Sheep sheep = new Sheep("多利", 5, "黑色");Sheep sheep2 = (Sheep)sheep.clone();Sheep sheep3 = (Sheep)sheep.clone();Sheep sheep4 = (Sheep)sheep.clone();Sheep sheep5 = (Sheep)sheep.clone();System.out.println("sheep1 = "+sheep);System.out.println("sheep2 = "+sheep2);System.out.println("sheep3 = "+sheep3);System.out.println("sheep4 = "+sheep4);System.out.println("sheep5 = "+sheep5);}
}输出结果:
sheep1 = Sheep{name='多利', age=5, color='黑色'}
sheep2 = Sheep{name='多利', age=5, color='黑色'}
sheep3 = Sheep{name='多利', age=5, color='黑色'}
sheep4 = Sheep{name='多利', age=5, color='黑色'}
sheep5 = Sheep{name='多利', age=5, color='黑色'}

注意:
原型设计模式会涉及浅拷贝问题,我们如果要做到深拷贝就必须重写Clone()方法,将被拷贝的类中的类变量也要进行拷贝,或者利用序列六的方式进行深拷贝。

三、备忘录模式

在不破坏封装性的前提下,捕获一个对象的内部状态,并在对象之外保存这个状态,这样以后就可以将该对象恢复到原先保存的状态

备忘录设计模式属于行为设计模式

Originator:对象(需要保存的状态的对象)
Memento:备忘录对象,负责保存好记录,即Originator内部状态
CareTaker:守护者对象,负责保存多个备忘录对象,使用集合管理,提高效率
如果希望保存多个对象的不同时间的状态,只需要用HashMap<String, 集合>

四、桥接设计模式

在程序设计中,有的时候会出现一簇类需要调用另一簇类的情况,比如说卖手机,有线下实体店渠道和线上电商渠道两种方式进行售卖,二手机的型号也有多种,比如华为、苹果、小米手机,我们线上和线下都能卖这三种产品,那么如果直接用者两个销售渠道类直接调用三个手机类的话,那么就需要有六种不同的情况,可能需要写六个不同的类来实现,那么现在我们利用桥接设计模式,创建一个销售渠道抽象类,让线上和线下重写抽象类的方法,然后我们再设置一个手机接口类,让三种手机类实现这个接口,然后我们再抽象类中传入手机接口,将两者连接起来,这样就能在需要的时候直接用抽象类创建销售渠道,再将实现接口类的手机类传入销售渠道类中,大大降低代码的书写量。

桥接模式是指将实现与抽象分离开,放在两个不同类的层次中,是两个层次可以独立改变
是一种结构型设计模式
Bridge模式基于类的最小数量设计原则,通过使用封装,聚合及继承等行为让不同的类承担不同的职责,他的主要特点就是把抽象与行为实现分离开来,从而可以保持各部分独立以及应对他们的功能拓展。

那么举个例子:现在有三种手机,直板、翻盖、触屏,有三个品牌的手机,华为,小米,苹果,那么每一种品牌都发布了这三种手机,现在每一种手机都要实现打开机、电话两个功能,那么具体的实现如下:

public interface BrandPhone {void Call();void Open();
}
public class HuaWei implements BrandPhone{@Overridepublic void Call() {System.out.println("用华为为手机打电话");}@Overridepublic void Open() {System.out.println("打开华为手机");}
}
public class Apple implements BrandPhone{@Overridepublic void Call() {System.out.println("用苹果手机打电话");}@Overridepublic void Open() {System.out.println("打开苹果手机");}
}
public class XiaoMi implements BrandPhone{@Overridepublic void Call() {System.out.println("用小米手机打电话");}@Overridepublic void Open() {System.out.println("打开小米手机");}
}
public abstract class Phone {private BrandPhone phone;public Phone(BrandPhone phone) {this.phone = phone;}public BrandPhone getPhone() {return phone;}
}
public class ZhiBan extends Phone{public ZhiBan(BrandPhone phone) {super(phone);}@Overridepublic BrandPhone getPhone() {return super.getPhone();}
}
public class FanGai extends Phone{public FanGai(BrandPhone phone) {super(phone);}@Overridepublic BrandPhone getPhone() {return super.getPhone();}
}
public class ZhiNeng extends Phone{public ZhiNeng(BrandPhone phone) {super(phone);}@Overridepublic BrandPhone getPhone() {return super.getPhone();}
}
public class BridgeDesign1 {public static void main(String[] args) {Phone phone = new ZhiBan(new HuaWei());phone.getPhone().Open();phone.getPhone().Call();phone = new FanGai(new Apple());phone.getPhone().Open();phone.getPhone().Call();phone = new ZhiNeng(new XiaoMi());phone.getPhone().Open();phone.getPhone().Call();}
}
输出结果:
打开华为手机
用华为为手机打电话
打开苹果手机
用苹果手机打电话
打开小米手机
用小米手机打电话

设计模式自学笔记007_Real(命令模式、备忘录模式、桥接模式)相关推荐

  1. 路由WDS 中继模式Repeater和桥接模式Bridge的区别,同时WDS对网速的影响

    WDS (Wireless Distribution System)无线分布式系统,是无线连接两个接入点(AP)的协议.在整个WDS无线网络中,把多个AP通过桥接或中继器的方式连接起来,使整个局域网络 ...

  2. 【设计模式实践笔记】第一节:工厂方法模式

    前言 工作有段时间了,一直没有把自己所知所想沉淀下来,想趁着重新学习设计模式的机会,记录一些自己的心得体会. 大学里也有学过设计模式,那会没有实际的项目经验,感触不是很深,工作以后跟人讨论设计模式,有 ...

  3. 图解Java设计模式学习笔记——结构型模式(适配器模式、桥接模式、装饰者模式、组合模式、外观模式、享元模式、代理模式)

    一.适配器模式(类适配器.对象适配器.接口适配器) 1.现实生活中的例子 泰国插座用的是两孔的(欧标),可以买个多功能转换插头(适配器),这样就可以使用了国内的电器了. 2.基本介绍 适配器模式(Ad ...

  4. 《javascript设计模式》笔记之第七章:工厂模式

    在读了这章之后,根据我个人现在的理解,工厂模式就是:将一个类或者一个方法称为一个工厂,然后再将一些模块交给这个工厂,让这个工厂按照给它的不同模块产出不同的实例. 下面为正文: 一:简单工厂: 例子: ...

  5. CSharp设计模式读书笔记(18):中介者模式(学习难度:★★★☆☆,使用频率:★★☆☆☆)...

    中介者模式(Mediator Pattern):用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互,中介者模式又称为 ...

  6. 6中结构型设计模式的对比理解(Composite组合模式,Proxy代理模式,Flyweight享元模式,Facade门面模式,Bridge桥接模式,Decorator装饰器模式)

    结构型模式 结构型模式用来组装 类和对象,以获得更大的结构. 结构型类模式,通过继承机制来组合接口或类.简单的例子就是多重继承,最后一个类拥有所有父类的性质.这个模式有助于独立开发一个协同类.另一个例 ...

  7. java 桥接模式_《JAVA与模式》之桥接模式

    桥接模式是一种结构型模式,它主要应对的是:由于实际的需要,某个类具有两个或两个以上的维度变化,如果只是用继承将无法实现这种需要,或者使得设计变得相当臃肿. 桥接模式的做法是把变化部分抽象出来,使变化部 ...

  8. 设计者模式详解--桥接模式

    1. 概述 将抽象部分(Abstraction)与实现部分(Implementor)分离,使它们可以独立地变化. 2. 解决的问题 在软件系统中,有些类型由于自身的逻辑,它具有两个或多个维度的变化.为 ...

  9. VMware下网络配置三种模式对比(桥接模式,主机模式,网络地址转换)

    1 VMware三种网络模式简介 VMWare提供了三种工作模式,它们是bridged(桥接模式).NAT(网络地址转换模式)和host-only(主机模式).安装好虚拟机以后,在网络连接里面可以看到 ...

最新文章

  1. 哈佛博士生教你轻松愉快地读博
  2. 主程序与子程序不在同一程序模块中_深度解析S7200系列PLC带参数子程序用法
  3. python 折线图x时间_在Python Bokeh折线图中设置日期/时间轴上的比例
  4. mysql 查看集群状态_MySQL数据库集群正确配置步骤
  5. vue中的slot插槽
  6. Squid服务日志分析
  7. arcgis出界址点成果表_界址点成果表打印
  8. Laravel服务提供器
  9. 拖动窗体FormBorderStyle属性为None的窗体移动
  10. js并列排名之div图片加载
  11. 电子签章系统如何无代码接入第三方应用
  12. (译)BPF技巧和窍门:bpf_trace_printk() 和 bpf_printk() 指南
  13. 电摩测试速度什么软件,速度最快的4款新电动车,你更看好谁?为什么呢?
  14. java刷票脚本_我来分享一段自己写的刷票脚本 Version 1.0
  15. 自写自用的移动小程序故障管理扫码报修系统
  16. 试卷模板 html,一年级语文试卷模板
  17. 建诗筑画 文/奥斯·科特林
  18. 如何立即尝试macOS High Sierra Beta
  19. 2021年电工(初级)考试及电工(初级)报名考试
  20. Word中如何把同一级编号一次性上升或下降一级或任意级,做到随意调整编号层级?

热门文章

  1. ubuntu16.04或者win10解压alz文件的方法
  2. JS函数封装三个例子
  3. PB 导入Excel文件并操作数据
  4. php 除法,php除法函数有哪些
  5. 第4章 - Java面向对象
  6. 微信小程序 | 基于ChatGPT实现模拟面试小程序
  7. php 检查磁盘,window_Win7系统中关闭检查磁盘和扫描并修复提示的方法, Win7系统关闭“检查磁盘r - phpStudy...
  8. 埃隆马斯克_埃隆·穆斯克(Elon Mussk)正在创造网络猪
  9. Lifelong SLAM 论文解读合集(2):针对长时间重复运行SLAM地图更新问题
  10. 微信公众号添加图片链接