Upload
sohaib-akram
View
179
Download
0
Embed Size (px)
Citation preview
6/24/2009
1
Software Design DefectsSoftware Design DefectsSoftware Design DefectsSoftware Design Defects
� Design Patterns are “good” solutions to recurring design problems
◦ Where you want to be in terms of good design
� Design Defects are “bad” solutions to recurring problems
◦ Where you should not find yourself in software development
� Design Defects lessen the quality of OO architectures and impede their evolution and their maintenance
Patterns and Software DefectsPatterns and Software Defects
� To Err Is Human
� 2 categories:
◦ High-level (global) problems: AntiPatterns
◦ Low-level (local) problems: Code Smells
� “ deviations from specifications or expectations which might lead to failures in operation ”
� They describe in general what not to do
� Arise due to lack of knowledge and experience
� A good form of problem-solving approach
AntiPatternsAntiPatterns
� AntiPatterns provide patterns that have negative consequences on software development effort◦ Reality of a good number of software projects
� Help identifying problems in software◦ Bad design results from common mistakes and
misunderstandings
� Provide common vocabulary to discuss problems and their solutions in software industry
� Understanding AntiPatterns provides the knowledge to prevent or recover from them
WellWell--known known AntiPatternsAntiPatterns
� AntiPatterns are all around us. They’re often used as tools for social control.
� SOCIAL AntiPatterns
◦ Criminal
◦ Drug Addict
◦Witch
◦ PickPocket
AntiPatternsAntiPatterns� Root causes◦ Haste
� Good design is a product of careful study� Trimming budgets, unrealistic committeements� Leads to compromises in software quality
◦ Apathy� Not caring about solving known problems
◦ Narrow-mindedness� Refusal to accept widely known solutions
◦ Laziness (Sloth)� Configuration management
◦ Ignorance� Failing to seek understanding
◦ Pride� Not-invented-here syndrome: avoids using or buying already existing
products
6/24/2009
2
AntiPatternsAntiPatterns
� Describe context and causes
� Describe symptoms to detect an AntiPattern in legacy software
� Describe their consequences
� Describe a roadmap for their solution
� In this course, we shall only cover AntiPatterns related to software code
The BlobThe Blob
� Blob (Huge Class)� “ Procedural-style design
leads to one object with a lion’s share of the responsibilities while most other objects only hold data or execute simple processes ”
� Large controller class� Many fields and methods
with a low cohesion� Dependent on the data
stored in associated data classes
The BlobThe BlobLibrary_Main_Control
Current_CatalogCurrent_ItemUser_IDFine_AmountEtc.
Do_Inventory()Check_Out_Item(Item)Check_In_Item(Item)Add_Item(Item)Delete_Item(Item)Print_Catalog()Sort_Catalog()Search_Catalog(Params)Print()Issue_Library_Card()Calculate_Late_Fine()
Person
NameUser_IDItems_OutFines…
Item
TitleISBN
AuthorPublisherCostData_InQty…
Catalog
TopicInventory…
The Blob The Blob Causes and ConsequencesCauses and Consequences
� Typical Causes
◦ Lack of proper Object-Oriented architecture
◦ Prototype software evolves into a product
◦ Lack of architectural enforcement
� Consequences
◦ Modular continuity is compromised
◦ Too complex for reuse and testing
◦ Expensive to load into memory even for small operations
The Blob The Blob SolutionSolution
� Avoid it
◦ Managers should review program design regularly
� Refactor it
◦ Move behavior away from the Blob
◦ Construct cohesive classes: cohesive set of attributes and methods are encapsulated together
◦ Remove far-coupling
The Blob The Blob -- SolutionSolutionLibrary_Main_Control
Current_CatalogCurrent_ItemUser_IDFine_AmountEtc.
Do_Inventory()Check_Out_Item(Item)Check_In_Item(Item)Add_Item(Item)Delete_Item(Item)Print_Catalog()Sort_Catalog()Search_Catalog(Params)Print()Issue_Library_Card()Calculate_Late_Fine()
Person
NameUser_IDItems_OutFines…
Item
TitleISBN
AuthorPublisherCostData_InQty…
Catalog
TopicInventory…
6/24/2009
3
Spaghetti CodeSpaghetti Code� “ Ad hoc software structure makes it difficult
to extend and optimize code.”
� Code with very little software structure, lack clarity
� Implementation invokes a process flow
� Lack of structure : no inheritance, no reuse, no polymorphism
� Long methods process oriented with no parameters and low cohesion
� Procedural names of classes and methods
� Negligible degree of interaction between objects
� Use of global variables for processing
Spaghetti Code Spaghetti Code Causes and ConsequencesCauses and Consequences
� Typical Causes◦ Inexperience with Object-Oriented design
technologies
◦ Ineffective code reviews
◦ No initial software design
� Consequences◦ Code reuse is difficult
◦ Follow-on maintenance efforts contribute to the problem
◦ Software reaches point of diminishing returns: the effort involved to maintain existing code exceeds the cost of developing a new “ground up” solution
public boolean startElement(int, XMLAttrList) throws Exception {
if (!fValidating && !fNamespacesEnabled) {return false;
}if (contentSpecType == -1 && fValidating) {
...}if (... && elementIndex != -1) {
...}if (DEBUG_PRINT_ATTRIBUTES) {
...}if (fNamespacesEnabled) {
fNamespacesScope.increaseDepth();if (attrIndex != -1) {
int index = attrList.getFirstAttr(attrIndex);while (index != -1) {
...if (fStringPool.equalNames(...)) {
...} else {...}
}index = attrList.getNextAttr(index);
}}int prefix =
fStringPool.getPrefixForQName(elementType);int elementURI;
if (prefix == -1) {...if (elementURI != -1) {
fStringPool.setURIForQName(...);}
} else {
...if (elementURI == -1) {
...}
fStringPool.setURIForQName(.elementURI);}if (attrIndex != -1) {
int index = attrList.getFirstAttr(attrIndex);while (index != -1) {int attName = attrList.getAttrName(index);
if (!fStringPool.equalNames(...)) {...if (attPrefix != fNamespacesPrefix) {
if (attPrefix == -1) {...
} else {
if (uri == -1) {…
}fStringPool.setURIForQName(attName, uri);if (fElementDepth >= 0) {
fElementDepth++;if (fElementDepth == fElementTypeStack.length) {
...} } } }
return contentSpecType == fCHILDRENSymbol; }
•No Objects•Process Flow•Conditionals•Complexity•Cannot be reused
Spaghetti Code Spaghetti Code SolutionSolution
� The best way is to prevent spaghetti code by first thinking and then developing. To avoid:◦ Domain model even when it is well-understood◦ OO Analysis◦ OO Design◦ Objects should be sufficiently refined
� When adding new features, remove code defects� Write accessor functions for member variables� Refactor code into methods� Remove obsolete code� Rename classes, functions, data types to conform
to industry standards
Functional DecompositionFunctional Decomposition
� One main routine that calls several other subroutines
� Invoked subroutines are implemented as classes
� Classes with single action such as a function
� Attributes are private and used only inside the class
� The resulting code resembles a structural language like C and is incredibly complex
Functional DecompositionFunctional DecompositionCauses and ConsequencesCauses and Consequences
� Typical Causes◦ No use of OO concepts like inheritance or
polymorphism
◦ Lack of understanding of OO concepts
◦ Lack of architecture enforcement
� Consequences◦ Difficult to reuse
◦ Expensive to maintain
◦ no way to clearly document (or explain) how the system works
6/24/2009
4
Functional DecompositionFunctional DecompositionSolutionSolution
� Find the original Use Cases to ascertain features from user view point
� OO reengineering process
� Find matching OO design model
� Combine classes which assist each other
� Combine classes which try to achieve the same design objective
� Find similar subsystems (reuse of code)
Functional Decomposition Functional Decomposition A customer loan scenarioA customer loan scenario
� Adding a new customer
� Updating a customers address
� Calculating a loan to a customer
� Calculating the interest on a loan
� Calculating a payment schedule for a customer loan
� Altering a payment schedule
Functional DecompositionFunctional Decomposition OO VersionOO Version
CutCut--andand--Paste ProgrammingPaste Programming� “Man, you guys work fast. Over 400,000 lines of
code in just three weeks is outstanding progress.”
� Cut-and-Paste Programming is a very common degenerate form of software reuse that causes maintenance nightmares.
� Less experienced programmers learn by changing code of experienced developers
� Presence of several similar segments of code
� Creates code duplication
� Positive short-term consequences such as boosting line count metrics
CutCut--andand--Paste ProgrammingPaste ProgrammingCauses and ConsequencesCauses and Consequences
� Typical Causes◦ Reusable code is difficult to create and organizations prefer
short term benefits
◦ Easier to modify existing code than writing from scratch
◦ Lack of abstraction in developers
◦ Lack of knowledge of tools and technologies, hence working examples are modified to create new components
◦ Lack of forward thinking
� Consequences◦ Software defects and bugs are replicated
◦ Difficult to locate all instances of a bug
◦ Code reviews and inspections are needlessly extended
◦ Excessive software maintenance costs
◦ Duplication of testing, review, bug fixing efforts
6/24/2009
5
CutCut--andand--Paste ProgrammingPaste ProgrammingSolutionSolution
� Three step approach
◦ Identify Code duplication
◦ Refactoring duplicates into libraries or components for black-box reuse
◦ Configuration management : code inspection, reviews and validation efforts in future to avoid Cut-and-Paste Programming
Swiss Army KnifeSwiss Army Knife
� A Swiss Army knife is a brand of multi-function pocket knife or multi-tool.
� Excessively complex class interface
� Designer attempts to provide for all possible uses of the class.
� Large number of interface signatures
� No clear abstraction or focus of the class interface
Swiss Army KnifeSwiss Army KnifeCauses and ConsequencesCauses and Consequences
� Causes◦ No focused responsibility
◦ Class attempting to provide too much functionality
� Consequences◦ More != Better
◦ Confusion
◦ Maintenance problems
◦ Each interface requires implementation of items on that interface
Swiss Army KnifeSwiss Army KnifeSolutionSolution
� Describe a profile for the class
� Profile documents the way to use a complex technology
� Profile for an interface describe the signatures and parameter values
ConclusionsConclusions
� AntiPatterns provide patterns that have negative consequences on software development effort
� Each AntiPattern includes a solution + solution pair
◦ AntiPattern Solution Generates mostly negative consequences
◦ Refactored Solution Generates mostly positive benefits
� AntiPatterns are useful for refactoring, migration, upgrade, and reengineering
Code SmellsCode Smells
� “If it stinks, change it”
� Hint that something has gone wrong
� Opportunities for improving program design
� Code smells indicate the need for the application of a possible refactoring
6/24/2009
6
Code Smells Code Smells -- ExamplesExamples
� Duplicate Code◦ Duplication of bugs, tests, reviews
◦ Same (or nearly) code in multiple places
◦ Frequently the result of cut-and-paste coding
� Long Method◦ OO puts premium on short methods
◦ Long procedures always harder to understand
� Large Class◦ Class has poor cohesion
◦ Too many instance variables or methods means a class is doing too much
◦ Class interface does not provide consistent level of abstraction
Code Smells Code Smells –– More ExamplesMore Examples
� Long Parameter List◦ Programs harder to understand
◦ Difficult to reuse and change
◦ Parameter lists should be shorter in OO programs than in traditional programs
� Divergent Change◦ One class commonly changed in different
ways for different reasons
◦ Some methods changed in one case
◦ Other methods changed in another
Code Smells Code Smells –– More ExamplesMore Examples
� Feature Envy
◦ Method seems more interested in a class other than the one it is in
◦ Most common focus is data (lots of getter calls)
� Data Clumps
◦ Same data items in multiple classes
◦ Parameter lists of several methods
◦ If after deleting one from clump the rest wouldn’t make sense, a clear candidate for refactoring