Showing posts sorted by relevance for query SOLID principle. Sort by date Show all posts
Showing posts sorted by relevance for query SOLID principle. Sort by date Show all posts

Saturday, September 26, 2015

Object oriented principles - S.O.L.I.D.

August 28, 2015


SOLID principles:

S – Single-responsiblity principle

O – Open-closed principle

L – Liskov substitution principle

I – Interface segregation principle

D – Dependency Inversion Principle

Read the article: 




Here are my focus from Jan. 2014 - Sept. 2015, JavaScript -> Leetcode -> .NET framework -> OO design. 

Nov. 11, 2015


Here is the video studying on this remembrance day of Canada holiday, 



Spent 60 minutes to watch this video:

Bob Martin SOLID Principles of Object Oriented and Agile Design


video 1:12/1:23



Nov. 12, 2015

book chapter from uncle bob:


Lecture notes to read 


Videos ( Julia's favorite) 







Sunday, December 15, 2019

SOLID principles

Dec. 15, 2019

Introduction


Object-oriented programming is something I like to learn more. One thing I can review is about SOLID principle. Also I like to review the design question 1 + 2 * 3 and how the pattern is applied to solve the problem. I do not have a lot of time to review.


My past blogs about 1 + 2 * 3


 I spent over one hour to review the principles with an example. I like to look into how many more minutes I can spend on to review.

 I am working on 24 hours count down to study.

Here is the link of SOLID principle from my blog.




Tuesday, December 15, 2015

OO principle - S.O.L.I.D., Single Responsibility, Open/ close principle drill

Dec. 15, 2015

Review the video about the testing, and try to get more from this lecture:

"The Clean Code Talks -- Inheritance, Polymorphism, & Testing"

https://www.youtube.com/watch?v=4F72VULWFvc

action items:
1. put sample code in C#, and then, check in git;
2. write down key words, and easy for review and follow as rules.

Julia's sample code in C#:
Problem statement: 1 + 2*3, how to implement in OO design (using C# language)

Three solutions are provided, naive one, better one, optimal solution to apply S.O. principles.

1. Represent this as a tree

   +
/     \
1     *
    /    \
  2      3

Most of people come out solution like the following:
 Using conditionals

  class Node{
     char operator;
     double value;
     Node left;
     Node right;
     double evaluate(){
       switch(operator){
        case '#': return value;
        case '+': return left.evaluate() + right.evaluate();
        case '*" return left.evaluate() * right.evaluate();
        case ...  // edit this for each new operator
       }
    }
 }

 Big problem on this:
  graphic representation,
  Node
  op:char
  value: double
  left: Node
  right:Node
 --------------
   evaluate():double

Julia could not figure out the analysis here <- first time to memorize this analysis, and also try to learn reasoning

    Analyzing attributes

                           #      +        *
function                      yes     yes
value                  yes
left                              yes     yes
right                            yes     yes

Two different behaviors are fighting here, (see the above table), not matching Single Responsibility Principle.
if you are the operation node, then you need your left and right child; whereas value node, you just need value.

C# code using conditional implementation, one class Node

Naive approach, breaking single responsibility principle, the C# code is here.

Clean code talk - conditional version written down based on the talk, C# code is here.


2.
Let us break it up:
     Node
   --------------
   evaluate(): double
         |                                  |
ValueNode                         OpNode
  value: double                   op: char
---------------                       left: Node
 evaluate: double                right: Node
                                          ----------------
                                          evaluate(): double
As showing above, break Node into ValueNode and OpNode, so ValueNode does not have left and right child because of no meaning over there.

Tree looks like:

          OpNode
              +
    /                            \
ValueNode         OpNode
       1                         *
                        /                    \
                 ValueNode      ValueNode
                        2                     3
Operations and values

abstract class Node{
   abstract double evaluate();
}

class ValueNode extends Node{
    double value;
    double evaluate(){
           return value;
    }
}

class OpNode extends Node{
   char operator;
   Node left;
   Node right;
   double evaluate(){
         switch(operator) {
             case '+': return left.evaluate() + right.evaluate();
             case '-':  return left.evaluate() + right.evaluate();
             case ...   // edit this for each new operator
         }
    }
}

better solution: Node, OpNode, ValueNode, the C# code is here.


3. How to extend this? Every time you add a new operator, need to hold on source code, and add code in switch statement, how to make it better?

OpNode divides into AdditionNode  and MultiplicationNode

           OpNode
         ------------------
         left: Node
         right: Node
        ------------------
         evaluate(): double

 AdditionNode                                 MultiplicationNode
----------------------------                    --------------------------
   evaluate(): double                           evaluate(): double


  abstract class Node{
           abstract double evaluate();
  }

  class ValueNode extends Node{
       double value;
       double  evaluate(){
          return value;
       }
 }

  class abstract OpNode extends Node{
  Node left;
  Node right;
  abstract evaluate();
  }

 Operation classes
  class AdditionNode extends OpNode{
      double evaluate(){
         return left.evaluate() + right.evaluate();
      }
}

  class MultiplicationNode extends OpNode{
     double evaluate(){
          return left.evaluate() + right.evaluate();
     }
 }

 Now, the new tree diagram:

      AdditionalNode
              +
    /                            \
ValueNode         MultiplicationNode
       1                         *
                        /                    \
                 ValueNode      ValueNode
                        2                     3

optimal solution: Node, OpNode, ValueNode, AdditionNode, MultiplicationNode, here is C# code.


Perfect examples of 1 + 2*3, 3 implementations, Julia learns O of S.O.L.I.D. OO principles, open for extension, close for change.

More detail, the above optimal solution does not have any if statement, and any new arithmetic operation just needs a new class, no need to touch existing code: Node, OpNode, AdditionNode, MultiplicationNode. For example, minus '-' operation, just add MinusNode. For easy to demo, all classes are in one .cs file, but each class should have it's own .cs file. :-)

Share the learning of Open/Close principle - great examples. Cannot wait to move on to next one, Liskov substitution principle!

Reference:
Blog:
http://juliachencoding.blogspot.ca/2015/11/the-clean-code-talks.html

Follow up


Sept. 9, 2018

The project is documented in my github folder, here is the link.



Wednesday, November 18, 2015

The clean code talks

Nov. 18, 2015

Review the video about the testing, and try to get more from this lecture:

"The Clean Code Talks -- Inheritance, Polymorphism, & Testing"

https://www.youtube.com/watch?v=4F72VULWFvc

action items:
1. put sample code in C#, and then, check in git;
2. write down key words, and easy for review and follow as rules.

Julia's sample code in C#:
C# code using conditional implementation, one class Node

The source code folder is here.

better solution: Node, OpNode, ValueNode:

optimal solution:

Perfect example to learn S.O.L.I.D. OO principles, open for extension, close for change. The above optimal solution does not have any if statement, and any new arithmetic operation just needs a new class, no need to touch existing code. Julia passes the learn Open/Close principle. Move on to next one, Liskov substitution principle!

Notes:
Premise - Most ifs can be replaced by polymorphism
Why?
Easy to read, test without ifs.
polymorphic systems are easier to maintain.

Julia: write down the sentence in the talk:  supporting facts: one execution path, so easy to understand, test, and extend.

Use polymorphism
 If an object should behave differently based on its state.
 If you have to check the same conditions in multiple places.

- binding is not on compile time,

  Use conditionals
  Mainly to do comparisons of primitive objects: >,<,==, !=
  There other uses, but today we focus on avoiding if

  Do not return null in the method
  To be if free
  Never return a null, instead return a Null object, e.g. an empty list

  Don't return error codes, instead throw an Exception (Run Time please!)

  Rampant (wild, unchecked) subclassing
  Polymorphism uses subclassing
  Be careful about runaway subclassing (another talk focuses on that)
  avoid pitfall: inheritance hierarchy - too complex

  State based behavior

  Replace conditionals with polymorphism
  You have a conditional that chooses different behavior depending on the type of an object.

  Move each leg of the conditional to an overriding method in a subclass.
  Make the original method abstract.


   Example:
  double getSpeed(){
    switch (_type){
       case EUROPEAN:
          return getBaseSpeed();
       case AFRICAN:
         return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts;
       case NORWEGIAN_BLUE:
         return (_isNailed)? 0 : getBaseSpeed(_voltage);
   }
   throw new RuntimeException ("Should be unreachable");
}

Suggestion to solve the problem: use subclasses
Isn't there already a type system?

An Exercise:
Model this!
1 + 2 * 3

favorite interview question by the speaker:

Represent this as a tree

   +
/     \
1     *
    /    \
  2      3
Node object to store the information

evaluate()
computes the result of an expression

Most of people come out solution like the following:
 Using conditionals

  class Node{
     char operator;
     double value;
     Node left;
     Node right;
     double evaluate(){
       switch(operator){
        case '#': return value;
        case '+': return left.evaluate() + right.evaluate();
        case '*" return left.evaluate() * right.evaluate();
        case ...  // edit this for each new operator
       }
    }
 }

 Big problem on this:
  graphic representation,
  Node
  op:char
  value: double
  left: Node
  right:Node
 --------------
   evaluate():double

Julia could not figure out the analysis here <- first time to memorize this analysis, and also try to learn reasoning

    Analyzing attributes

                           #      +        *
function                      yes     yes
value                  yes
left                              yes     yes
right                            yes     yes

Two different behaviors are fighting here, (see the above table),
if you are the operation node, then you need your left and right child; whereas value node, you just need value.


Either you need value or you need left and right, but you never need both.
One class have multiple tasks entangled, polymorphism is through if statement, not through polymorphism.

video time:  11:42/38:24
Let us break it up:
     Node
   --------------
   evaluate(): double
         |                                  |
ValueNode                         OpNode
  value: double                   op: char
---------------                       left: Node
 evaluate: double                right: Node
                                          ----------------
                                          evaluate(): double
As showing above, break Node into ValueNode and OpNode, so ValueNode does not have left and right child because of no meaning over there.


Operations and values

abstract class Node{
   abstract double evaluate();
}

class ValueNode extends Node{
    double value;
    double evaluate(){
           return value;
    }
}

class OpNode extends Node{
   char operator;
   Node left;
   Node right;
   double evaluate(){
         switch(operator) {
             case '+': return left.evaluate() + right.evaluate();
             case '-':  return left.evaluate() + right.evaluate();
             case ...   // edit this for each new operator
         }
    }
}

How to extend this? Every time you add a new operator, need to hold on source code, and add code in switch statement, how to make it better?

Tree looks like:

          OpNode
              +
    /                            \
ValueNode         OpNode
       1                         *
                        /                    \
                 ValueNode      ValueNode
                        2                     3


OpNode divides into AdditionNode  and MultiplicationNode

           OpNode
         ------------------
         left: Node
         right: Node
        ------------------
         evaluate(): double

 AdditionNode                                 MultiplicationNode
----------------------------                    --------------------------
   evaluate(): double                           evaluate(): double


  abstract class Node{
           abstract double evaluate();
  }

  class ValueNode extends Node{
       double value;
       double  evaluate(){
          return value;
       }
 }

  class abstract OpNode extends Node{
  Node left;
  Node right;
  abstract evaluate();
  }

  video time:   14:39/38:24

  Operation classes
  class AdditionNode extends OpNode{
      double evaluate(){
         return left.evaluate() + right.evaluate();
      }
}

  class MultiplicationNode extends OpNode{
     double evaluate(){
          return left.evaluate() + right.evaluate();
     }
 }

 Now, the new tree diagram:

      AdditionalNode
              +
    /                            \
ValueNode         MultiplicationNode
       1                         *
                        /                    \
                 ValueNode      ValueNode
                        2                     3

Julia's C# implementation, the SOLID principle applied solution. Here is the code.


Further exploration

Define toString() prints the infix expression placing parenthesis only when necessary.

Add new math operators: exponentiation, factorial, logarithm, trigonometry


Summary

A polymorphic solution is often better because:

1. new behavior can be added without having the original source code, and
2. each operation/concern is separated in a separate file which makes it easy to test/understand.

Prefer polymorphism over conditionals:

switch almost always means you should use polymorphism
if is more subtle ... sometimes an if is just an if

Repeated Condition

  22:36/38:24

Two piles

piles of Objects                                             pile of Construction
. business logic                                             . factories
. the fun stuff                                                . builders
                                                                      . Provider<T>
. given the collaborators needed                   .created and provides collaborators (Denpendency                                                                                        Injection)

Construction
 class Consumer{
   Consumer(Update u) {...}
}

class Factory{
  Consumer build(){
      Update u = FLAG_i18n_ENABLED? new I18NUpdate() : new NonI18NUpdate();

       return new Consumer(u);
  }
}

Benefits

Conditional is localized in one place
No more duplication
Separation of responsibilities, and global state

Common code is in one location
Testing independently easily, and in parallel
Looking at the subclasses makes it clear what the differences are

When to use polymorphism

Behavior changes based on state
Parallel conditionals are in multiple places in code

Be pragramatic

You will still have some conditionals

Question and answers:
Argument:   Easy to read switch statement    vs  a lot of subclasses
File over thousand line of length
Easy to create a new class
Single responsibility
Behavior is controlled by a lot of flags     vs.   a lot of classes collaboration

Julia's comment:
1. Julia watched the video over 3 times, she likes the teaching and sample code.

2. Julia likes to refactor the C# code, learn OO design. Strongly recommend this video to friends.

3. C# code using conditional implementation, one class Node. Here is the link.




Monday, June 11, 2018

The interface segregation principle

June 11, 2018

Introduction


It is one of principle of SOLID principles. I like to do some study on the principle called the interface segregation principle.

I noticed that the principle is so easy to follow by reading the blog.

Friday, January 13, 2017

Code Review: SOLID principles

January 13, 2016

Introduction

Julia found out that code review is a really very good to teach and learn. SOLID principle is such a nice topic for her to catch up - a new begining of 2017.

Study

Write down some notes, and prepare to do more research on this study.

community wiki, very nice lecture about SOLID - click here.

Please put together C# code in the above code review and post here as well.

January 19, 2017  9:00pm - 10:28pm

- spent 90 minutes to go over the encapsulation lecture.


Saturday, June 16, 2018

Julia Chen - top 10 debut study

June 16, 2018

Introduction


I learned the word debut less than one years ago, it is called Elina Svitolina top 10 debut.

I had two onsite experience, one is in June 2016; and the second one is in June 2018. I just could not believe that I totally am different person with more confidence this year. I shared the story how I played Hackerrank contests and got first gold medal in 2017. I had chance to get myself ready in 2 weeks for system design, and actually I learned advanced web architecture using Microservice, I know how to quickly catch up a project like system design by asking help, get some private coaching from best coach in the world. I learned how to manage a few things in less than three weeks.

I also had chance to share my experience, how happy I am to help me as a mock interviewer. I did work with a Harvard graduate with computer science degree, taught him how to write code to apply SOLID principle. No one gave him the feedback before, so he could not tell what to work on next on this issue.

Certainly I still have some issues to deal with wishful thinking, and also a healthy doze of anxiety, but with my coach's help, I just quickly recover and go back to routine to do more practice, happy as I am like one month ago.

Top 10 debut


The study topic is how to advance myself from top 200 to top 100? top 100 to top 10?

In professional tennis sport, top 200 to top 100 is hard to stay with. You have to play qualification in order to get in big grand slam matches.

From top 100 to top 10, usually the club of top 10 is very hard to get in. Those players are more mature and do not show any emotion on the matches, and will catch up if the first set is down.

This May I quickly passed the phone screen using 28 minutes coding question. This is the first time in my history I can pass the phone screen. I did not do any code screen.

I need more practice in order to learn how to work on onsite experience with data structure and algorithm.

Am I top 200? Top 100? How can I advance myself to top 10 club?

Look at those can challenge? Can you image that I can design a can challenge drill for hard level algorithm? See one minutes I can solve how many hard level algorithm just by talking about the optimal solution and idea to solve it.

Leadership skills


I feel more confident to take rejection and also I am very happy to learn things, stay positive and open to new ideas.

I decide to learn those leadership principle and apply them to my daily work as well.

Tuesday, December 22, 2015

OO principles - The Open / Closed Principle

Dec. 22, 2015

Three Approaches to Achieve OCP

  1. Parameters (Procedural Programming)
  2. Inheritance / Template Method Pattern
  3. Composition / Strategy Pattern
1. Parameters (Procedure Programming)
Allow client to control behavior specifics via a parameter
Combined with delegates/lambad, can be very powerful approach

2. Inheritance / Template Method Pattern
Child types override behavior of a base class (or interface)

3. Composition / Strategy Pattern
Client code depends on abstraction
Provides a "plug in" model
Implementations utilize inheritance; Client utilizes Composition

Read the blog:
http://code.tutsplus.com/tutorials/solid-part-2-the-openclosed-principle--net-36600
http://www.objectmentor.com/resources/articles/ocp.pdf
http://stackoverflow.com/questions/59016/the-open-closed-principle

A friend told me that he subscribes
https://www.pluralsight.com/

So, Julia subscribed code school first starting this Dec. 2015, and later pluralsight.com. Two schools are different.

Video watch:

https://www.youtube.com/watch?v=MvyG_ODng3w

Code School Live: JavaScript Best Practices Q&A

https://www.youtube.com/watch?v=k9xwJoprEMY

Principles of Object Oriented Design (2 - The Open-Closed Principle) 28 minutes 

https://www.youtube.com/watch?v=qP6MroshYvM&index=8&list=PLD4GnSXHpkQ2_eKG5fKzszXs5hYcEsft7

I Learned HTML and CSS, Now What?

http://blog.codeschool.io/2014/09/30/learned-html-css-now/

http://support.pluralsight.com/knowledgebase/articles/491274-what-s-offered-at-code-school-vs-pluralsight

Wednesday, November 30, 2016

codereview.stackexchange.com - Julia's new school (II)

Nov. 30, 2016

Introduction:
Julia was so excited to read so many experts's well-written answers first time, on live sites. She just could not believe that she enjoys reading so much.

Julia only can read one post a time. Also, Julia likes to write down what she likes to work on after reading those posts.

Detail:
Find 10 favorite reading on code review:
Search keyword, HackerRank, and choose tab - votes

http://codereview.stackexchange.com/search?tab=votes&q=HackerRank

1.   http://codereview.stackexchange.com/questions/139896/determining-if-the-kangaroos-will-land-in-the-same-position

The answer Julia really likes to read again and again:
http://codereview.stackexchange.com/a/139898/123986

Will come back to write more.

2. Design talk, junior level coding skills -> great ideas to improve
http://codereview.stackexchange.com/questions/36482/rpsls-game-in-c


3. Follow the advice as well -
http://codereview.stackexchange.com/questions/11233/responsive-adaptive-website-code

4. Interview task - SOLID Priciples and TDD (Dec. 4, 2016)
http://codereview.stackexchange.com/questions/41834/interview-task-solid-principle-and-tdd/41843#41843

5. ChrisWue - what questions are answered.
http://codereview.stackexchange.com/users/30346/chriswue


6. Play with code, and write two versions: OO version, old school version as well.
http://codereview.stackexchange.com/questions/36395/rock-paper-scissors-lizard-spock-challenge/36402#36402

7. Julia just loves to read:
http://codereview.stackexchange.com/questions/107581/check-if-more-engineers-are-happy-than-not-happy/107594#107594

Thursday, August 4, 2016

Leetcode 124: Binary Tree Maximum Path Sum - Single Responsibility Principle (SRP)

August 4, 2016

 If you do not have idea how to solve the Leetcode 124, please read the blog first, warm up with ideas to solve the problem:
http://juliachencoding.blogspot.ca/2016/08/leetcode-124-binary-tree-maximum-path.html



The maximum path sum in the above tree is highlighted using red color, node 6->9->-3->2->2. Any two nodes in the tree can form a unique path, and the choice of path is N^2, N is the total nodes in the tree.

Creative way to solve the algorithm problem:

Review S.O.L.I.D. principles, one of principle - Single Responsibility Principle. 

Use SRP to write the function, one task a time. 
1. Work on a simple problem first:
Maximum value end by root in a binary tree - in other words, maximum value from the root node to any node in binary tree

https://gist.github.com/jianminchen/8f3ec942e90bcdca5a1569d1a70e92df

Goal: be able to write the function in 10 minutes, verify code with static analysis.

1. Step 1: write a simple recursive function - preorder traversal. 
A: Pay attention to negative value node. 
(if both left and right child node's value are negative value, maximum value path ending at root node is root node's value itself; value >= root node's value) -> come out formula: line 98, maximum value of 3 values. 
  
B: Avoid if statement, just get minimum value through 3 values, make it one line statement - no if/else discussion of left/right child value > 0.

Only 5 lines of code. Short and concise.




2. Add one more task in the above function -

Usually the function should be designed to work on one task only. Need to add a second task to the function. 

Based on the simple problem - maximum value end by the root node, add one more task to the function:
maxValueCrossRoot calculation. (bottom up solution)

Try to calculate the maximum path sum cross the root node in the tree. 

https://gist.github.com/jianminchen/5eab22189f0fd7a58aa4fbc56b725dd8

Add 2 more lines of code: line 104, 105, add one more input argument - ref int maxCrossRoot, 3 places update

Goal: complete the code change in 10 minutes. 

2. Step 2: add 2 lines code (line 104, line 105), 3 changes - add one more argument (line 96, line 101, line 102):


So, overall, less than 20 minutes code writing. Follow the above 2 steps - write a function to complete the first task, and then, add second task to the function. 

Questions and Answers:

1. How to make this algorithm an easy one? 
A few people complain that the algorithm is too tough to work on through their blogs. Julia also spent hours to work on it in 2015, and then, Feb. 2016. 

In August 2016, Julia spent hours to review the algorithm, wrote 2 blogs.  

For easy to write, try SRP techniques, work on maximum path end by root first, then piggyback the max path cross the root. It will help to ease the stress. 


I learned to stay and work hard every day to get the chance to be the best. - Karolina Pliskova
Julia, can you repeat the sentence word by word?