Sunday, November 29, 2015

Study time - watch CppCon videos

Nov. 29, 2015

Julia likes to get some idea how unit test can be done as a developer, and also in C++. She likes to adventure out and see if she can get ideas how to build up good habit to do unit test. 
Notes from video:
Less code = More Software
Let Julia read those sentences and laugh about mistakes she made as well:
1. Complexity is one of the biggest problems with software if not THE biggest.
2. It is much easier to create a complicated "solution" than to really solve a problem.
3. Much software complexity is accidental not inherent to the problem solved.
4. It starts in the small, one statement at a time.
5. Architects and developers need to value Simplicity!
  . Good Abstractions are the key, as are
  . Managing Dependencies (Avoid global variables)
6. Software needs to be simpler to solve more complex problems.
7. Simple software requires work and skill but pays off in the long run.

   (4:06/5:49)
    Quotes by Sir C.A.R. (Tony) Hoare (quick sort algorithm inventer in 1959/1960) 
     "Inside every large problem, there is a small problem trying to get out."
     
          Bad design vs good way: 
          one way is to make it simple that there are no obviously no deficiencies, and the other way is 
          to make it so complicated that there are no obvious deficiencies. 
          The first methods is far more difficult

C++ test-driven development

Another video watched in Sunday evening: 

CppCon 2014: Titus Winters "The Philosophy of Google's C++ code" 

4k-ish C++ engineers in Google

CppCon 2015: Bjarne Stroustrup “Writing Good C++14”

CppCon 2015: Herb Sutter "Writing Good C++14... By Default" ( Julia rating: A+, Nov. 30, 10:00-11:11pm)
https://www.youtube.com/watch?v=hEx5DNLWGgA

CppCon 2015: Sean Parent "Better Code: Data Structures"












Wednesday, November 25, 2015

Testing and Refactoring Legacy Code

