首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >复合和观察者模式实现

复合和观察者模式实现
EN

Software Engineering用户
提问于 2017-01-11 08:51:18
回答 1查看 1.9K关注 0票数 1

我正在学习复合和观察者设计模式,并创建了一个FileSystem类,其中我将节点、文件夹和文件定义为复合关系。现在,我想实现观察者模式,所以当有FileBrowser/Finder/FileBrowser观察者时,当我向文件夹添加一个文件时,它们可以得到更新。这是我的关系和密码:

我为Node (组件)实现了Subject接口,而在Directory本身中,我实现了Subject方法:附件、dettach和notifyObservers。这是个好设计吗?如果我想获得文件夹和子文件夹的通知怎么办?是否需要将每个目录传递给我的FileBrowser观察者?如果文件更改,我们可能需要复制代码,意思是向我的File类添加附加、dettach和notifyObservers?

代码语言:javascript
复制
public class SolutionMain {

    public static StringBuffer g_indent = new StringBuffer();

    public static void main(String[] args) {

        Node root = FileSystem.getFileSystem();
        Node one = new Directory("dir1");
        Node two = new Directory("dir2");
        Node thr = new Directory("dir3");
        Node a = new File("a", 100);
        Node b = new File("b", 200); 
        Node c = new File("c", 200); 
        Node d = new File("d", 400);
        Node e = new File("e", 10);

        new FileBrowser(root);
        root.add(one);
        root.add(two);
        one.add(a);
        one.add(two);
        one.add(b);
        two.add(c);
        two.add(d);
        two.add(thr);
        thr.add(e);
    }

}

FileBrowser

代码语言:javascript
复制
public class FileBrowser extends Observer {

    private static int observerIDTracker = 0;
    private int observerID;
    private Subject subject;

    public FileBrowser (Subject subject) {
        this.subject = subject;
        this.observerID = ++observerIDTracker;
        System.out.println("New observer "  + this.observerID);
        // Attach observer in this case FileBrowser
        this.subject.attach(this);
    }

    public void update() {
        Node d = (Directory) subject;
        d.display();
    }


}

目录

代码语言:javascript
复制
public class Directory extends Node{

    private String _name;
    private ArrayList<Node> _children = new ArrayList<Node>();
    private ArrayList<Observer> _observers = new ArrayList<Observer>();

    public Directory(String name) { _name = name; }

    public void name(String name) { _name = name; }

    public String name() { return _name; }

    public void add(Node obj) { 
        _children.add(obj); 
        notifyAllObservers();
    }


    public void display() { System.out.println("Directory: " + _name + " changed"); }

    public void attach(Observer observer){
          _observers.add(observer);     
    }

    public void detattach(Observer observer){
          _observers.remove(observer);      
    }

    public void notifyAllObservers(){
          for (Observer observer : _observers) {
             observer.update();
          }
    } 
}

通知可以工作,但不知道这是否是一个好的观察者实现。

我在网上找到了一个示例,其中使用了Mediator模式,并且有这个类的实现,但不确定它的优点是什么。

EN

回答 1

Software Engineering用户

回答已采纳

发布于 2019-02-23 13:25:21

在google上寻找一些用于组合设计模式的UML类图,以便在一篇文章中使用它,并看到了您的这条主线。不幸的是,您的uml类图中有一个错误。但是,在“目录”和“节点”之间存在聚合关系,这是不正确的。相反,这应该是一种复合关系。

在聚合(您在目录和节点之间使用的)关系中,您有两个没有存在依赖关系的对象。这意味着尽管B级被删除了,A类仍然可以持续。

相反,复合关系用于两个具有存在依赖关系的对象。因此,如果在A类和B类之间使用复合符号而在B类处使用复合符号,则A类一旦销毁B类,就会被销毁。

这意味着,对于您的关系图,一个节点,即目录或文件将持续甚至删除父目录。这是没有道理的,对吧?

票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/339951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档