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
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
29 30
• Make it expressive (self-documenting, comments, etc.) 2. Prepare tests to assure the behavior after the code is
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
• Data clumps • Solution: Substitute algorithm or use an Adapter
• 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
• Obscured intent
• Code should be as expressive as possible
3 4
9 0
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
• Result of copy-pasted code actually is in
• Solutions: extract method, extract class, pull-up method, • Keep together things that change together
Template Method pattern • Inappropriate intimacy
• Dead code (code that is never used) • Classes that know too much about one another
• Usually detected by static analysis tools • Smells: inheritance, bidirectional relationships
• Speculative generality • Solutions: move method / field, extract class, change bidirectional
to unidirectional association, replace inheritance with delegation
• "Some day we might need this …"
• The "YAGNI" principle
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
• Move an expression inline • Convert a set of type codes (constants) to enum
• 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
• Alternatively use the Decorator pattern
6 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
code that adheres to a coding standard • Detecting potential bugs and performance issues
• Can detect many types of common, hard-to-find bugs
• FindBugs: Uses static analysis to look for • Use “bug patterns”
bugs in Java code Address address = client.getAddress();
if ((address != null) || (address.getPostCode() != null)) {
• Standalone Swing application NullPointerException
...
}
• Eclipse plug-in
• Integrated into the build process (Ant or public class ShoppingCart {
Maven) private List items;
Uninitialized field public addItem(Item item) {
items.add(item);
}
}
95 96
24
97 98
97 98
99
99
25