Software Design Principles and Design Patterns in eXtreme

Software Design Principles and Design Patterns in eXtreme Programming Johan Ullén [email protected] 2013-03-05 ... changing what already exists but...

0 downloads 71 Views 144KB Size
Software Design Principles and Design Patterns in eXtreme Programming Johan Ullén [email protected] 2013-03-05

Abstract A study in software design and software architecture where it is tested how you can use spikes to guide a team into always think about and consider what principles, design and architecture to use. A common problem with a group of new developers is that they do not have much experience in how to implement design patterns to make a flexible and easily expandable software. I pose the question: “How can we use spikes to guide a team into considering and ultimately choosing suitable design patterns and architecture?”.

Contents 1. Introduction 2. Values, principles and practices 2.1.

Values

2.2.

Principles

2.3.

Practices (Patterns)

2.4.

Code smells

3. Research Approach 3.1.

The EDA260 Project

3.2.

Methodology Analysis

3.3.

Alternative approach

4. Experiences with the team 4.1.

Comparison to other teams

4.2.

Reasons for the problems

5. Conclusion 6. Further research 7. References

1. Introduction This paper explores the idea of how to convey a coding standard to less experienced developers in an eXtreme Programming (from now on denoted XP) team to help them develop code that is easier to maintain and expand upon. By using spikes to study both patterns to use in the code and the code produced itself, a coach should be able to induce the developers with solid coding standards. In section 2 the theories of what a good coding standard is, in particular for object-oriented programming, will be discussed. In section 3 the background of this research and methodology is explained, including a description of the project used for research. A theoretical approach of how to convey to less experienced developers how to and why they should use these standards will be put forward and discussed. And finally in section 4 an analysis of a team, a group of students taking the course EDA260, will be presented. This approach has been taken several times in other studies for the same course, most similarly in Marcus Jacobsson and Magnus Weinberg's study in 2006 [JAC&WEI06], but also Martin Larsson and Stefan Johansson [LAR&JOH12] in 2012 and Mårten Kongstad [KONG02] in 2002. This paper will focus more on the principles of design rather than design patterns themselves.

2. Values, principles and practices Kent Beck and Cynthia Andres [BECK&AND04] explain that XP consists of values, principles and practices. According to Beck values are the roots of the things we like and do not like in a situation, the ideas of purpose and direction. Practices are evidence of values, they are clear and focused, a practice is somethings you do. Values and practices are widely separated and thus we have principles to connect them. Principles are domain-specific guidelines, when you understand the principles of the domain you are working in you can apply your values at the practice level. When you do not understand the principles you can still follow the practices but it is a blind following, uninformed. 2.1 Values The main values of XP are communication, simplicity, feedback, courage and respect according to Beck and Anders [BECK&AND04]. While all values require some work to implement simplicity seems to be the most difficult one because it is the most abstract one. The focus of this paper relates strongly to simplicity and the principles and practices that goes with it. Here is a brief description of the values according to Beck and Anders [BECK&AND04]: Communication – "When problems arise in development, most often someone already knows the solution...", [BECK&AND04] Communication is the power of sharing knowledge. Without communication each individual would have to learn everything from the very beginning and every invention ever made would be made over and over again and very rarely progressed upon. Communication also helps creating a team feeling, it gives a sense that we work together, because we share our problems and our progress. When you communicate you include everybody you communicate with in what you have done, are doing or are going to do. Simplicity – "Simplicity is the most intensely intellectual of the XP values. To make a system simple enough to gracefully solve only today's problem is hard work.", [BECK&AND04] Making something simple often requires the most skill. Compare with any professional athlete who can make the toughest tasks you can imagine seem like child's play. Feedback – "No fixed direction remains valid for long...", [BECK&AND04] XP as well as

