行为型设计模式应用(二)
一、题目要求
- 绘制和撤销圆点使用命令模式;
- 两个标签内容的变更使用观察者模式;
- 在代码实现之前,进行UML类图设计;
- 根据类图,编程实现程序的功能。
二、实现过程及步骤
制作如图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用于记录鼠标的位置。
行为型设计模式应用(二)相关推荐
- 中介者模式 调停者 Mediator 行为型 设计模式(二十一)
中介者模式(Mediator) 调度.调停 意图 用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散 而且可以独立地改变它们之间的交互. 中介者模式又 ...
- 模板方法模式 Template method 行为型 设计模式(二十六)
模板方法模式 Template method 上图为网上百度的一份简历模板截图 相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为你的 ...
- 观察者模式 Observer 发布订阅模式 源 监听 行为型 设计模式(二十三)
观察者模式 Observer 意图 定义对象一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并自动更新. 别名:依赖(Dependents),发布订阅(Publish-Su ...
- 备忘录模式 Memento 快照模式 标记Token模式 行为型 设计模式(二十二)
备忘录模式 Memento 沿着脚印,走过你来时的路,回到原点. 苦海翻起爱恨 在世间难逃避命运 相亲竟不可接近 或我应该相信是缘份 一首<一生所爱>触动了多少人的心弦,一段五百年都没有结 ...
- C#设计模式之二十职责链模式(Chain of Responsibility Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第八个模式,该模式是[职责链模式],英文名称是:Chain of Responsibility Pattern.让我们看看现实生活中的例 ...
- C#设计模式之二十一访问者模式(Visitor Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第九个模式,该模式是[访问者模式],英文名称是:Visitor Pattern.如果按老规矩,先从名称上来看看这个模式,我根本不能获得任 ...
- 设计模式(二)—— 创建型模式
设计模式(二)-- 创建型模式 文章首发于 掘金 作者:MiyueFE 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 创建型模式,即处理对象创建过程的设计模式,根据实际情况来使 ...
- 设计模式(二)——创建型模式
目录 一.简单工厂模式 二.工厂方法 三.抽象工厂 四.单例模式 五.原型模式 六.建造者模式(生成器模式) 创建型设计模式: 即处理对象创建过程的设计模式,根据实际情况来使用合适的模式创建对象.创建 ...
- Java设计模式(二)创建型设计模式
文章目录 三 创建型设计模式 3.1 单例设计模式 3.1.1 饿汉式(线程安全) 3.1.2 懒汉式(线程不安全) 3.1.3 优缺点 3.1.4 补充 3.1.5 框架中的使用 3.1.4.1 S ...
- 二、java设计模式之工厂方法+抽象工厂模式(创建型设计模式)
创建型设计模式-工厂模式和应用 工厂模式介绍: 它提供了一种创建对象的最佳方式,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象 例子: 需要购买一辆车,不用管 ...
最新文章
- AI科技大本营招实习生了!
- Android用户界面开发(16):ImageSwitcher
- 各个系统动态多路径软件识别LUN的方法
- Vue是如何渲染页面的,渲染过程以及原理代码
- Yii的应用主体的配置
- 精通JavaScript攻击框架:AttackAPI
- ShuffleNet论文阅读笔记
- efcore 新特性 SaveChanges Events
- [汇编语言]常用命令
- java查询多条_Mybatis查询多条记录并返回List集合的方法
- 数据分析:为什么说Python比Excel更简单高效 ?
- java 多线程两种方式_JAVA多线程实现的两种方式
- [原创]web application中使用Profile应该注意的问题
- golang 格式化时间成datetime
- cdh用户权限_CDH6.3.2之Sentry权限管理(三)
- iOS包重签名工具,ipa文件重签名,快速签名,SignTool签名工具,好用的签名工具,App重签名
- 细分领域:偏门的色流玩法+简单的色流变现套路
- 聊一聊以前公司的测试流程
- 根据计算机配置设置bios,设置BIOS让计算机每天都按时自动开机
- windows 上Miktex的镜像源最新配置方法
热门文章
- 如何设计扩展操作码--应用
- 末日要塞找不到服务器,末日要塞攻略 末日要塞流程攻略
- redis源码分析之ae_select.c
- 特斯拉大裁员,苹果赢麻了?维基百科:我的每一条引用都AI过;面向工业落地的目标检测框架;我的『粗野主义』操作系统;MLOps概览 | ShowMeAI资讯日报
- 微信小程序走工行聚合支付
- 鸿蒙火龙第十六季,传奇火龙攻略(鸿蒙火龙传奇霸业游戏攻略)
- MATLAB | App Designer·我用MATLAB制作了一款LATEX公式实时编辑器
- 【存储技术分享】SGL和SGE
- [导入]自己编写QQ挂机软件--基于HTTP的QQ协议之我所见
- 做什么副业挣钱快?2021有哪些挣钱的副业?