Improving on the refactoring in the clean code talk on inheritance, polymorphism, and testing by going from an inheritance approach to a composition approach.
Files should be read in order switch -> inheritance -> composition.
Improving on the refactoring in the clean code talk on inheritance, polymorphism, and testing by going from an inheritance approach to a composition approach.
Files should be read in order switch -> inheritance -> composition.
void main() { | |
var root = new OpNode(add, new ValueNode(1), | |
new OpNode(multiply, new ValueNode(2), new ValueNode(3))); | |
print(root.toString()); | |
print('='); | |
print(root.evaluate()); | |
} | |
final multiply = new Multiplication(); | |
final add = new Addition(); | |
abstract class Operation { | |
num evaluate(num left, num right); | |
} | |
class Multiplication implements Operation { | |
num evaluate(num left, num right) => left * right; | |
String toString() => '*'; | |
} | |
class Addition implements Operation { | |
num evaluate(num left, num right) => left + right; | |
String toString() => '+'; | |
} | |
abstract class Node { | |
num evaluate(); | |
} | |
class ValueNode implements Node { | |
final num value; | |
ValueNode(this.value); | |
num evaluate() => value; | |
String toString() => value.toString(); | |
} | |
class OpNode implements Node { | |
final Operation operation; | |
final Node left; | |
final Node right; | |
OpNode(this.operation, this.left, this.right); | |
num evaluate() => operation.evaluate(left.evaluate(), right.evaluate()); | |
String toString() => '$left $operation $right'; | |
} |
void main() { | |
var root = new AdditionNode(new ValueNode(1), | |
new MultiplicationNode(new ValueNode(2), new ValueNode(3))); | |
print(root.toString()); | |
print('='); | |
print(root.evaluate()); | |
} | |
abstract class Node { | |
num evaluate(); | |
} | |
class ValueNode extends Node { | |
final num value; | |
ValueNode(this.value); | |
num evaluate() => value; | |
String toString() => value.toString(); | |
} | |
abstract class OpNode extends Node { | |
final Node left; | |
final Node right; | |
OpNode(this.left, this.right); | |
} | |
class AdditionNode extends OpNode { | |
AdditionNode(Node left, Node right) : super(left, right); | |
num evaluate() => left.evaluate() + right.evaluate(); | |
String toString() => '$left + $right'; | |
} | |
class MultiplicationNode extends OpNode { | |
MultiplicationNode(Node left, Node right) : super(left, right); | |
num evaluate() => left.evaluate() * right.evaluate(); | |
String toString() => '$left * $right'; | |
} |
void main() { | |
var root = new Node( | |
'+', | |
0, | |
new Node('#', 1, null, null), | |
new Node( | |
'*', 0, new Node('#', 2, null, null), new Node('#', 3, null, null))); | |
print(root.toString()); | |
print('='); | |
print(root.evaluate()); | |
} | |
class Node { | |
final char operator; | |
final num value; | |
final Node left; | |
final Node right; | |
Node(this.operator, this.value, this.left, this.right); | |
num evaluate() { | |
switch (operator) { | |
case '#': | |
return value; | |
case '+': | |
return left.evaluate() + right.evaluate(); | |
case '*': | |
return left.evaluate() * right.evaluate(); | |
} | |
} | |
String toString() { | |
switch (operator) { | |
case '#': | |
return '$value'; | |
case '+': | |
return '$left + $right'; | |
case '*': | |
return '$left * $right'; | |
} | |
} | |
} |