Skip to content

Instantly share code, notes, and snippets.

@natebosch
Last active April 3, 2016 22:10
Show Gist options
  • Save natebosch/bdd793d447ed44bdc48f to your computer and use it in GitHub Desktop.
Save natebosch/bdd793d447ed44bdc48f to your computer and use it in GitHub Desktop.

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';
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment