您的位置:首页 > 编程语言 > Java开发

java之设计模式

2015-06-17 21:43 232 查看
一、代理模式

  a、抽象角色(接口):声明真实对象和代理对象的共同接口
  b、代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能替代真实对象相同的接口以便在任何时刻都能替代真实对象。
同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
  c、真实角色:代理角色代表的真实对象,是我们最终要应用的对象
1.静态代理:
由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

//抽象观察者角色
public interface Watcher {
public void update(String str);
}

//抽象主题角色,watched:被观察
public interface Watched {
public void addWatcher(Watcher watcher);
public void removeWatcher(Watcher watcher);
public void notifyWatchers(String str);
}

//具体的观察者
public class ConcreteWatcher implements Watcher{
private String name;
public ConcreteWatcher(String name) {
super();
this.name = name;
}
public void update(String str) {
System.out.println(name+"收到更新的消息=====》"+str);
}
}

//具体的主题角色: 
public class ConcreteWatched implements Watched{
// 存放观察者
private List<Watcher> list = new ArrayList<Watcher>();
public void addWatcher(Watcher watcher) {
list.add(watcher);
}
public void removeWatcher(Watcher watcher) {
list.remove(watcher);
}
public void notifyWatchers(String str) {
// 自动调用实际上是主题进行调用的
for (Watcher watcher : list)
{
watcher.update(str);
}
}
}

//测试
public class Test {
public static void main(String[] args) {
Watched girl = new ConcreteWatched();//定义主题
//创建观察者
Watcher watcher1 = new ConcreteWatcher("男一号");
Watcher watcher2 = new ConcreteWatcher("男二号");
Watcher watcher3 = new ConcreteWatcher("男三号");
//主题添加观察者
girl.addWatcher(watcher1);
girl.addWatcher(watcher2);
girl.addWatcher(watcher3);
//主题产生最新消息
girl.notifyWatchers("开心");
}
}


View Code
优点

支持松耦合和减少依赖性。客户端不再依赖于观察器,因为通过使用主体和 Observer 接口对客户端进行了隔离。许多框架具有此优点,在这些框架中的应用程序组件可以注册为当(低级)框架事件发生时得到通知。结果,框架将调用应用程序组件,但不会依赖于它。

观察器数目可变。观察器可以在运行时附加和分离,因为主体对于观察器数目没有任何假定。此功能在这样的情况下是很有用的:观察器数在设计时是未知的。例如,如果用户在应用程序中打开的每个窗口都需要一个观察器。

缺点

性能降低。在许多实现中,观察器的 update() 方法可能与主体在同一线程中执行。如果观察器列表很长,则执行 Notify() 方法可能需要很长时间。抽取对象依赖性并不意味着添加观察器对应用程序没有任何影响。

内存泄漏。在 Observer 中使用的回调机制(当对象注册为以后调用时)会产生一个常见的错误,从而导致内存泄漏,甚至是在托管的 C# 代码中。假定观察器超出作用范围,但忘记取消对主体的订阅,那么主体仍然保留对观察器的引用。此引用防止垃圾收集在主体对象也被破坏之前重新分配与观察器关联的内存。如果观察器的生存期比主体的生存期短得多(通常是这种情况),则会导致严重的内存泄漏。

隐藏的依赖项。观察器的使用将显式依赖性(通过方法调用)转变为隐式依赖性(通过观察器)。如果在整个应用程序中广泛地使用观察器,则开发人员几乎不可能通过查看源代码来了解所发生的事情。这样,就使得了解代码更改的含意非常困难。此问题随传播级别急剧增大(例如,充当 Subject 的观察器)。因此,应该仅在少数定义良好的交互(如 Model-View-Controller 模式中模型和视图之间的交互)中使用观察器。最好不要在域对象之间使用观察器。

测试 / 调试困难。尽管松耦合是一项重大的体系结构功能,但是它可以使开发更困难。将两个对象去耦的情况越多,在查看源代码或类的关系图时了解它们之间的依赖性就越难因此,仅当可以安全地忽略两个对象之间的关联时才应该将它们松耦合(例如,如果观察器没有副作用)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: