一、题目要求

  1. 绘制和撤销圆点使用命令模式;
  2. 两个标签内容的变更使用观察者模式;
  3. 在代码实现之前,进行UML类图设计;
  4. 根据类图,编程实现程序的功能。

二、实现过程及步骤

制作如图1所示GUI界面,需求如下:
1.鼠标左键点击界面时,在鼠标所在位置填充一个直径为20像素的圆,并在界面上方的标签上显示“新增圆点位于:(x,y)”;
2.鼠标右键点击时,则实现undo操作,将最后填充的圆点从界面中删除,并在界面上方的标签上显示“删除圆点位于:(x,y)”; 3界面下方的标签随时显示“鼠标位于:(x,y)”;

(1)命令模式及观察者模式设计:

  • 首先设计一个Circle类,该类对象用来记录鼠标位置以及圆的位置信息,每填充一个圆点,就实例化一个Circle类对象,并将其放置到具体命令对象关联的List对象中,用来作为undo操作的依据;
  • 然后设计一个Command抽象命令类,里面包含execute和undo抽象方法,具体命令LeftCommand类实例化Command类,在LeftCommand类中实现对填充以及删除圆点的具体操作,然后设计一个接受者类Receive,它是真正执行命令的对象,Invoker类用于命令对象执行请求,这是客户端真正出发命令并要求命令执行相应操作的地方。
  • 再设计一个抽象观察者Observer类,里面定义抽象方法update类,然后设计两个具体观察者类ConcreteObserver和ConcreteObserver2,ConcreteObserver类用于记录新增及删除的圆点位置,ConcreteObserver2类用于记录鼠标的位置;
  • 再设计一个被观察者的抽象类Subject,里面包含两个抽象方法addObserver和deleteObserver,最后设计一个具体被观察者类去实现者两个抽象方法。

(2)UML类图如下:

(3)运行结果如下:

1)增加圆点时:

2)删除圆点时:

(4)主要代码入下:

Circle类

package demo4;public class Circle {private int x;private int y;public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public Circle(int x, int y) {this.x = x;this.y = y;}
}

Command抽象命令类

package demo4;import javax.swing.*;public interface Command {void execute(JPanel jPanel, Circle circle);void undo(JPanel jPanel);
}

具体命令LeftCommand类

package demo4;import javax.swing.*;
import java.util.ArrayList;public class LeftCommand implements Command {private Receiver receiver;private ArrayList<Circle> arrayList;private ConcreteOfInvoke concreteOfInvoke;public LeftCommand(Receiver receiver, ArrayList<Circle> arrayList, ConcreteOfInvoke concreteOfInvoke) {this.receiver = receiver;this.arrayList = arrayList;this.concreteOfInvoke = concreteOfInvoke;}@Overridepublic void execute(JPanel jPanel, Circle circle) {receiver.addSpot(jPanel, circle);arrayList.add(circle);}@Overridepublic void undo(JPanel jPanel) {Circle circle;if (arrayList.size() >= 1) {circle = arrayList.get(arrayList.size() - 1);receiver.deleteSpot(jPanel, circle);arrayList.remove(arrayList.size() - 1);int n = 2;concreteOfInvoke.notifyObservers(n, circle.getX(), circle.getY());}}
}

接受者类Receive

package demo4;import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;public class Receiver {private Graphics2D graphics2D;public void addSpot(JPanel jPanel,Circle circle) {Shape shape = new Ellipse2D.Double(circle.getX()-10,circle.getY()-10,20,20);graphics2D = (Graphics2D) jPanel.getGraphics();graphics2D.setPaint(Color.BLACK);graphics2D.fill(shape);}public void deleteSpot(JPanel jPanel, Circle circle) {Shape shape = new Ellipse2D.Double(circle.getX()-10,circle.getY()-10,20,20);graphics2D = (Graphics2D) jPanel.getGraphics();graphics2D.setPaint(jPanel.getBackground());graphics2D.fill(shape);}
}

用于命令对象执行请求Invoker类

package demo4;import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;public class Invoke extends JPanel {private Command command;private ConcreteOfInvoke concreteOfInvoke;public Invoke(Command command, ConcreteOfInvoke concreteOfInvoke) {this.command = command;this.concreteOfInvoke = concreteOfInvoke;this.addMouseListener(new Mouse());this.addMouseMotionListener(new MouseMotion());}class Mouse implements MouseListener {@Overridepublic void mouseClicked(MouseEvent arg0) {executeCommand(arg0);}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}}class MouseMotion implements MouseMotionListener {@Overridepublic void mouseDragged(MouseEvent e) {}@Overridepublic void mouseMoved(MouseEvent arg0) {int n = 0;concreteOfInvoke.notifyObservers(n,arg0.getX(), arg0.getY());}}public void executeCommand(MouseEvent mouseEvent) {int x = mouseEvent.getX();int y = mouseEvent.getY();Circle circle = new Circle(x, y);if (mouseEvent.getButton() == mouseEvent.BUTTON1) {this.command.execute(this,circle);int n = 1;concreteOfInvoke.notifyObservers(n,mouseEvent.getX(),mouseEvent.getY());} else if (mouseEvent.getButton() == mouseEvent.BUTTON3) {this.command.undo(this);}}
}

抽象观察者Observer类

package demo4;public interface Observer {void update(int n, int x, int y);
}

两个具体观察者类ConcreteObserver和ConcreteObserver2(此处只列举ConcreteObserver)

