注册观察员的最佳选择是什么?我没有找到关于这个主题的任何内容。主要是" push vs. pull"讨论了,但也有一些注册观察者的选择。
public static void main(String[] args)
{
Subject subject = new ConcreteSubject();
// External registration
Observer observerExternal = new ConcreteObserverExternal();
subject.registerObserver(observerExternal);
// Internal registration, option 1
Observer observerInternal1 = new ConcreteObserverInternal1(subject);
// Internal registration, option 2
ConcreteObserverInternal2 observerInternal2 = new ConcreteObserverInternal2(subject);
}
interface Observer
{
void inform();
}
class ConcreteObserverExternal implements Observer
{
@Override
public void inform()
{
// do sth.
}
}
class ConcreteObserverInternal1 implements Observer
{
public ConcreteObserverInternal1(Subject subject)
{
subject.registerObserver(this);
}
@Override
public void inform()
{
// do sth.
}
}
class ConcreteObserverInternal2
{
public ConcreteObserverInternal2(Subject subject)
{
subject.registerObserver(() -> inform());
}
private void inform()
{
// do sth.
}
}
interface Subject
{
void registerObserver(Observer obs);
void unregisterObserver(Observer obs);
}
class ConcreteSubject implements Subject
{
@Override
public void registerObserver(Observer obs)
{
// register
}
@Override
public void unregisterObserver(Observer obs)
{
// unregister
}
private void foo()
{
// ...
notifyObservers();
}
private void notifyObservers()
{
// notify observers
}
}
我的代码中有三种情况:
在所有3个选项都可行的情况下,从OO和清洁代码的角度来看哪一个最好?
以下列出了我认为每个选项都有的优缺点。
1。外部注册
赞成:
- 观察者构造函数中的参数较少
- 主体不需要抽象,以促进主体和观察者之间的松散耦合。
缺点:
- 不要忘记在客户端代码中注册观察者。
- 客户代码负责注册。
中性:
- 观察者有一个额外的公共方法
- Observer可以通过客户端代码注册/取消注册。
2。内部注册,选项1:具体观察者实现Observer接口
赞成:
- 观察员负责注册
- 注册不能忘记,因为一个人被迫将主题传递给观察者的构造函数。
缺点:
- 观察者的构造函数中的另一个参数。
中性:
- 观察者有一个额外的公共方法
- 观察者可以通过客户代码注册/取消注册
- 观察者可以注册/注销自己。
第3。内部注册,选项2:具体观察者不实施Observer接口
赞成:
- 观察员负责注册
- 注册不能忘记,因为一个人被迫将主题传递给观察者的构造函数。
- 观察者没有额外的公共方法,可以被与#34;主题通知观察者"无关的任何东西滥用。
缺点:
- 观察者的构造函数中的另一个参数。
中性:
- 观察者只能注册/注销自己。
答案 0 :(得分:1)
鉴于你在外部'之间提出的微妙差异。和'内部'注册,似乎没有一个正确的答案。不过,我会尝试。
我更喜欢'外部'注册其他两个有两个原因:
Observer
不了解Subject
s;即它们相当分离。例如,我可以将一个Observer
附加到多个Subject
,并且不会有任何人需要更改。Observer
仅关注inform
时需要执行的操作。它并不关心注册/取消注册任何人。