昨天懈怠了,没有写什么内容!
今天主要还是想写设计模式: 在阅读源码的过程中我们会接触到越来越多的设计模式,所以我觉得是时候来认真的来写一写了!
今天主要完成的是: 事件触发器的测试,就是相当于我们自己设计了一个框架来专门完成触发器这个功能!
首先我列出元模型,然后我在后面一节会根据这个模型进行改编成浏览器中大量出现的或者swing中也大量出现的事件类型,例如按钮事件:点击、释放等
然后这个按钮是通过工厂模式进行创建,因为事件是以一个具体的存在的对象为前提的!
接着我们使用了观察者模式,通知多个观察者(如果观察者观察到了主题的变化);因为我们一般是定义单一处理事件,所以加入的中介者模式进行事件处理级别的处理;
①分析:
产品: 事件源(例如按钮)
产品创建工厂: 事件源的生产者
产品事件类型: 枚举(定义事件源产生的事件种类)
事件类型(相当于主题,继承了Observable):如果事件源发生了某种事件,那么就进行通知观察者进行相应的处理
事件转发器(相当于观察者,实现了Observer接口):如果接受到了变化就进行update();
后面部分:因为我们规定了具体的事件处理逻辑,我们使用了中介者模式,
事件消费类型: 事件消费类型和事件源发生的事件类型相对应;
抽象的事件消费者: 对某个事件有具体的处理逻辑;这里的某个事件就是事件类型,就是对事件进行声明式的逻辑处理
具体的事件消费者(继承了抽象的事件消费者):例如:平民修改一个产品、贵族克隆一个产品、乞丐销毁一个产品
具体的代码分析如下:
①首先是产品类:
package java20180227;
public class Product implements Cloneable{
private String name;
private boolean canChanged = false;
public Product(ProductManager productManager, String name) {
if(productManager.getCreateProduct()) {
this.canChanged = true;
this.name = name;
}
}
protected Object clone() throws CloneNotSupportedException {
Product product = null;
try {
product = (Product) super.clone();
} catch (Exception e) {
e.printStackTrace();
}
return product;
}
public String getName() {
return name;
}
public void setName(String name) {
if(canChanged) {
this.name = name;
}
}
}
②接着是产品管理类:(主要用来生成一个产品相关的事件,产品就是事件源)
package java20180227;
/**
* 事件 和 产品 : 通过产品管理者进行桥梁进行关联
* @author dudu
*/
public class ProductManager {
//是否可以创建一个产品
private boolean isPermittedCreate = false;
//建立一个产品
public Product createProduct(String name) {
isPermittedCreate = true;
Product product = new Product(this, name);
//产生一个创建事件:
new ProductEvent(product, ProductEventType.NEW_PRODUCT);
return product;
}
/**废弃一个产品**/
public void abandonProduct(Product product) {
//销毁一个产品,例如删除数据库记录
//产生删除事件
new ProductEvent(product, ProductEventType.DEL_PRODUCT);
product = null;
}
/**修改一个产品**/
public void editProduct(Product product, String name) {
product.setName(name);
//产生修改事件: 这里加入产品事件类型就是为了方便扩展
new ProductEvent(product, ProductEventType.EDIT_PRODUCT);
}
/**克隆**/
public Product clone(Product product) {
try {
new ProductEvent(product, ProductEventType.CLOEN_PRODUCT);
return (Product) product.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
public boolean getCreateProduct() {
return isPermittedCreate;
}
}
③目前的产品事件类型类:
package java20180227;
/**
* @author dudu
* 这里的产品事件类型多一个值就可以相对应的多一个事件触发类型
*/
public enum ProductEventType {
NEW_PRODUCT(1),
DEL_PRODUCT(2),
EDIT_PRODUCT(3),
CLOEN_PRODUCT(4);
private int value = 0;
private ProductEventType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
④产品具体事件 继承 主题 Obervable:
package java20180227;
import java.util.Observable;
/**
* 继承主题类
* @author dudu
*/
public class ProductEvent extends Observable {
//事件起源
private Product source;
//事件的类型: 类似就是事件改变类型: 也就是事件注册者
private ProductEventType type;
//传入事件的源头,默认为新建类型
public ProductEvent(Product product) {
// this.ProductEvent(product, ProductEventType.NEW_PRODUCT);
this(product, ProductEventType.NEW_PRODUCT);
}
//事件源头以及事件类型
public ProductEvent(Product product, ProductEventType type) {
this.source = product;//产品就是事件源
this.type = type;
//触发事件 : 新建事件之后进行通知
notifyEventDispatch();
}
//获得事件的始作俑者
public Product getSource() {
return source;
}
//获得事件的类型
public ProductEventType getEventType() {
return this.type;
}
//通知事件中心: 根据不同的情况进行通知,但是不在这里实现
private void notifyEventDispatch() {
super.addObserver(EventDispatch.getDispatch());//观察者就是事件类型 : 通过事件分发者:(中介者模式)
super.setChanged();//是否修改: 这个修改时通知观察者的一个条件
super.notifyObservers(source);//通知观察者
//update是交给观察者自己去实现的
}
}
⑤观察者 实现了 Observer 观察者接口 :
具体的观察者逻辑: 注册观察者(这里使用具体事件消费者来进行替代)、update具体的事件处理相应的逻辑
package java20180227;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
/**
* 单例模式
* @author dudu
*/
public class EventDispatch implements Observer {
//单例模式
private final static EventDispatch dispatch = new EventDispatch();
//事件消费者
private Vector<EventCustomer> customers = new Vector<EventCustomer>();
//不允许生成新的实例
private EventDispatch() {}
//获得单例对象
public static EventDispatch getDispatch() {
return dispatch;
}
//事件触发
public void update(Observable o, Object object) {
System.out.println("这里定义事件触发的效果");
//事件源头
Product product = (Product) object;
//事件
ProductEvent event = (ProductEvent) o;
//处理者处理,这里是中介模式的核心,可以是很复杂的业务逻辑
for(EventCustomer e : customers) {
//处理能力是否匹配
for(EventCustomType ect : e.getCustomTypeVector()) {
if(ect.getValue() == event.getEventType().getValue()) {
e.exec(event);//执行处理事件
}
}
}
}
//注册事件的处理者
public void registerCustomer(EventCustomer customer) {
customers.add(customer);
}
}
⑥事件消费者类型:
package java20180227;
/**
* @author dudu
*/
public enum EventCustomType {
NEW(1),
DEL(2),
EDIT(3),
CLONE(4);
private int value = 0;
private EventCustomType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
⑦抽象的事件消费者: 定义了消费者的处理级别,同时也能在中介者模式中充当一个容器的作用,先保存事件消费类型,又定义了事件声明式消费方法
package java20180227;
import java.util.Vector;
/**
* @author dudu
*/
public abstract class EventCustomer {
//容纳每个消费者能够处理的级别
private Vector<EventCustomType> customTypeVector = new Vector<EventCustomType>();
//每个消费者都要声明自己处理哪一类别的事件
public EventCustomer(EventCustomType type) {
addCustomType(type);
}
//每个消费者可以消费多个事件
public void addCustomType(EventCustomType type) {
customTypeVector.add(type);
}
//得到自己的处理能力
public Vector<EventCustomType> getCustomTypeVector() {
return customTypeVector;
}
//每个事件都要对事件进行生命式消费
public abstract void exec(ProductEvent event);
}
⑧具体的消费者实现类:
package java20180227;
public class Commoner extends EventCustomer {
//定义平民能够处理的事件的级别
public Commoner() {
super(EventCustomType.NEW);
}
@Override
public void exec(ProductEvent event) {
//事件源头
Product product = event.getSource();
//事件类型
ProductEventType type = event.getEventType();
System.out.println("平民处理事件: " + product.getName() + "诞生记, 事件类型 = " + type);
}
}
⑨
package java20180227;
public class NobleMan extends EventCustomer {
//定义贵族能够处理的事件的级别
public NobleMan() {
super(EventCustomType.EDIT);
super.addCustomType(EventCustomType.CLONE);
}
@Override
public void exec(ProductEvent event) {
//事件的源头
Product product = event.getSource();
//事件类型
ProductEventType type = event.getEventType();
if(type.getValue() == EventCustomType.CLONE.getValue()) {
System.out.println("贵族处理事件: " + product.getName() + "克隆, 事件类型 = " + type);
} else {
System.out.println("贵族处理事件: " + product.getName() + "修改, 事件类型 = " + type);
}
}
}
10: 简单的测试:
package java20180227;
/**
* @author dudu
*
*/
public class Client {
public static void main(String[] args) {
//获得事件分发中心
EventDispatch dispatch = EventDispatch.getDispatch();
//接受平民对事件的处理
dispatch.registerCustomer(new Commoner());
//接受贵族对事件的处理
dispatch.registerCustomer(new NobleMan());
//建立一个原子弹生产工厂
ProductManager factory = new ProductManager();
//制造一个产品
System.out.println("=====模拟创建产品事件======");
System.out.println("创建一个叫做小男孩的原子弹");
Product p = factory.createProduct("小男孩原子弹");
//修改一个产品
System.out.println("\n=====模拟修改产品事件======");
System.out.println("把小男孩原子弹修改为胖子号原子弹");
factory.editProduct(p, "胖子号原子弹");
//再克隆一个原子弹
System.out.println("\n=====模拟修改克隆产品事件======");
System.out.println("克隆胖子号原子弹");
factory.clone(p);
//遗弃一个产品
System.out.println("\n=====模拟销毁产品事件======");
System.out.println("销毁胖子号原子弹");
factory.abandonProduct(p);
}
}
个人总结: 目前对模式的理解还是不够,虽然模拟着原代码写了一遍,感觉上还是无法在脑海中形成架构!
继续加油!!!