other agile development methods, described in The Agile Manifesto [FOW&HIG01], relies heavily on short iterations. One of the main reasons to have short iterations is so that you can make informed decisions and that can only happen through feedback. Courage – "Courage is effective action in the face of fear", [BECK&AND04] Daring to do something when encountering problems and not being afraid to claim the common ownership of the code written by someone else in the team are both examples of how courage plays in XP. Respect – "If members of a team don't care about each other and what they are doing, XP won't work. If members of a team don't care about a project, nothing can save it. ", [BECK&AND04] 2.2 Principles SOLID is an acronym for a set of principles identified by Robert C. Martin (Uncle Bob) [BOB] in the early 2000's. The first five and the name giver to SOLID are the single responsibility principle (SRP), the open close principle (OCP), the Liskov substitution principle (LSP), the interface segregation principle (ISP) and the dependency inversion principle (DIP). All refer to principles of simple class design and can easily connected the value of simplicity to the use of design patterns such as singleton, abstract and template method. Single responsibility (SRP) – SRP is when you make sure a class only do a single thing. To identify a violation of single responsibility, you see if a class has more than one reason for a change. When you find a violation of single responsibility you should separate that class through re-factoring into as many new classes as you find responsibilities. To do this you may have to use an interface between the rest of the program and the newly separated classes so the view from outside is still uniform. Keeping single responsibility in mind and having the courage to re-factor away violations of it may keep you safe from problems later on. Open closed (OCP) – OCP means that a class is open for extension but closed for modification. In practice it means you should use abstractions. When building an application you should use a least common denominator approach, when later you find that smallest common denominator is not enough you can add functionality to it, not by changing what already exists but by extending it with an abstraction level. The typical

example is that of shapes; a shape essentially have an area and that is it, as long as you only need the area that is what you should have. If you later need a circle with a radius to calculate the area you do not modify the shape but extend upon it to make the circle. That way you can later extend the shape with a rectangle without worrying about the circle, and later still extend the rectangle with a square. The smallest common denominator is still safe from any modifications and you have your extended functionality. Liskov substitution (LSP) – LSP is when you use abstractions without letting the user method know it. In the example of the above shapes a method getting the area of a shape does not need to know if it is a rectangle, a circle or any other shape. Interface segregation (ISP) – ISP is violated when an interface inherits an interface because some classes of the first interface also need the second interface. By the use of an adapter to the second interface we can keep the classes that do not need it without it and still let those that need it use it through the adapter. Alternatively, and more commonly, multiple inheritance can be used, letting one class implement both interfaces while those classes not needing the second one only implements the first one. Dependency inversion (DIP) – DIP is avoiding dependency from higher to lower level modules. Low level modules often need to be interchangeable and only seem to retain the same functionality because of similar functionality. For example a file writer and a console writer are very similar in the view of the module using them. By using an abstraction between the higher and lower level modules that both sides depend on you can change lower level modules freely and use them with other higher level modules. "High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.", [BOB] 2.3 Practices (Patterns) If SOLID are the principles of simplicity then patterns are the practice of it. Patterns tell us in detail how we can do an implementation by looking at what is commonly done by others. Patters often focus on a particular part of the implementation such as creation, structure or behaviour. In all types of patterns we can still see a relation to the simplicity value through the principles that have been discussed above. While it is useful to know about and be able to work with many patterns, it is usually very specific how they are

used, the observer pattern for example is best suited for an application with shared information for example of a database that has input and output with several modules, like different display views. As the application in the EDA260 project is For the project in EDA260 the most fitting patterns are mainly a database with a few different sub applications with many similar and some different functionality the singleton, abstract factory, builder, factory method, strategy and template method. Since these seven patterns are enough for the point, and to avoid bloating the paper only these will be described. According to the authors of Design Patterns elements of reusable objectoriented software [DP95] these are: Singleton – "Ensure a class only has one instance, and provide a global point of access to it.", [DP95] In case of the EDA260 project this applies to the data structure. Abstract factory – "Provide an interface for creating families of related or dependent without specifying their concrete classes.", DP95] In case of the EDA260 project this could apply to the different types of races implemented. Builder – "Separate the construction of a complex object from its representation so that the same construction process can create different representations.", [DP95] Can only apply to the different race types implemented in the EDA260 project. Factory method – "Define an interface for creating an object, but let subclasses decided which class to instantiate. Factory method lets a class defer instantiation to subclasses.", [DP95] Can be used in the EDA260 project to allow different race implementation use slightly different modules, for example to sort result lists. Strategy – Define a family of algorithms, encapsulate each one, and make them interchangeable.", [DP95] Strategy lets the algorithm vary independently from clients that use it. Useful for the slightly different behaviour of the different races in the EDA260 project. Template method – "Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.", [DP95] Also useful for the slightly different behaviour of the different races in the EDA260 project. For further knowledge on design patterns refer to Design Patterns Elements of Reusable