Nov. 25, 2015
Testing and refactoring Legacy Code ( Julia rating: very good! Definitely watch again, and practice demo code using C# language. )

Julia watched the video, now she knew better about dependency injection, design, and also unit test. The lecture is excellent. MockitoJunitRunner/ Spring is used in the demo, TripDAO inject is demoed to add for better code. 

The lecture in the video is to work on a legacy code in Java, and then, the code is analyzed, refactored, and test code is also added. Julia follows 100% the thinking process, great time to learn. Will review the part to do refactoring in the video. 

Notes taken down:
Craftsmen at work
. Write readable and maintainable code
 - Code must express business rules
. Strive for simplicity
. Know your tools well (i.e. frameworks, shortcuts)
. Work in small and safe increments
- Commit often
. Embrace changes, be brave
. Boy scout rule / No broken windows

Book reading: software craftsmanship
Professionalism Pragmatism Pride
Sandro Mancuso

The verse I like it as well, "How it is done is as important as getting it done".
The story in early 90s to have his code reviewed by the manager in his 20s, really a good story.
200 lines of code, and the cases are the following:

1: allocate memory in one method and deallocate it in another method - risk of memory leak, temporal coupling
2. block of lines, reduce eight line to 2 by thinking harder
3. Try/ catch block too big
4. name of this variable / method, what do they mean?
5. Hard-coded bit - if we want to change where it points to, need to open it, change it, recompile it, and redeploy the entire application
6. Code duplication all over the place
7. A big method - how much we would need to keep in our heads if every single method were that big? What about making them smaller and naming them according to their behavior.
8. It is not respectful - a few lines of code, no one else could understand. No idea what the code does. some cryptic ode in there, trying to show how clever.

Julia had this kind of experience as well in 2014, but Julia now is a big fan of OO principles, SRP - single responsibility principle is her favorite one. And then, open/ close principle, how to estimate the probability of change and then create new class based on the odds, she just loves the idea.

Ref:


Sunday, November 22, 2015

Study time - Learn dependency injection, and others

Nov.22, 2015

This Sunday morning, Julia spent time to work on learning dependency injection, and really had great time to get concrete ideas what to learn in this OO design principles, S.O.L.I.D. Here are the videos she watched:

1. Understanding Dependency Injection (DI) & IOC


2. Dependency Injection using Microsoft Unity Application block ( DI IOC) - 30 minutes training (Julia's comment: so great the video, Julia follows every step and then understand whole idea using third party container to do dependency injection)

Julia tries to catch up a lot of things last 5 years, but OO principles, dependency injection is just a new thing for her. She likes the learning, and also enjoys the great teaching from those videos. Compared to Leetcode algorithms problem solving, this should be pass; in other words, not so difficult and intimidating. Most important, do something as well besides watching the video, maybe, short code to practice, sharing; a short note to help understand the topic in the video.

Julia likes to write code, and she believes that being a good software developer, also she has to develop the skills to write, enjoy writing the blogs :-), and also find different challenging tasks in the daily life.

More videos on Sunday afternoon from 4:00pm - 11:30pm, enjoyed Google employee presentation, and two Microsoft employees's.

1. Codemania 2014: Scott Hanselman - Angle Brackets, Curly Braces, JavaScript & Assembler


2. Rob Ashton - "Javascript sucks and it doesn't matter"


3. Jon Skeet - "Back to basics: the mess we've made of our fundamental data types"


4. Going Beyond Dependency Injection

5. 10 Rules of English Communication For developers







Saturday, November 21, 2015

Study time - OO design, principles and testability


Nov. 21, 2015

Spent one hour to watch the video of topic: (Julia's rating A+) from 10:20am - 11:23am. Try to go outdoor to play tennis and get some workout in this freezing temperature. Come back later to get more notes written down, and help myself to continue to learn on this topic.

"Michael Feathers - the deep synergy between testability and good design"
https://www.youtube.com/watch?v=4cVZvoFGJTU

some  notes:  (Julia's comment, I made all the mistakes in the talk, that is the reason I like it; start to learn OO design)
 
   1. video time 11:43/50:49
   Solving Design Problems
   Solving Testing Problems
   solving design problems means solving testing problems.


   Testing pain
   State hidden in method
   You find yourself wishing you could access local variables in tests.
   Your method is so long.
    Analysis for reasons:
    Method are too long, SRP violations   <- Julia's comment: agree! 
    More than 20 lines <- not good
    usually 5 - 10 lines
    matching human cognitive ability - small thing, focus on one thing, little thing

   video time  14:36/50:49
   Difficult setup
   Instantiating a class involving instantiating 12 others
   Need to factor the class into small pieces - you always can do that

   Interface / Class / Object
   too much coupling      <- Julia's comment: made mistakes before, will be more careful!
   concrete pain in the testing, but the problem is in the design.

   video time:  17:25/ 50:49
   Incomplete shutdown
   Piece of your code lose resources and you never realize it until you test.
   In detail, for example, you got to the shop, after the work, does not clean up after yourself; in C++, resource leak. In test environment, class should take itself better.
   Classes Don't Take Care of themselves, Poor Encapsulation <- Julia's comment: still remember in C++ destructor, need to free the memory.

   video time: 19:46/ 50:49
   State-Leaks Across Tests
   The state of one test affects another
   For instance, share static mutable data through the tests.   So, one test is depending on another test's actions.

   Singletons or other forms of Global mutable state <- Julia: look into more later. 

   video time: 22:27/50:49
  Framework frustration
  Testing in the presence of a framework is hard
  Insufficient domain separation  <- Julia'a comment: watch again, example for domain separation. 

  video time: 24:39
  Difficult mocking
  You find yourself writing mocks for objects returned by other objects
  Law of Demeter Violations  <- Julia's comment: get more familiar with the law. 
  For example, A ->B->C->D, a chain of dependencies to get something. Client code like A, B, C, D, those dependencies hurts you on compile time, also in conceptual, you have to know too many clients in order to do the piece of work. So, mocking is from fake A to fake B to fake C to fake D, real big pain.

   video time: 26:58
   Difficult Mocking - 2
   Hard to mock particular classes
   Answer: Introduce interface  <- Julia's comment:  Good point!
 
 video time: 28:07
  Hidden effects:
  You cannot test a class because you have no access to the ultimate effect of its execution.

   Reason: Insufficient separation of concerns, encapsulation violation

  Hidden inputs  - same type of things comparing to Hidden effects.
  There is no way to instrument the setup conditions for a test through the API. 
  Reason: Over-Encapsulation, insufficient separation of concerns.

  video time: 30:31
   Unwieldy parameter lists
  It is too much work to call a method or instantiate a class
  Reason: Too many responsibilities in a class or method
  
  video time: 32:07
  Insufficient Access
  You find yourself wishing you could test a private method.
  Reason: Too many responsibilities in a class 

   Test Thrash
   Many unit tests changes whenever you change your code
   Symptons: unit test always fails
   reason: Open / Close violations
   In detail, Close for modification / Open for extension
   class, function, need to have a small, tight focus, (Julia agrees, matching cognitive principles, small tight focus!)
   small piece, easy to reason

   Why? small function, small test.
   Good design follows cognitive principles. Small detail makes people easy to recognize.  

   The Golden Hammer <- another name for dependency injection. 
   dependency injection

   Groping Test Tools 

   Best example Julia's favorite:
   a team many years ago, every class member/method is public; what is problem?
   Should be a lot of things encapsulated, and a small API to access it.
   Make tests too brittle.

   using medical condition to help understand the OO design,
   people do not feel the pain - easy to break bones, and others, can not live long

   So, every one of us hates pain, but pain is the learning experience.

   video time: 45:24
   Testing isn't Hard. Testing is Easy in the Presence of Good Design.

Saturday evening video:

Escaping the Technical Debt Cycle - Michael Feathers
https://www.youtube.com/watch?v=7hL6g1aTGvo

Read the blog to understand Law of Demeter - "Principle of least knowledge"

http://javarevisited.blogspot.ca/2014/05/law-of-demeter-example-in-java.html

http://javarevisited.blogspot.sg/2012/03/10-object-oriented-design-principles.html

Fast App Dev using Dependency Injection, Code First EF, and SOLID Design - SVNUG Presentation 32 (Julia comment: surprisingly great! good presentation, code with demo. Learn a lot!)
https://www.youtube.com/watch?v=zY1kzXPD568


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.




Sunday, November 15, 2015

book reading: 97 Things Every Programmer Should Know (I)

Nov. 15, 2015.

 I like to tell how I get here to read this book - 97 things every programmer should know. It is a long story, but it can be described as this flow:

Julia works on leetcode questions (January 2015) ->
Challenged on August, 2015 about SOLID OO principles (Only know / remember S, basic decoupling, work on interface)
-> procedural code's concern, try to follow DRY principles, Oct. 2015
-> Learn SOLID priciples through videos in Nov., 2015:
-> Recommended reading: the book

Spent 3 hours to read the book on Sunday morning, take some notes about my favorite ideas:

1. Act with prudence - Seb Rose

"doing it right"   vs "doing it quick"

Julia's comment: thinking about it later :-)  Prudence means " be careful".

2. Apply Functional Programming Principles - Edward Garson

Julia's comment:
   Look into the term: "high degree of referential transparency"
   Questions from Julia, list a 3-5 principles of functional programming principles, most popular ones.

3.  Ask, "What Would the User Do?" (You are not the user) - Giles Colborne
Julia's comment:
     Look up the term: the false consensus bias - psychologists call it.

4. Automate your coding Standard - Filip van Laenen

Julia's comment: Look up the meaning of "antipatterns", things talked about are interesting: test coverage, coding standard. Read the article later.

5. Beauty is in simplicity - Jorn Olmheim

Julia's comment: Four things we strive for in our code:
   Readability (1), maintainability (2), speed of development (3), the elusive quality of beauty (4)
Simple objects with a single responsibility, with simple, focused methods with descriptive names.
Desirable goal is to have short methods of 5-10 lines of code. (Julia likes this argument!)

6. Before you refactor - Rajith Attapattu

Julia's comment: great topic, and good to hear some advice.

7. Beware the Share - Udi Dahan

8. The Boy Scout Rule - Robert C. Martin (Uncle Bob)

Julia's favorite: Make it better: improve name of one variable, or split one function into two smaller functions. Or break a circular dependency, or add an interface to decouple policy from detail.

And more about team spirit, help one another and clean up after one another.

9. Check Your Code First before looking to blame others - Allan Kelly
    Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth.
    http://www.allankelly.net/

10. Choose Your tools with Care - Giovanni Asproni
      existing tools - components, libraries, and frameworks
http://www.atlantec.ie/giovanni-asproni-to-be-added/
 
11. Code in the language of the Domain - Dan North
consulting service:
http://dannorth.net/about/

12. Code is Design - Ryan Brush
http://conferences.oreilly.com/strata/stratany2014/public/schedule/speaker/138579

13. Code layout matters - Steve Freeman

Julia is still working on the code layout; she thinks that the good layout helps, her favorite book: the art of readable code

15. Code Reviews - Mattias Karlsson
 Code review - increase code quality and reduce defect rate.

used to be:  Lead programmer does the review, architect reviews everything.

16 Coding with Reason - Yechiel Kimchi

http://programmer.97things.oreilly.com/wiki/index.php/Coding_with_Reason

Julia likes the idea -
1. Try to reason about software correctness by hand
2. Automated tools are preferable but not always possible
3. a middle path - reasoning semiformally about correctness
    Julia likes this middle path, in detail,
   To divide all the code under consideration into short sections - from a single line, such as a function call, to blocks of less than 10 lines - and argue about their correctness.

Julia likes to memorize those good advices, so just write it down word by word.
1. Avoid using goto statements, as they make remote sections highly interdependent.
2. Avoid using modifiable global variables, as they make all sections that use them dependent.
3. Each variable should have the smallest possible scope. For example, a local object can be declared right before its first usage.
4. Make objects immutable when relevant.
5. Make the code readable using spacing, both horizontal and vertical.
6. Make the code self-documenting by choosing descriptive name for objects, types, functions, etc.
7. If you need a nested section, make it a function. <- Julia's favorite: avoid nested section, add a function
8. Make your functions short and focus on a single task. <-  great advice, obey it.
The old 24-line limit still applies. Although screen size and resolution have changed, nothing has changed in human cognition since 1960s. ( 24 lines, Julia can do it! )
9. Function should have few parameters ( four is a good upper bound). This does not restrict the data communicated to functions: Grouping related parameters into a single object benefits from object invariants and saves reasoning, such as their coherence and consistency.

17. Convenience is Not an -ility - Gregor Hohpe

It is a great topic about API design. A good API follows a consistent level of abstraction, exhibits consistency and symmetry, and forms the vocabulary for an expressive language.

API design reading, found one through search:
http://lcsd05.cs.tamu.edu/slides/keynote.pdf

18. Deliberate practice

Leading Lean Software Development (Addison-Wesley Professional)

19. Domain-Specific Languages

https://about.me/mhunger

20 Do not afraid to break things - Mike Lewis

21. Encapsulate Behavior, Not just State - Julia's favorite article

http://www.researchgate.net/profile/Einar_Landre/publications

http://programmer.97things.oreilly.com/wiki/index.php/Encapsulate_Behavior,_not_Just_State

Examples:
  It is easy to find a class with a single 3,000-line main method, or a class with only set and get method for its primitive attributes.
Analysis: do not understand the object-oriented thinking, do not take advantage of the power of objects as modeling constructs.

Given an example, 3 classes: Customer, Order, and Item.
A Customer  object is the natural placeholder for the credit limit and credit validation rules.
An Order object knows about its associated Customer, and its addItem operation delegates the actual credit check by calling customer.ValidateCredit(Item.Price()).

Less experienced OO developer, design one objects: OrderManager or OrderService to wrap all business rules. In the design, Order, Customer, and Item are treated as little more than record types.
All logic is factored out of the classes and tied together in one large, procedural method with a lot of internal if-then-else constructs.

But, these methods are easily broken and almost are impossible to maintain. Because encapsulation is broken.

22. Hard work does not pay off - Olve Maudal

23. Know your limits
http://www.boost.org/doc/libs/1_34_0/people/greg_colvin.htm

24. A message to the Future - Linda Rising

Her website:
http://www.lindarising.org/

Julia really likes the short story written in the chapter. The problem solved is difficult, and the solution should be just as difficult for everyone (maybe even for themselves a few months after the code was written) to understand and maintain. But, the code should be easy to understand.

25. Only the code tells the truth - Peter Sommerlad

https://www.youtube.com/watch?v=XLsZkA77h8c
Notes from video:
Less code = More Software
Let Julia read those sentences and laugh about mistakes she made as well:
1. Complexity is one of the biggest problems with software if not THE biggest.
2. It is much easier to create a complicated "solution" than to really solve a problem.
3. Much software complexity is accidental not inherent to the problem solved.
4. It starts in the small, one statement at a time.
5. Architects and developers need to value Simplicity!
  . Good Abstractions are the key, as are
  . Managing Dependencies (Avoid global variables)
6. Software needs to be simpler to solve more complex problems.
7. Simple software requires work and skill but pays off in the long run.

Famous Quotes by Sir C.A.R. (Tony) Hoare
1. Inside every large problem, there is a small program trying to get out.
2. There are two ways of constructing a software design:
   1. one way is to make it so simple that there are obviously no deficiencies, and
   2. the other way is to make it so complicated that there are no obvious deficiencies.
   The first method is far more difficult.

Good advice:

 1. Strive for good names.
 2. Structure your code with respect to cohesive functionality, which also naming.
 3. Decouple your code to achieve orthogonality.
 4. Write automated tests explaining the intended behavior and check the interfaces.
 5. Refactor mercilessly when you learn how to code a simpler, better solution.
 6. Make your code as simple as possible to read the understand.

- to be continued.

More reading about authors:

1.  Enjoy reading the blog of one of authors:

To junior developer:

http://dearjunior.blogspot.ca/2014/11/make-implicit-concepts-explicit-in-code.html

Note:

Eric Evans, the thought leader of Domain Driven Design.

http://dearjunior.blogspot.ca/2012/03/dry-and-false-negatives.html


Saturday, November 14, 2015

OO design principles - DRY - Don't repeat yourself principle

Nov. 14, 2015

It is so great to find something to work on this weekend of November. My favorite time to study the video:

The Don't repeat yourself princple, part 2

https://www.youtube.com/watch?v=wweNdRuM64g&list=PLD4GnSXHpkQ2_eKG5fKzszXs5hYcEsft7&index=2

Video time: 30:15/31:07
Summary
. Repetition breed errors and waste
. Abstract repetitive logic in code
. Related fundamentals:
  . template method pattern
  . command pattern
  . dependency inversion principle
Recommended reading:
  . The pragmatic programming: From Journeyman to Master
  . 97 Things Every Programmer Should Know.

So, Julia found one book to read this weekend, 97 Things Every Programmer Should Know.

Further reading: (Nov. 18, 2015)
Template method pattern:
https://en.wikipedia.org/wiki/Template_method_pattern

Sunday, November 8, 2015

testing, automation and testing patterns

Nov. 8, 2015

  Watch the video:

Automated Testing Patterns and Smells

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

Julia is a developer in the city of Vancouver last 5 years, she enjoyed the understanding how to minimize time 70% by following one simple principle: DRY - Do not repeat yourself.

For instance, to calculate something, the same code repeats twice; Just a simple example, Julia does not like to see the code repetition in the C# code, so she gives out a try to use base class, and then, merge to one function applying to the base class. But, all other repetitions are everywhere, so she cuts other places similar to the one, 2 to 1. So, do a math, the code needs change for cases 2 x 2 x 2, 3 place duplication, becoming 1 x 1 x 1; Done, reduce the 7/8 work to work with design, unit test, and bugs related to design. (similar ideas seen video, watched on Nov. 13, 2015 - https://www.youtube.com/watch?v=bxQK7hcVyGs&list=PLD4GnSXHpkQ2_eKG5fKzszXs5hYcEsft7)

Julia tries to contribute the ideas to show how important it is to following DRY principle, and then, reduce test cases, improve code quality, and then, shorten time to work on a project.

Back to the video, Julia likes to write down the notes from the video, she does not have time to read 600 pages book, but she knows the tip: get a good video, google talk, and then, invest 2-3 hours:

1. video time 16:07/59.33
What is a " Test smell"
1. duplicate code, hard coded values, etc.

A set pf symptoms of an underlying problem in test code. Like duplicate code, breaking DRY principle.

In the talk, using changing diaper as an example, how to know when to change diaper? When diaper stinks.

code smells - visible problems in test code
behavior smells - test behaving badly
project smells - testing-related problems visible to a project manager

2. video time 19:27 / 59:33
What's a "Test Pattern"?

A "test pattern" is a recurring solution to a test automation problem
- E.g. A "Mock Object" solves the problem of verifying the behavior of an object that should delegate behavior to other objects

Test Patterns occur at many levels:
- Test automation strategy pattern
 recorded test vs scripted test
- Test design Patterns
 implicit setup  vs delegated setup
- Test coding patterns
  assertion method, creation method
- Language-specific test coding idioms
  expected exception test, constructor test

3. video time 20:28/59:33
Common code smells
  • conditional test logic
  • hard to test code
  • obscure test
  • test code duplication 
  • test logic in production 
4. Example to explain, best part
video time 22:16/59:33

1. Better assertion
2. Hard-wired test data - what is the relationship between those data? What is math? Do we need math? 30, why it is not 1, 19.99, why it is not 2, 69.96, why it is not 3? 6 months later, what is business logic?
    Hard-wired test data - will lead to fragile test

3. Introduce custom assert

  Avoid any conditional test logic in the test method - make less test code.
  Problem of conditional test logic is not sure what you are testing. <-  Julia likes this argument
  use customer assert, make a compaction of the code.

video time 28:58 / 59:33
4. Automated fixture teardown

tear down logic is a smell, such as, to separate business logic with presence logic

explicitly create deleteAllTestObjects instead of those complicated logic checking - nested try methods.

5. video time 32:07 / 59:33
Obscure test - irrelevant information

create address
create ..                               vs   createAnnoymousCustomer       vs createAnnoymounsInvoice
create customer                         createAnnoymounsInvoice

Hide detail in creation method - encapsulation, what is level of info - different levels info stays in one function - create more functions - each function much easy to be understandable, easy for unit test, variable scope less than a few lines

6. Test coverage, rapid test writing

Work outside in, create functions not existed yet, type test what you like to look

- Julia's comment:
If the code she wrote, it seems that the task is not showed in Leetcode questions, that means the code is not abstracted, not using object-oriented programming, cannot be unit test easily, people cannot read it without too much memorization, one function does all kinds of tasks; results? just too much time wasted for development, maintenance, testing, and it is bad behavior, not a pro. 


7. video time
44:08/ 59:38
Reducing Erratic Tests - Shared Fixture

Build new Shared Fixture for each run
- Avoids Unrepeatable Tests
- When:
 >> Lazy Setup
>> Setup Decorator
>> SuiteFixture Setup

Fragile Tests:
Causes:
Interface Sensitivity
- Every time you can change the SUT (S- , U- , T- tear down), tests won't compile or start failing
- You need to modify lots of tests to get things "Green" again
- Greatly increases the cost of maintaining the system

Behavior Sensitivity
- Behavior of the SUT changes but it should not affect test outcome
- Caused by being dependent on too much of the SUT's behavior.

Data sensitivity

Context sensitivity
- something outside the SUT changes
e.g. system time/date, contents of another application

46:19/ 59:33
Hard to test code
. code can be hard to test for a number of reasons:
- too closely coupled to other software
- No interface provided to set state, observe state
- Only asynchronous interfaces provided

. Root cause is lack of design for testability
- comes naturally with Test-Driven development
- Must be retrofitted to legacy (test-less) software

. Temporary workaround is Test Hook
- Becomes test logic in production (code smell) not removed.

50:17/59:33
What Does it take to be successful?
Programming Experience
+ xUnit Experience
+ Testing Experience
+ Design for Testability
-  Test smells
+ Test Automation Patterns
+ Fanatical Attention to Test Maintainability

read the website:
http://xunitpatterns.com/

Julia's comment:
Source code should be only written for machine to understand             - 20%
Source code should be readable for herself after 6 months / years        - 20%
Source code should be minimal - DRY principle - All other principle for easy to understand,
relax for herself - any time                                                                     - 30%
Source code should be fun to read, with documented unit test cases, log history etc.                                           - ?