package demo4;import javax.swing.*;public class ConcreteObserver extends JLabel implements Observer {public ConcreteObserver() {super("新增圆点位于:(0,0)");}@Overridepublic void update(int n, int x, int y) {if (n == 1) {this.setText("新增圆点位于:(" + x + "," + y + ")");} else if (n == 2) {this.setText("删除圆点位于:(" + x + "," + y + ")");}}
}

被观察者的抽象类Subject

package demo4;public interface Subject {void addObserver(Observer observer);void deleteObserver(Observer observer);
}

三、出现的问题及解决方案

开始时只设计了一个具体观察者类ConcreteObserver,用于记录圆点的位置,最后发现不满足实验要求,缺少记录鼠标位置的类,又添加了一个ConcreteObserver2用于记录鼠标的位置。

行为型设计模式应用(二)相关推荐

  1. 中介者模式 调停者 Mediator 行为型 设计模式(二十一)

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

  2. 模板方法模式 Template method 行为型 设计模式(二十六)

    模板方法模式 Template method 上图为网上百度的一份简历模板截图 相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为你的 ...

  3. 观察者模式 Observer 发布订阅模式 源 监听 行为型 设计模式(二十三)

    观察者模式 Observer 意图 定义对象一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并自动更新. 别名:依赖(Dependents),发布订阅(Publish-Su ...

  4. 备忘录模式 Memento 快照模式 标记Token模式 行为型 设计模式(二十二)

    备忘录模式 Memento 沿着脚印,走过你来时的路,回到原点. 苦海翻起爱恨 在世间难逃避命运 相亲竟不可接近 或我应该相信是缘份 一首<一生所爱>触动了多少人的心弦,一段五百年都没有结 ...

  5. C#设计模式之二十职责链模式(Chain of Responsibility Pattern)【行为型】

    一.引言 今天我们开始讲"行为型"设计模式的第八个模式,该模式是[职责链模式],英文名称是:Chain of Responsibility Pattern.让我们看看现实生活中的例 ...

  6. C#设计模式之二十一访问者模式(Visitor Pattern)【行为型】

    一.引言 今天我们开始讲"行为型"设计模式的第九个模式,该模式是[访问者模式],英文名称是:Visitor Pattern.如果按老规矩,先从名称上来看看这个模式,我根本不能获得任 ...

  7. 设计模式(二)—— 创建型模式

    设计模式(二)-- 创建型模式 文章首发于 掘金 作者:MiyueFE 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 创建型模式,即处理对象创建过程的设计模式,根据实际情况来使 ...

  8. 设计模式(二)——创建型模式

    目录 一.简单工厂模式 二.工厂方法 三.抽象工厂 四.单例模式 五.原型模式 六.建造者模式(生成器模式) 创建型设计模式: 即处理对象创建过程的设计模式,根据实际情况来使用合适的模式创建对象.创建 ...

  9. Java设计模式(二)创建型设计模式

    文章目录 三 创建型设计模式 3.1 单例设计模式 3.1.1 饿汉式(线程安全) 3.1.2 懒汉式(线程不安全) 3.1.3 优缺点 3.1.4 补充 3.1.5 框架中的使用 3.1.4.1 S ...

  10. 二、java设计模式之工厂方法+抽象工厂模式(创建型设计模式)

    创建型设计模式-工厂模式和应用 工厂模式介绍: 它提供了一种创建对象的最佳方式,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象 例子: 需要购买一辆车,不用管 ...

最新文章

  1. AI科技大本营招实习生了!
  2. Android用户界面开发(16):ImageSwitcher
  3. 各个系统动态多路径软件识别LUN的方法
  4. Vue是如何渲染页面的,渲染过程以及原理代码
  5. Yii的应用主体的配置
  6. 精通JavaScript攻击框架:AttackAPI
  7. ShuffleNet论文阅读笔记
  8. efcore 新特性 SaveChanges Events
  9. [汇编语言]常用命令
  10. java查询多条_Mybatis查询多条记录并返回List集合的方法
  11. 数据分析:为什么说Python比Excel更简单高效 ?
  12. java 多线程两种方式_JAVA多线程实现的两种方式
  13. [原创]web application中使用Profile应该注意的问题
  14. golang 格式化时间成datetime
  15. cdh用户权限_CDH6.3.2之Sentry权限管理(三)
  16. iOS包重签名工具,ipa文件重签名,快速签名,SignTool签名工具,好用的签名工具,App重签名
  17. 细分领域:偏门的色流玩法+简单的色流变现套路
  18. 聊一聊以前公司的测试流程
  19. 根据计算机配置设置bios,设置BIOS让计算机每天都按时自动开机
  20. windows 上Miktex的镜像源最新配置方法

热门文章

  1. 如何设计扩展操作码--应用
  2. 末日要塞找不到服务器,末日要塞攻略 末日要塞流程攻略
  3. redis源码分析之ae_select.c
  4. 特斯拉大裁员,苹果赢麻了?维基百科:我的每一条引用都AI过;面向工业落地的目标检测框架;我的『粗野主义』操作系统;MLOps概览 | ShowMeAI资讯日报
  5. 微信小程序走工行聚合支付
  6. 鸿蒙火龙第十六季,传奇火龙攻略(鸿蒙火龙传奇霸业游戏攻略)
  7. MATLAB | App Designer·我用MATLAB制作了一款LATEX公式实时编辑器
  8. 【存储技术分享】SGL和SGE
  9. [导入]自己编写QQ挂机软件--基于HTTP的QQ协议之我所见
  10. 做什么副业挣钱快?2021有哪些挣钱的副业?