09 Programming
09 Programming
1 2
3 4
3 4
1
5 6
Programming style
Proper programming styles
• Coding • Use constants for all constant values (e.g. tax
convention/standard
rate).
• Use variables whenever possible
• Always declare constants before variables at
the beginning of a procedure
• Always comment code (especially ambiguous or
misleading code), but do not over comment.
• Use appropriate descriptive names (with/without
prefixes) for identifiers/objects (e.g. btnDone).
5 6
7 8
7 8
2
9 10
9 10
11 12
11 12
3
13 14
13 14
15 16
15 16
4
17 18
17 18
19 20
19 20
5
21 22
21 22
23 24
23 24
6
25 26
27
2
8
27 28
7
Code Refactoring When to Refactor?
• What is refactoring of the source code? • Bad smells in the code indicate need of refactoring
• Improving the design and quality of existing source • Refactor:
code without changing its behavior • To make adding a new function easier
• Step by step process that turns the bad code into • As part of the process of fixing bugs
good code (if possible) • When reviewing someone else's code
• Have technical debt (or any problematic code)
• Why we need refactoring? • When doing test-driven development
• Code constantly changes and its quality constantly • Unit tests guarantee that refactoring does not change
degrades (unless refactored) the behavior
• Requirements often change and code needs to be • If there are no unit tests, write them
changed to follow them
2 3
9 0
29 30
3 3
1 2
31 32
8
Refactoring Tips
• Keep refactoring small
• One at a time
• Make a checklist
• Make a "later" / TODO list
• Check-in / commit frequently
• Add tests cases
• Review the results
• Pair programming
CODE
• Use tools (Visual Studio + add-ins / Eclipse + plugins /
others)
REFACTORING
Live Demo
3
3
33 34
35 36
9
Code Smells: The Bloaters (2) Code Smells: The Bloaters (3)
• Long parameter list (in / out / ref parameters) • Oddball solution
• May indicate procedural rather than OO style • A different way of solving a common problem
• May be the method is doing too much things • Not using consistency
• A set of data are always used together, but not organized together • Class doesn't do much
• E.g. credit card fields in the Order class • Solution: Merge with another class or remove
• Combinatorial explosion • Required setup / teardown code
• Ex. ListCars(), ListByRegion(), ListByManufacturer(), • Requires several lines of code before its use
ListByManufacturerAndRegion(), etc. • Solution: use parameter object, factory method, IDisposable
• Solution may be the Interpreter pattern (LINQ)
3
37 8
37 38
39 40
10
41
• May break the Liskov substitution principle • Hard to find them, easy to miss some
• Solution: move methods, move fields, reorganize the code
• Inappropriate static field
• Strong coupling between static and callers
• Static things cannot be replaced or reused
4
2
41 42
4 4
3 4
43 44
11
Code Smells: Dispensables (2) Code Smells: The Couplers
• Duplicated code • Feature envy
• Violates the DRY principle • Method that seems more interested in a class other than the one it
4 4
5 6
45 46
Code Smells: The Couplers (2) Code Smells: The Couplers (3)
• The Law of Demeter (LoD) • Message chains
• A given object should assume as little as possible about the • Something.Another.SomeOther.Other.YetAnother
structure or properties of anything else • Tight coupling between client and
• Bad e.g.: customer.Wallet.RemoveMoney() the structure of the navigation
• Indecent exposure • Middle man
• Some classes or members are public but shouldn't be • Sometimes delegation goes too far
• Violates encapsulation • Sometimes we can remove it or inline it
• Can lead to inappropriate intimacy
• Tramp data
• Pass data only because something else needs it
• Solutions: Remove middle-man data, extract class
4 4
7 8
47 48
12
49
49 50
51 52
13
Rafactoring Patterns (3) Rafactoring Patterns (4)
• Two classes are tightly coupled à merge them or redesign • Complex expression à split it into few simple parts
them to separate their responsibilities • A set of constants is used as enumeration à convert it to
• Public non-constant fields à make them private and define enumeration
accessing properties • Too complex method logic à extract several more simple
• Magic numbers in the code à consider extracting methods or even create a new class
constants • Unused classes, methods, parameters, variables à
• Bad named class / method / variable à rename it remove them
• Complex boolean condition à split it to several • Large data is passed by value without a good reason à
expressions or method calls pass it by reference
5 5
3 4
53 54
55 56
55 56
14
Data-Level Refactoring Data-Level Refactoring (2)
• Replace a magic number with a named constant • Create a local variable for local purposes rather than a
• Rename a variable with more informative name parameter
• Replace an expression with a method • Convert a data primitive to a class
• Additional behavior / validation logic (money)
• To simplify it or avoid code duplication
• Convert a set of type codes (constants) to enum
• Move an expression inline
• Introduce an intermediate variable • Convert a set of type codes to a class with subclasses with
different behavior
• Introduce explaining variable
• Change an array to an object
• Convert a multi-use variable to a multiple single-use
• When you use an array with different types in it
variables
• Encapsulate a collection
• Create separate variable for each usage
5 5
7 8
57 58
59 60
15
Class-Level Refactoring Class Interface Refactorings
• Change a structure to class and vice versa • Extract interface(s) / keep interface segregation
• Pull members up / push members down the hierarchy • Move a method to another class
• Extract specialized code into a subclass • Split a class / merge classes / delete a class
• Combine similar code into a superclass
• Hide a delegating class
• Collapse hierarchy
• A calls B and C when A should call B and B call C
• Replace inheritance with delegation
• Remove the man in the middle
• Replace delegation with inheritance
• Introduce (use) an extension class
• When you have no access to the original class
6
• Alternatively use the Decorator pattern 6
1 2
61 62
6 6
3 4
63 64
16
65 66
65 66
67 68
67 68
17
69 70
69 70
71 72
71 72
18
73 74
73 74
75 76
75 76
19
77 78
77 78
79 80
79 80
20
81
82
81 82
83 84
answer and the other does not • Start with data that revealed defect
• Keep paring it down (binary search “by you” can help)
• Can't find "very happy" within
• Often leads directly to an understanding of the cause
• "I am very very happy to see you all."
• When not dealing with simple method calls
• Can find "very happy" within
• The “test input” is the set of steps that reliably trigger the
• "I am very happy to see you all." failure
• Same basic idea
83 84
21
85 86
85 86
87
88
87 88
22
89 90
89 90
91 92
91 92
23
93 94
93 94
95 96
95 96
24
97 98
97 98
99
99
25