多态性与if和逻辑

Lpc*_*ark 4 architecture oop polymorphism logic

class Person { 
  private state ="normal" //cripple

  run() { 
    if (this.state === "normal") { 
      console.log("run")
    } else {
      console.log("hobble")
    }
  }
}


//vs

abstract class AttemptRun { 
  abstract run();
}


class NormalRun extends AttemptRun { 
  run() { 
    console.log("run")
  }
}

class CrippleRun extends AttemptRun { 
  run() { 
    console.log("hobble")
  }
}

class Person { 
  protected runAbility: AttemptRun;

  run() { 
    this.runAbility.run()
  }
}
Run Code Online (Sandbox Code Playgroud)

假设我理解这里的概念是我的问题.为什么多态性比if和逻辑更好.

因为在我看来你仍然需要工厂或其他方法来设定人的能力类型.因此,如果逻辑不在这里,它将会在其他地方.

为什么我在阅读的书中重复了一些,比如干净的代码.它被列为代码气味.

我觉得它可以使单元测试更容易,因为那时你只测试能力而你不需要测试使用它的实际其他类.

这就是它所提供的一切.

if/else而不是你需要写一个不同的类和工厂?看起来很公平吗?

也许这是更多的工作,但从长远来看,它会更好.

每个案件有哪些弱点?

如果这是一个小班,你会这样做吗?基本上,我不知道我是否理解这个概念,然后假设我这样做.它的实用性如何.

明智的开发人员可能只在他们需要特定的东西时使用它.我不知道任何具体细节.

ROX*_*ROX 6

关于您的简单示例,有一些事情没有证明多态方法的好处.

在你的情况下,只有一个if语句(在运行中),只有2个人的变体,并且在每种情况下的行为非常相似(它们都只是记录一些文本).

考虑一个更大的案例,你可以获得更多功能.如果你添加了一个tryToDance,你会引入一个新的if/else块,如果你添加了其他人的变体,你的所有函数都需要在现有函数中使用新的if或case.当您添加更多功能时,您会在许多if/else块中遇到许多情况,并且编译器无法验证您是否未错过if情况中的某个人类型.

使用单元测试捕获错误是很好的,但是选择一个使错误无法实现的设计会更好 - 编译器永远不会错过这样的东西,你知道编译器运行和工作(你希望单元测试运行成功 - 但是你'从来没有那么肯定)

如果您有一个抽象基类,定义了所有类型的人都实现的接口,那么编译器将告诉您是否未能为其中一个派生类类实现其中一个方法.

在更大的实际案例中,每种类型的人的每种方法的实现可能并且可能不仅仅是输出不同的文本.如果它们保留在if情况下,所有不同的功能都会在一个地方结束,那么您的代码会同时依赖于许多内容,这会使测试和维护变得更加困难.如果人类的状态使得方法相互作用,这会使事情更加复杂化,并且多态性允许您在类中包含该行为,而不需要将该类与其他类型的人类关联.

在简单的情况下,if/else版本可以工作,在许多情况下它只是不能很好地扩展.

你可能仍然需要在某个工厂方法中使用if/else或switch,但是一个负责构造的开关比许多开关或块更容易维护.

  • 这是一个可靠的答案,我一定会从中受益。谢谢。 (2认同)

小智 5

使用多态性代替 if-else 语句有利有弊。

专业人士

  1. OOP 是一种改进和促进代码重用的方法,使用 if/else 语句而不是具有AttemptRun许多实现的抽象类/接口,您可能会遇到需要添加另一个类的情况,例如Animal,您需要重写也是类中常见的情况Person
  2. 使用多态性有助于通过提高代码的可读性来维护代码。很长的if-else语句读起来很累,你必须记住这一点,因为这是有用的,而不是一个类名直接提醒你具体情况的功能。

缺点

  1. Pro 2 也是一个缺点:正如您所说,多态性迫使您测试用于注入职责更改行为的所有相关类。
  2. 多态性对性能的影响:编译器通过转发检索方法的正确实现;if-else 列表肯定更快。

  • 在现代虚拟机(如 JIT 或 CLR)中调用多态方法的性能差异非常小 - 事实上,它可以比(一堆)条件检查“更快”!这显然会因实现和语言设计以及条件检查的成本而异;考虑一下,即使是对“Equals”的调用也涉及 C#/Java 中的(多态)调用。 (7认同)