封装属性设计模式

时间:2017-03-29 08:55:16

标签: angularjs angular typescript design-patterns architecture

我想封装文档激活方式的逻辑(布尔值)。激活文档时,应将其添加到activeDocuments列表中,并将标志设置为true。我想禁止直接访问isActive属性。

class DocumentService {
      private activeDocuments : Map<DocumentModel> = new Map<DocumentModel>();

      // Activates the document and adds it to the list
      activateDocument(document: DocumentModel) {
                document.setActive();
                activeDocuments.set(document.id, document);
      }
}


class DocumentModel {
      private isActive: boolean;

      setActive() {
                this.isActive = true;
      }         
}

class DocumentComponent {
      documentSelected() {
           // this.document.setActive()  - SHOULD BE FORBIDDEN because the document is not added to the activedocument list !
           this.documentService.activateDocument(this.document);
      }
}

我解决这个问题的唯一解决方案是创建两个接口DocumentServiceInterface,它有一个setActive()方法和DocumentInterface,它没有它,所以它阻止了| DocumentComponent激活文件,但服务可以仍然激活文件。

是否有可以解决此问题的设计模式/配方?

遍历文档列表以检查它是否活动不是一个选项,因为结构在应用程序中要复杂得多,文档数量应该缩放(例如,可能有多个文档)

2 个答案:

答案 0 :(得分:2)

您可以使用Mediator Design Pattern来解决问题。或者如果您只想将方法隐藏到客户端代码中,您可以使用es2015符号方法,然后使用DocumentService&amp; DocumentModel无法访问活动方法,因为ACTIVE的可见性仅在模块中可见,代码如下所示:

const ACTIVE = Symbol("active");

class DocumentService {
    private activeDocuments: Map<String,DocumentModel> = new Map<String,DocumentModel>();

    // Activates the document and adds it to the list
    activateDocument(document: DocumentModel) {
        document[ACTIVE]();
        this.activeDocuments.set(document.id, document);
    }

}

class DocumentModel {
    public id: string;
    private isActive: boolean;

    [ACTIVE]() {
        this.isActive = true;
    }
}

答案 1 :(得分:0)

具体的javascript方式如下:

setActive() {
    if (arguments.callee.caller.toString()!=='DocumentService')
         throw new Exception();
}

但我发现它非常传统且难以阅读