Object-Oriented Software [DP95] or Implementation Patterns [BECK07]. 2.4 Code smells Problems with code is often identified as code smells or bad smells in code. This relates strongly to principles and patterns. Principles are the cure for code smells, and are, vice versa, violations of principles. With patterns you should ideally not have the problem of bad smells in code. This is code smells as described by Coding Horror – Code Smells [CS06]: Large classes/methods – classes and methods become too big to easily grasp what they do, a sign of violation of single responsibility, consider re-factoring out functionality. Shotgun surgery – when a small change forces you to do more small changes in many different places, consider re-factoring to remove dependencies. Duplicate code / oddball solution – the same code in two places equals changes need to be done in two places, consider re-factoring out the duplicate code to a single method. Lazy classes / message chains / middle man – a class that does nothing more than passing on information and instructions, consider removing the middleman. Divergent change – a class gets more and more functionality which after some time may give it more than one responsibility, a violation of single responsibility, consider separating. Comments – comments is a sign that the code is not understandable enough as it is, rewrite code with clearer naming convention. Long parameter lists – Not all information need to be present in a class, often it is enough to know where the information can be acquired. Temporary fields – when you do not use all information available, consider removing the information you do not use. Dead code – when you forget to delete code that is no longer used, delete. Inappropriate Intimacy – Classes that interact too much or know too much about each other.

3 Research Approach The research has been done within the very narrow frames of a project done in the courses EDA260 and EDA270 at Lund institute of technology (LTH). Due to the nature of the courses it is not viable to replicate the research or do it differently with minor changes in several iterations. Ideally a research like this should be done multiple times until a satisfying result has been found. In the following sections the project and the methodology used will be described. 3.1 The EDA260 Project Second year students LTH are taking a course, EDA260, in software development in a team focusing on agile development and in particular XP according to [BECK&AND04]. There are usually between eight and ten developers in a team. The team-coaches are two senior students (such as the author of this paper), who are taking a course in coaching for software development in a team, EDA270. Besides coaching the team the seniors students are doing an in depth study related to the project (such as this paper). The customers are fictive and acted by various professors at the faculty of computer science at LTH. The project lasts for six iterations, each with a two hour planning session and an eight hour development session. Aside from the scheduled time the developers also have four hours of spike time, two of which should be dedicated to an XP focus and the other two hours should be used for something beneficial to the team. The goal of the project is to make an application that can handle in an Enduro race. The early product only need to handle single point to point races but as the project continues more functionality, such as lap races and stage races are added and the final product will usually have some complex structure supporting different races. A complete description (in Swedish) of the project can be found at the course website for EDA260 [EDA260] under "Projekt". 3.2 Methodology Analysis The original idea was to in every iteration let all team members use some spike time to research a design pattern and determine how and if it fits into the application they are working on. This, however, has been problematic for several reasons. The predicted restrictions that the developers need to use their spike time to solve other more urgent

problems with the development proved valid, such as time for re-factoring, estimations of stories, preparation for documentation and identification of bad smells in code. Another problem has been that the developers have had a hard time visualizing what to do during a development cycle and could therefore not analyse a pattern to suit it properly. Finally the developers are simply too inexperienced with both development of this size, and, despite having recently taken a course in the subject, they do not have enough knowledge about software design patterns. Similar to what Jacobsson and Weinberg's [JAC&WEI06] discovered this way of suggesting patterns, or practices, has proven ineffective. The developers already understand the values but lack the knowledge to apply the practices we give them. After about half the project time the approach was changed to focus on principles instead of practices. The principles contain a lot less information and are therefore much easier to absorb, they also do not take much time and can thus be combined with other more time-consuming tasks without exaggerating the developers spike time. 3.3 Alternative approach Focus should have been on principles from the very beginning. An easy way to approach it would have been to have the developers study the SOLID principles. One to two of them for the first three iterations and after than introduce the concept of practices in the form of patterns. This way the developers would have a firmer grasp on the underlying principles before they had to understand the patterns and would then find the more specific solutions of patterns. The code would then be cleaner and free from most bad smells and it would also be easier for the developers to both identify and choose suitable patterns for their application.

