观察者模式与单一职责原则的违反

4
我是一个有用的助手,可以翻译文本。
我有一个小程序,一旦文本发生变化就会重新绘制自己。
设计1:
//MyApplet.java
public class MyApplet extends Applet implements Listener{
    private DynamicText text = null;
    public void init(){
        text = new DynamicText("Welcome");
    }
    public void paint(Graphics g){
        g.drawString(text.getText(), 50, 30);
    }

    //implement Listener update() method
    public void update(){
       repaint();
    }
}

//DynamicText.java
public class DynamicText implements Publisher{
    // implements Publisher interface methods
    //notify listeners whenever text changes   
}

这是否违反了单一职责原则(SRP)?我的Applet不仅充当Applet,还必须执行Listener的工作。同样地,DynamicText类不仅生成动态文本,还会更新已注册的Listener。 设计2:
//MyApplet.java
public class MyApplet extends Applet{
    private AppletListener appLstnr = null;
    public void init(){
        appLstnr = new AppletListener(this);
        // applet stuff
    }
}

// AppletListener.java
public class AppletListener implements Listener{
    private Applet applet = null;
    public AppletListener(Applet applet){
        this.applet = applet;
    }

    public void update(){
        this.applet.repaint();
    }
}

// DynamicText
public class DynamicText{
    private TextPublisher textPblshr = null;

    public DynamicText(TextPublisher txtPblshr){
        this.textPblshr = txtPblshr;
    }
    // call textPblshr.notifyListeners whenever text changes   
}

public class TextPublisher implments Publisher{
    // implements publisher interface methods
}

问题1. 设计1是否违反SRP原则?

问题2. 在这里,使用组合来消除SRP违规是否是更好的选择,就像设计2中一样。


请注意,您的Design 2具有交叉引用(appLstnr具有Applet,而Applet具有listener)。在这种情况下,这不是问题,但在较低级别时可能会使垃圾收集器混淆。GC可以处理循环引用,但只能处理到一定程度。 - extraneon
如果我想避免违反SPR,那么我应该如何继续前进? - pankajt
@extraneon:您能否澄清一下您所看到的循环引用问题是哪一个? - Volker Stolz
@vs Applet持有对监听器的引用,监听器持有对Applet的引用。现代GC可以处理这种简单的交叉引用,但旧的GC则不能。 - extraneon
2个回答

1

问题1:是的。

问题2:是的。

我的问题:这是一种推动人们使用更好设计技术的某种形式的推销吗?

无论如何,你正在认识到你的问题中也存在中介者模式。这是微妙的。现在看起来可能是一个适配器,但随着你的设计的发展,我怀疑很快就会清楚这实际上是一个中介者。中介者在许多UI问题中都有应用。事实上,人们已经给解决UI问题中存在的中介者力量一个特殊的名字:“MVC”。


我对决定应该选择什么感到非常困惑。我希望听取大家的意见。可能,最好的人都在SO上。寻求他们的意见来澄清我的疑虑。谢谢回复。现在我可能需要研究中介者! :) - pankajt

0

我认为设计1 按照现有的写法 并没有 SPR(单一职责原则)问题。在MVC中,视图应该监听模型,而在这种情况下,视图是小程序,发布者是模型。

当然,小程序还有其他一些职责(例如生命周期管理),这可能意味着您需要在开始处理这些职责时分离出特定的视图类。然后,小程序可以通过组合使用视图。


另一个呢?你看到它有什么问题吗? - pankajt
从长远来看,随着更多的功能,您可能最终会比设计1更接近设计2。但目前我认为这是过度设计。此外,由于所显示的功能非常简单,很难为所有实体想出好的名称(尽管选择与MVC等众所周知的模式匹配的名称可以有所帮助)。我会坚持YAGNI原则,但确保您拥有足够的测试和良好的IDE。这样,您可以在需要时重构,而不是之前。只是我的两分钱... - pdbartlett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接