首页 > 解决方案 > 类不变量:一个对象需要不为空的,反之亦然。提供什么优雅的方式?

问题描述

假设我们应该实现一个双向链表。这个数据结构假设有一个 ' 链,Link它们中的每一个都与前一个和下一个都有连接。由于我不喜欢处理讨厌if (previousLink !== null)的空检查(所以它可能看起来像这样:

class Link { 
  data;
  previousLink;
  nextLink;

  constructor(data, previousLink, nextLink) {
    this.data = data;
    this.previousLink = previousLink;
    this.nextLink = nextLink;
    this.checkClassInvariants();  
  }

  checkClassInvariants() {
    assert(this.previousLink !== null);
    assert(this.nextLink !== null);
  }

  insertPreviousLink(link) { ... checkClassInvariants(); }
  
  removePreviousLink() { ... checkClassInvariants(); }

  /* etc. */ 
}

所有插入/删除例程都不会进行空检查,而只是修补对象连接。我们的牺牲是我们必须实现一些BeginningLinkand EndLink。前者知道它的previousLinkisnull和后者是相同的,但与nextLink. 但是,除了这些之外,断言的其他部分应该仍然有效。似乎这个目标可以通过 的多态性来实现checkClassInvariants()

class BeginningLink extends Link {
  constructor(nextLink) {
    super(new DummyData(), null, nextLink);
  }

  checkClassInvariants() {
    assert(this.nextLink !== null);
  }
}

class EndLink extends Link {
  constructor(previousLink) {
    super(new DummyData(), previousLink, null);
  }

  checkClassInvariants() {
    assert(this.previousLink !== null);
  }
}

当我们LinkedList尝试用BeginningLinkand初始化自身时EndLink,它们的不变量将失败,因为此时BeginningLink正在创建 no EndLinkexists(反之亦然)。

绕过这个混乱的优雅方法是什么?我应该checkClassInvariants()Link至少在构造函数中)忽略并LinkedList负责非空检查吗?但是如果一个类本身明确声明它的不变量会更好,不是吗?

标签: javascriptoop

解决方案


推荐阅读