Skip to content

Commit 00fdd15

Browse files
committed
check in
1 parent cd103ae commit 00fdd15

File tree

4 files changed

+441
-0
lines changed

4 files changed

+441
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace theCleanCodeTalks_ConditionalVersion
8+
{
9+
class Node
10+
{
11+
public char op;
12+
public double value;
13+
Node left;
14+
Node right;
15+
16+
/*
17+
* julia's comment:
18+
* 1. bug 001 - need to add '#' for value node
19+
*/
20+
public Node(string s)
21+
{
22+
if (s.CompareTo("#") == 0 || s.CompareTo("+") == 0 || s.CompareTo("*") == 0)
23+
op = s.Substring(0, 1).ToCharArray()[0];
24+
else
25+
{
26+
op = '#'; // bug 001
27+
value = Convert.ToDouble(s);
28+
}
29+
}
30+
31+
public double evaluate(){
32+
switch(op){
33+
case '#':
34+
return value;
35+
case '+':
36+
return left.evaluate() + right.evaluate();
37+
case '*':
38+
return left.evaluate() * right.evaluate();
39+
default:
40+
return 0;
41+
}
42+
}
43+
44+
/*
45+
* Problem statement:
46+
* 1+2*3
47+
* Optimal solution is to use polymorphism, design ValueNode, OpNode, AdditionNode, MultiplcationNode classes.
48+
* Naive solution (most people do) is to use a lot of conditionals
49+
* Pseudo code as following:
50+
*
51+
*
52+
* Google talk:
53+
* https://www.youtube.com/watch?v=4F72VULWFvc
54+
* Reference:
55+
* http://juliachencoding.blogspot.ca/2015/11/the-clean-code-talks.html
56+
*
57+
* +
58+
* / \
59+
* 1 *
60+
* / \
61+
* 2 3
62+
*/
63+
static void Main(string[] args)
64+
{
65+
//string input = "1+2*3";
66+
Node n1 = new Node("+");
67+
n1.left = new Node("1");
68+
n1.right = new Node("*");
69+
n1.right.left = new Node("2");
70+
n1.right.right = new Node("3");
71+
72+
double result = calculate(n1);
73+
Console.WriteLine("Test result is "+result.ToString());
74+
}
75+
76+
public static double calculate(Node root)
77+
{
78+
if (root == null) return 0;
79+
80+
return root.evaluate();
81+
}
82+
}
83+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace OODesign_CleanCodeTalk_ConditionalVersion
8+
{
9+
class Node
10+
{
11+
public char op;
12+
public double value;
13+
Node left;
14+
Node right;
15+
16+
/*
17+
* julia's comment:
18+
* 1. bug 001 - need to add '#' for value node
19+
*
20+
* Dec. 15, 2015
21+
* Walk through the code, and refresh the idea to solve the problem.
22+
*
23+
*/
24+
public Node(string s)
25+
{
26+
if (s.CompareTo("#") == 0 || s.CompareTo("+") == 0 || s.CompareTo("*") == 0)
27+
op = s.Substring(0, 1).ToCharArray()[0];
28+
else
29+
{
30+
op = '#'; // bug 001
31+
value = Convert.ToDouble(s);
32+
}
33+
}
34+
35+
public double evaluate()
36+
{
37+
switch (op)
38+
{
39+
case '#':
40+
return value;
41+
case '+':
42+
return left.evaluate() + right.evaluate();
43+
case '*':
44+
return left.evaluate() * right.evaluate();
45+
default:
46+
return 0;
47+
}
48+
}
49+
50+
/*
51+
* Problem statement:
52+
* 1+2*3
53+
* Optimal solution is to use polymorphism, design ValueNode, OpNode, AdditionNode, MultiplcationNode classes.
54+
* Naive solution (most people do) is to use a lot of conditionals
55+
* Pseudo code as following:
56+
*
57+
*
58+
* Google talk:
59+
* https://www.youtube.com/watch?v=4F72VULWFvc
60+
* Reference:
61+
* http://juliachencoding.blogspot.ca/2015/11/the-clean-code-talks.html
62+
*
63+
* +
64+
* / \
65+
* 1 *
66+
* / \
67+
* 2 3
68+
*/
69+
static void Main(string[] args)
70+
{
71+
//string input = "1+2*3";
72+
Node n1 = new Node("+");
73+
n1.left = new Node("1");
74+
n1.right = new Node("*");
75+
n1.right.left = new Node("2");
76+
n1.right.right = new Node("3");
77+
78+
double result = calculate(n1);
79+
Console.WriteLine("Test result is " + result.ToString());
80+
}
81+
82+
public static double calculate(Node root)
83+
{
84+
if (root == null) return 0;
85+
86+
return root.evaluate();
87+
}
88+
}
89+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace OODesign_CleanCodeTalk_OpNodeValueNodeAndMore
8+
{
9+
/*
10+
* Dec. 15, 2015
11+
* Julia works on the code based on the talk:
12+
*
13+
* Talk:
14+
* https://www.youtube.com/watch?v=4F72VULWFvc
15+
* blog:
16+
* http://juliachencoding.blogspot.ca/2015/11/the-clean-code-talks.html
17+
*
18+
* The implementation is not naive version,
19+
* see the implementation:
20+
* https://github.com/jianminchen/OODesignPractice/blob/master/ConditionalVersion.cs
21+
*
22+
* instead, OpNode and ValueNode are designed to bring in polymorphism. Good pratice:
23+
* Node (better called: AbstractNode, differentiate from Node), OpNode, ValueNode
24+
*
25+
* https://github.com/jianminchen/OODesignPractice-1-2-3-B/blob/master/OODesign_CleanCodeTalk_OpNodeValueNode.cs
26+
*
27+
* Optimal solution:
28+
*
29+
* Node, ValueNode, OpNode, AdditionNode, MultiplicationNode
30+
*
31+
*
32+
*/
33+
abstract public class Node
34+
{
35+
36+
/*
37+
* use abstract to declare the function
38+
* C++ pure virtual <-> C# abstract method
39+
* http://stackoverflow.com/questions/4948992/pure-virtual-methods-in-c
40+
* */
41+
public abstract double evaluate();
42+
}
43+
44+
class ValueNode : Node
45+
{
46+
public double value;
47+
48+
public ValueNode(string s)
49+
{
50+
value = Convert.ToDouble(s);
51+
}
52+
53+
override public double evaluate()
54+
{
55+
return value;
56+
}
57+
}
58+
59+
/*
60+
* Dec. 15, 2015, Julia plays with C# inheritance, fixed a compile error:
61+
* bug001:
62+
* class OpNode -> compile error: OpNode does not implement inherited abstract member evaluate()
63+
* so, add 'abstract' before class OpNode
64+
* class OpNode vs abstract class OpNode
65+
* compile error compile ok
66+
*/
67+
abstract class OpNode : Node
68+
{
69+
public char op;
70+
public Node left;
71+
public Node right;
72+
}
73+
74+
class AddtionNode : OpNode
75+
{
76+
override public double evaluate()
77+
{
78+
return left.evaluate() + right.evaluate();
79+
}
80+
}
81+
82+
class MultiplcationNode : OpNode
83+
{
84+
override public double evaluate()
85+
{
86+
return left.evaluate() * right.evaluate();
87+
}
88+
}
89+
90+
class OODesign_CleanCodeTalk_OpNodeValueNodeAndMore
91+
{
92+
/*
93+
* Problem statement:
94+
* 1+2*3
95+
* Optimal solution is to use polymorphism, design ValueNode, OpNode, AdditionNode, MultiplcationNode classes.
96+
* Naive solution (most people do) is to use a lot of conditionals
97+
* Pseudo code as following:
98+
*
99+
*
100+
* Google talk:
101+
* https://www.youtube.com/watch?v=4F72VULWFvc
102+
* Reference:
103+
* http://juliachencoding.blogspot.ca/2015/11/the-clean-code-talks.html
104+
* Naive solution: one class called Node, use conditional if to cover polymorphism.
105+
* https://github.com/jianminchen/OODesignPractice/blob/master/ConditionalVersion.cs
106+
*
107+
* +
108+
* / \
109+
* 1 *
110+
* / \
111+
* 2 3
112+
*/
113+
static void Main(string[] args)
114+
{
115+
//string input = "1+2*3";
116+
117+
OpNode n1 = new AddtionNode();
118+
n1.left = new ValueNode("1");
119+
120+
OpNode n2 = new MultiplcationNode();
121+
n2.left = new ValueNode("2");
122+
n2.right = new ValueNode("3");
123+
124+
n1.right = n2;
125+
126+
double result = calculate(n1);
127+
Console.WriteLine("Test result is " + result.ToString());
128+
}
129+
130+
public static double calculate(Node root)
131+
{
132+
if (root == null) return 0;
133+
134+
return root.evaluate();
135+
}
136+
}
137+
}

0 commit comments

Comments
 (0)