背景:
从最开始的开门小例子到后来的,使用C#事件与委托到java的事件与委托,老师针对发消息的人和收消息人的提出了监听器的概念,java的监听器是怎么实现的呢?是放置了两个空壳放置发消息的人和收消息的人。
过程
图:
讲完课以后
大概的图(这个还需要完善)
代码:
package 米老师讲的两个事件与委托2023年5月7日;
public class Client {
public static void main(String[] args) throws Exception {
Notice notice = new Notice();
notice.notice();
}
}
public class Notice {
public void notice() throws Exception {
Listener listener = new Listener();
listener.addRegister(new CatEvent(),new Cat("Tom"), "shout");
listener.addDelegate(new MouseEvent(),new Mouse("jerry"), "run");
listener.addDelegate(new MouseEvent(),new Mouse("jack"), "run");
listener.invoke();
}
}
public class Register {
protected Object obj;
protected String methodName;
protected Object[] methodParameter;
protected Class<?>[] methodType;
protected static List<Register> registerList=new ArrayList<>();
public Register(){}
public Register(Object obj, String methodName, Object... methodParameter) {
this.obj = obj;
this.methodName = methodName;
this.methodParameter = methodParameter;
int len = methodParameter.length;
this.methodType = new Class[len];
for (int i = 0; i < len; i++) {
methodType[i] = methodParameter[i].getClass();
}
}
public void invoke() throws Exception {
Method method = obj.getClass().getDeclaredMethod(methodName, methodType);
method.invoke(obj, methodParameter);
}
public void addRegister(Register register){
}
}```
```bash
public class CatEvent extends Register {
public CatEvent() {
super();
}
@Override
public void invoke() throws Exception {
for (Register d : registerList) {
d.invoke();
}
}
@Override
public void addRegister(Register delegate) {
System.out.println(delegate.toString());
registerList.add(delegate);
}
}
public class RegisterFather {
}
public class Cat extends RegisterFather {
private String name;
public Cat(String name){
this.name = name;
}
public void shout() {
System.out.println("我是"+name+",我来了");
}
}
public class Cat extends RegisterFather {
private String name;
public Cat(String name){
this.name = name;
}
public void shout() {
System.out.println("我是"+name+",我来了");
}
}
public class Delegate {
protected Object obj;
protected String methodName;
protected Object[] methodParameter;
protected Class<?>[] methodType;
protected static List<Delegate> delegateList=new ArrayList<>();
public Delegate(){}
public Delegate(Object obj, String methodName, Object... methodParameter) {
this.obj = obj;
this.methodName = methodName;
this.methodParameter = methodParameter;
int len = methodParameter.length;
this.methodType = new Class[len];
for (int i = 0; i < len; i++) {
methodType[i] = methodParameter[i].getClass();
}
}
public void invoke() throws Exception {
Method method = obj.getClass().getDeclaredMethod(methodName, methodType);
method.invoke(obj, methodParameter);
}
public void addDelegate(Delegate delegate){
}
}
public class MouseEvent extends Delegate{
public MouseEvent() {
super();
}
@Override
public void invoke() throws Exception {
for (Delegate d : delegateList) {
d.invoke();
}
}
@Override
public void addDelegate(Delegate delegate) {
System.out.println(delegate.toString());
delegateList.add(delegate);
}
public void delDelegate(Delegate delegate) {
delegateList.remove(delegate);
}
}
public class DelegateFather {
}
public class Mouse extends DelegateFather {
private String name;
public Mouse(String name){
this.name = name;
}
public void run(){
System.out.println("我是"+name+",我跑了");
}
}
2023年5月9日22:37:21
更加完善了一下图,抽象出来发消息和收消息的接口
2023年5月11日10:16:36
完善了一版抽象出来体现多态的接口,使用配置文件读取确定运行时传入什么
基于上一次
public class Notice {
public void notice() throws Exception {
// Listener listener = new Listener();
// MouseEvent mouseEvent = new MouseEvent();
//
// listener.addRegister(new CatEvent(),new Cat("Tom"), "shout");
// listener.addDelegate(mouseEvent,new Mouse("jerry"), "run");
// listener.addDelegate(mouseEvent,new Mouse("jack"), "run");
// listener.invoke();
Listener listener = new Listener();
CatEvent catEvent = new CatEvent();
MouseEvent mouseEvent = new MouseEvent();
Properties properties = new Properties();
properties.load(new FileInputStream("E:\\zy\\TGB-zgy-2022\\米老师设计模式课相关资料必须留着\\米老师设计模式课小例子\\JAVAtest\\entrust\\src\\main\\resources\\config.properties"));
String catPath = (String) properties.get("catPath");
String catMethod = (String) properties.get("catMethod");
String[] catList = properties.get("catList").toString().split(",");
String mousePath = (String) properties.get("mousePath");
String mouseMethod = (String) properties.get("mouseMethod");
String[] mouseList = properties.get("mouseList").toString().split(",");
for (String catName : catList) {
Object catInstance = Class.forName(catPath).getConstructor(String.class).newInstance(catName);
listener.addRegister(catEvent, (ISend) catInstance, catMethod);
}
for (String mouseName : mouseList) {
Object mouseInstance = Class.forName(mousePath).getConstructor(String.class).newInstance(mouseName);
listener.addDelegate(mouseEvent, (IReceive) mouseInstance, mouseMethod);
}
listener.invoke();
}
}
配置文件
catPath =end20230507.Cat
catMethod = send
catList = Tom,Tom4
mousePath =end20230507.Mouse
mouseMethod = receive
mouseList = Jerry,Ja
总结:
1加到n上是需要有n的前提的,知道java的监听器是怎么来的,将发消息和收消息的人进行匹配是在监听器中进行的,知道监听器是怎么来的,知其然,知其所以然。
设计模式的七大设计原则,也被称为SOLID原则,是一组面向对象设计的指导原则,旨在帮助开发者编写易于维护、扩展和理解的代码。下面是这些原则的概述以及它们的应用方式:
单一职责原则(Single Responsibility Principle - SRP): 一个类应该只有一个引起变化的原因。换句话说,一个类应该只有一个职责。这有助于保持代码的可维护性和理解性。
开闭原则(Open-Closed Principle - OCP): 软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。这意味着在增加新功能时,应该通过扩展现有代码而不是修改它来实现。
里氏替换原则(Liskov Substitution Principle - LSP): 子类应该能够替换掉父类并且不影响程序的正确性。这意味着子类应该保持父类的行为和约束。
接口隔离原则(Interface Segregation Principle - ISP): 不应该强迫客户端依赖它们不需要的接口。一个类不应该实现过多的接口,而应该将它们拆分为更小、更具体的接口。
依赖反转原则(Dependency Inversion Principle - DIP): 高层模块不应该依赖低层模块,它们应该依赖于抽象。同时,抽象不应该依赖于具体,而具体应该依赖于抽象。
这些原则的应用方式包括:
在设计和编写代码时,尽量遵循这些原则,以确保代码的质量、可维护性和可扩展性。
使用单一职责原则来确保每个类或模块只负责一个清晰的职责,从而降低类的复杂性。
使用开闭原则来设计可扩展的架构,通过抽象和接口定义来允许添加新功能而不影响现有代码。
遵循里氏替换原则来确保子类在替换父类时不会破坏系统的正确性。
使用接口隔离原则来设计细粒度、专注的接口,避免客户端依赖不需要的接口。
遵循依赖反转原则来解耦高层和低层模块之间的依赖关系,通过依赖注入等方式实现。
这些原则共同为面向对象的软件设计提供了指导,可以帮助开发者编写易于维护和扩展的高质量代码。
在Java中,监听(Listener)是一种用于捕获和响应事件的机制。它允许程序在特定事件发生时执行相应的操作,从而实现事件驱动的编程模型。常见的例子包括图形界面应用程序中的按钮点击、鼠标移动、键盘输入等事件。
要实现监听,通常需要以下几个步骤:
定义事件源(Event Source): 事件源是能够触发事件的对象,例如按钮、文本框、窗口等。事件源需要提供注册监听器的方法,通常以addXxxListener的形式命名,其中"Xxx"是事件类型。
创建监听器接口(Listener Interface): 监听器接口定义了处理特定事件的方法。每个事件类型都有对应的监听器接口,其中至少包含一个处理事件的方法。
实现监听器类(Listener Class): 实现监听器接口的类,具体实现监听器接口中的方法,以定义事件发生时的行为。
将监听器注册到事件源: 使用事件源的注册方法将监听器对象注册到事件源上,以便事件源能够通知监听器特定事件的发生。
事件触发: 当事件源上发生特定事件时,会调用相应事件类型的监听器方法,从而执行注册的监听器对象中的代码。
以下是一个简单的示例,展示如何在Java中实现监听器模式:
import java.awt.*;
import java.awt.event.*;
class ButtonClickListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Button Clicked!");
}
}
public class EventListenerExample {
public static void main(String[] args) {
Frame frame = new Frame("Listener Example");
Button button = new Button("Click Me");
ButtonClickListener listener = new ButtonClickListener();
button.addActionListener(listener);
frame.add(button);
frame.setSize(300, 200);
frame.setLayout(new FlowLayout());
frame.setVisible(true);
}
}
在上面的示例中,ButtonClickListener实现了ActionListener接口,定义了在按钮点击事件发生时的行为。在main方法中,我们创建了一个按钮,并将ButtonClickListener的实例作为监听器注册到按钮上。当按钮被点击时,注册的监听器方法actionPerformed会被调用,从而输出"Button Clicked!"。
请注意,Java中还有其他更高级的事件处理机制,如使用匿名内部类、Lambda表达式等来简化监听器的实现。此外,不同的框架和库可能会有自己的事件处理机制,但基本的监听器模式概念在各种情况下都是类似的。