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'; | |
| } | |
| } | |
| } |