4 Experiences with the team As mentioned above the methodology used in the first part of the project proved less successful. The developers had a hard time definitely deciding on a structure, and until the later stages of the development they seemed reluctant to re-factor the code freely. This resulted in violations of all the SOLID principles. For example a huge class with nearly all the functionality of the application, inappropriate intimacy and methods which has resulted in the need for shotgun surgery. In the third iteration this became so bad that no progress at all was made in the iteration and the forth iteration was dedicated primarily to re-factoring the code. The team decided to implement a local SQL database during spike time and when integrating it during the development time they cleaned up the code significantly. 4.1 Comparison to other teams Looking at the team and comparing it to other teams taking the same course as well as to teams from previous years of the course there seem to be a common problem. After discussion with other coaches, and reading Jacobsson and Weinberg's who discuss very similar problems in their paper from 2006 [JAC&WEI06]. It appears that the team examined was not alone in implementing an application of lower standards, in terms of maintainability and expandability. The similarities between the groups suggests that the problems is related to the groups, unfortunately there is no different control-group to compare with. The most obvious similarities perceived are that all developers in these teams are young and they are computer engineering students, more precisely most of them are second year computer engineering students. 4.2 Reasons for the problems The problem's seen can probably be appointed to inexperience which is not unsurprising to see in young student in the beginning of their education. It can thus be recommend to use the simpler approach suggested in section 3.3 when coaching younger, i.e. Inexperienced, developers. Another possible reason for the problems is the experience spread, within the low experience range the developers are in. Simplified it could be said that the developers in

the group examined came from two groups with slightly different programming backgrounds. Some had been developing code informally for many years, others had first encountered programming when they started the computer engineering program at university. The developers with less experience where probably easier to affect, but since they where less confident they would not trust any new-found intuition compared to the more vocal developers. Those more vocal developers would often be comparably more experienced but perhaps not in the best of ways. A developer who is already set in a certain way of programming is less inclined to accept a new approach to how to implement a solution. As they are more confident they voice their ideas and control the common direction of the group in a possibly negative way. Again, approaching the group with the less controlling principles, as explained in section 3.3, would make them consider the way they are coding without removing the benefits from their experience. A third possible reason for the problems could be a lack of communication, which is one of XP's five values, explained in section 2.1. While the team did not seem to have any problems communicating it is not certain they communicated about the correct things. Many of the team members reflected at the end of the first iteration that they had communicated very well and felt confident that the team worked very well together. At the same time they contradicted this statement by stating that they had found it hard to agree on anything and set a clear path for the project.

5. Conclusion While the research is inconclusive I still think this is a viable method to work with a less experienced team. Before you focus on good practices (good design patterns), you need good principled and good values. While the values are easily conveyed and understood the principles are as easily missed. Not until a development team has clean code can they make good use of the more advanced practices.

6. Further research To further understand the problems you can face, and how to solve them, while coaching an inexperienced software development team, further research must be done. As with agile methods only small changes and good feedback can help optimizing the process of coaching a team through principles and to practices of simplicity. I suggest additional research to be done with this according to the alternative approach, described in section 3.3, and then following similarly with results from that research until a way has been found that coaches inexperienced developers to write code with the SOLID principles, described in section 2.2, in mind and using suitable patterns, like those described in section 2.3.

7. References [BECK07] Beck K.: Implementation Patterns, Addison-Wesley 2007. ISBN 978-0-321-41309-3 [BECK&AND04] Beck K., Anders C.: Extreme Programming Explained 2nd Edition, Addison-Wesley 2004 ISBN 978-0-321-27865-4 [DP95] Gamma E., Helm R., Johnson R., Vlissides J.: Design Patterns Elements of Reusable Object-Oriented Software, Addison-Wesley 1995 ISBN 978-0-201-63361-0 [CHORM03] Chromatic: Extreme Programming Pocket Guide, O’Reilly 2003 [FOW&HIG01] Fowler M., Highsmith J.: The Agile Manifesto, 2001 http://www.ddj.com/184414755, 2013-03-03 also http://www.drdobbs.com/the-agile-manifesto/184414755, 2013-03-03 [BOB] Martin R. C. (Uncle Bob): butunclebob.com http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod [JAC&WEI06] Jacobsson M., Weinberg M.: Simple Code and Design, LTH 2006 http://fileadmin.cs.lth.se/cs/Education/EDA270/Reports/2006/JacobssonWeinberg.pdf, 2013-03-03 [LAR&JOH12] Larsson M., Johansson S.: Code Smells / Refaktorisering, LTH 2012 http://fileadmin.cs.lth.se/cs/Education/EDA270/Reports/2012/LarssonJohansson.pdf, 2013-03-03 [KONG02] Kongstad M.: Om Simple Design in Practice, LTH 2002 http://fileadmin.cs.lth.se/cs/Education/EDA270/Reports/2002/Kongstad.pdf, 2013-03-03 [CS06] Coding Horror – Code Smells, 2006 http://www.codinghorror.com/blog/2006/05/code-smells.html, 2013-03-03 [EDA260] Course website for EDA260 http://cs.lth.se/kurs/eda260_2012/, 2013-03-03