1700482750
1700482751
//修改后的产品
1700482752
1700482753
p.setName(name);
1700482754
1700482755
}
1700482756
1700482757
//获得是否可以创建一个产品
1700482758
1700482759
public boolean isCreateProduct(){
1700482760
1700482761
return isPermittedCreate;
1700482762
1700482763
}
1700482764
1700482765
//克隆一个产品
1700482766
1700482767
public Product clone(Product p){
1700482768
1700482769
//产生克隆事件
1700482770
1700482771
return p.clone();
1700482772
1700482773
}
1700482774
1700482775
}
1700482776
1700482777
仔细看看工厂类,产品的创建、修改、遗弃、克隆方法都很简单,但有一个方法可不简单——isCreateProduct方法,它的作用是告诉产品类“我是能创建产品的”,注意看我们的程序,在工厂类ProductManager中定义了一个私有变量isCreateProduct,该变量只有在工厂类的createProduct函数中才能设置为true,在创建产品的时候,产品类Product的构造函数要求传递工厂对象,然后判断是否能够创建产品,即使你想使用类似这样的方法:
1700482778
1700482779
Product p=new Product(new ProductManager(),“abc”);
1700482780
1700482781
也是不可能创建出产品的,它在产品类中限制必须是当前有效工厂才能生产该产品,而且也只有有效的工厂才能修改产品,看看产品类的canChanged属性,只有它为true时,产品才可以修改,那怎么才能为true呢?在构造函数中判断是否可以为true。这就类似工厂要创建产品了,产品就问“你有权利创建我吗?”于是工厂类出示了两个证明材料证明自己可以创建产品:一个是“我是你的工厂类”,二是“我的isCreateProduct返回true,我有权创建”,于是产品就被创建出来了。这种一个对象只能由固定的对象初始化的方法就叫做单来源调用(Single Call)——很简单,但非常有用的方法。
1700482782
1700482783
注意 采用单来源调用的两个对象一般是组合关系,两者有相同的生命期,它通常适用于有单例模式和工厂方法模式的场景中。
1700482784
1700482785
我们继续往下分析,一个产品新建要触发事件,那事件是什么?当然也是一个对象了,需要把它设计出来,仅仅有事件还不行,还要考虑有人去处理这个事件,产生了一个事件不可能没有对象去处理吧?如果是这样那事件还有什么意义呢?既然要去处理,那就需要一个通知渠道了,于是观察者模式准备好了。好,我们把这段分析的类图也画出来,如图36-2所示。
1700482786
1700482787
1700482788
1700482789
1700482790
图36-2 观察者模式处理事件
1700482791
1700482792
在该类图中,观察者为EventDispatch类,它使用了单例模式,避免对象膨胀,但同时也带来了性能及线程安全隐患,这点需要大家在实际应用中注意(想想Spring中的Bean注入,默认也是单例,在通常的应用中一般不需要修改,除非是较大并发的应用)。我们来看代码,先来看事件类型定义,它是一个枚举类型,如代码清单36-3所示。
1700482793
1700482794
代码清单36-3 事件类型定义
1700482795
1700482796
public enum ProductEventType{
1700482797
1700482798
//新建一个产品
1700482799
[
上一页 ]
[ :1.70048275e+09 ]
[
下一页 ]