Seb*_*ebi 7 java oop design-patterns
注册观察员的最佳选择是什么?我没有找到关于这个主题的任何内容。主要讨论了“推与拉”,但也有几个选项可以注册观察者。
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
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我的代码中的三种情况:
在所有 3 个选项都可能的情况下,从面向对象和干净代码的角度来看,哪一个是最好的?
这是我认为每个选项都有的一些优点和缺点的列表。
1.外部注册
优点:
- 观察者的构造函数中的参数较少。
- 不需要对Subject 进行抽象以促进Subject 和Observer 之间的松散耦合。
缺点:
- 不要忘记在客户端代码中注册观察者。
- 客户端代码负责注册。
中立:
- 观察者有一个额外的公共方法。
- 观察者可以通过客户端代码注册/取消注册。
2.内部注册,方案一:具体的observer实现Observer接口
优点:
- 观察者负责注册。
- 注册不能忘记,因为必须将Subject 传递给Observer 的构造函数。
缺点:
- 观察者的构造函数中多了一个参数。
中立:
- 观察者有一个额外的公共方法。
- 观察者可以通过客户端代码注册/取消注册。
- 观察者可以注册/取消注册自己。
3.内部注册,选项2:具体观察者不实现观察者接口
优点:
- 观察者负责注册。
- 注册不能忘记,因为必须将Subject 传递给Observer 的构造函数。
- 观察者没有额外的公共方法可以被与“主题通知观察者”无关的任何东西滥用。
缺点:
- 观察者的构造函数中多了一个参数。
中立:
- 观察者只能注册/取消注册自己。
鉴于您提出的“外部”和“内部”注册之间的细微差别,看起来似乎没有一个正确的答案。尽管如此,我还是会尝试。
与其他两个相比,我更喜欢“外部”注册,原因有两个:
Observer对 s 一无所知Subject;即,它们是相当解耦的。例如,我可以将一个附加Observer到多个Subjects,并且无需任何人进行更改。Observer关心的是编辑时需要做什么inform。它不关心向任何人注册/注销。