how to apply design principles in pratice

7
How to apply design principles in practice? Ganesh Samarthyam, Tushar Sharma, Girish Suryanarayana HOW TO APPLY DESIGN PRINCIPLES IN PRACTICE? WWW.DESIGNSMELLS.COM

Upload: ganesh-samarthyam

Post on 16-Jul-2015

139 views

Category:

Software


2 download

TRANSCRIPT

Page 1: How to apply design principles in pratice

How to apply design principles in practice?

Ganesh Samarthyam, Tushar Sharma, Girish Suryanarayana

HOW TO APPLY DESIGN PRINCIPLES IN PRACTICE? WWW.DESIGNSMELLS.COM

Page 2: How to apply design principles in pratice

How to apply design principles in practice?

"The  critical  design  tool  for  software  development  is  a  mind  well  educated  in  design  principles"  -­‐  Craig  Larman

It is well known and widely accepted that applying design principles is essential to developing high-quality software. Booch’s object model mentions four fundamental principles viz. Abstraction, Encapsulation, Modularization, and Hierarchy for creating quality object oriented designs [2]. Table I lists these principles with their descriptions from our earlier work [1].

Conceptually, fundamental principles such as abstraction and modularization are quite generic, high-level, and seem easy to understand; however, our experience in creating designs for real-world projects shows that they are difficult to apply in practice for design problems we face on a day-to-day basis as designers! For example, consider abstraction – it is easy to say “simplify entities through reduction and generalization”; but it is difficult to understand and apply the specific techniques that are required to be followed to realize the conceptual understanding in practice?

HOW TO APPLY DESIGN PRINCIPLES IN PRACTICE? WWW.DESIGNSMELLS.COM

Page 3: How to apply design principles in pratice

One solution we found is to use “enabling techniques” for applying each of these fundamental design principles. For instance, a few specific techniques that we can employ to apply modularization principle are to:

a) Localize related data and methods together in a class b) Break-down or decompose classes into manageable size (i.e., neither too small nor

too large) c) Create acyclic dependencies between classesd) Limit dependencies by reducing the number of incoming dependencies (i.e., fan-

in) and outgoing dependencies (i.e., fan out).

Figure  I:  Fundamental  design  principles  and  the  enabling  techniques  

Figure I lists the enabling techniques we have created for Booch’s four fundamental design principles. favored since the product is always market-ready and refactoring can consistently improve the quality to sustain the product for a longer period.

Of course, it may be sometimes difficult to understand how to apply these “enabling techniques” themselves! For example, one of the enabling techniques for encapsulation is to “hide variations”. How do we “hide variations”? It is quite general and not really straight forward to understand. It requires deeper understanding and experience to notice specific actions to apply the enabling technique. Some of the guidelines that can be employed in the case of “hide variations” enabling technique are:

(a) separate algorithm from the clients that use it

HOW TO APPLY DESIGN PRINCIPLES IN PRACTICE? WWW.DESIGNSMELLS.COM

Page 4: How to apply design principles in pratice

(b) separate abstraction from its implementation so that the two can vary independently

(c) separate policy from the implementation Let us consider the first guideline (separate algorithm from the clients that use it)

with the help of a detailed example to understand how encapsulation can be applied in practice by “hiding variations” enabling technique.

Separating algorithm from the clients that use it Consider the design of a cloud based application. In such applications, security is an

important consideration and often encryption is used for securing the information stored in the cloud. Assume a class named Encryption that uses DES (Data Encryption Standard) algorithm by default in its public Encrypt() method, as shown in Figure II.

Figure  II:  Initial  design  that  requires  support  only  for  DES  algorithm  in  Encryption  class  

Now, due to changes in requirements (for instance, introducing a more secure algorithm for encryption), the class needs to support another algorithm viz. AES (Advanced Encryption Standard). The Encrypt class now has two public methods named EncryptUsingDES() and EncryptUsingAES(). It may be the case that it is required to support yet another algorithm viz. TDES (Triple Data Encryption Standard) in some cases by the Encryption class. Figure III shows the resultant design with methods such as EncryptUsingDES(), EncryptUsingAES(), EncryptUsingTDES(), etc.

Is this a good design? Is it possible to improve (i.e., refactor) this design such that:• A specific algorithm (such as DES, AES, or TDES) can be “plugged” at runtime?

HOW TO APPLY DESIGN PRINCIPLES IN PRACTICE? WWW.DESIGNSMELLS.COM

Page 5: How to apply design principles in pratice

• Reuse these algorithms in new contexts? • Easily add support for new algorithms in Encryption class?

Figure  III:  The  Encryption  class  becomes  “smelly”  

There are many solutions for this problem, but here is a solution that isolates algorithms as a separate hierarchy (see Figure IV). With this solution, the Encryption class encapsulates the variation in the algorithm in the form of a hierarchy. The hierarchy rooted in EncryptionAlgorithm (which could be an interface or an abstract class) implements specific algorithms such as DESEncryptionAlgorithm, AESEncryptionAlgorithm etc as derived classes.

With this solution: • A specific DES, AES, TDES, or any other algorithm can be “plugged” at runtime.

How? From the constructor of the Encryption class or from a suitable method in Encryption class, the object “algo” can be made to point to the required derived object of EncryptionAlgorithm type. By employing runtime polymorphism, a new algorithm can be plugged at runtime.

• We can reuse these algorithms in different contexts. Since EncryptionAlgorithm hierarchy is a separate hierarchy which concerns providing specific encryption algorithms as a service to the clients of this hierarchy, it can be easily reused in other contexts within the same application or other applications.

HOW TO APPLY DESIGN PRINCIPLES IN PRACTICE? WWW.DESIGNSMELLS.COM

Page 6: How to apply design principles in pratice

• We can easily add support for new algorithms in Encryption class. We can add new algorithm, such as support for TDES, as a new derived class of EncryptionAlgorithm type and the Encryption class (because it holds reference to a EncryptionAlgorithm object) can now use the new algorithm.

Figure  IV:  Separating  encryption  algorithms  from  its  clients  using  Strategy  pattern    

Did you identify this solution structure? Yes, it is the “Strategy pattern” which “decouples an abstraction from its implementation so that the two can very independently” [3].

An important note: This example illustrates the application of design patterns for applying the principle of encapsulation. However, applying principles might not result in a design that employs patterns.

Coming back to our discussion on applying the principle of encapsulation, this example illustrates how the enabling technique of “hide variations” can be applied in practice.

In addition, this example is also an illustration of Open Closed Principle (OCP) [4]: “Software entities should be open for extension, but closed for modification”. What does it mean? It means that an entity such as a class, component, or a module must support extending the behavior without need to modify the source code within that entity. Consider Figure III: Adding support for new encryption algorithms requires changing the entity (i.e., it is NOT open for extension) and hence violates OCP. In contrast, consider the design in Figure IV: Adding support for new encryption algorithms does not require changing the entity (i.e., it is open for extension) and hence follows OCP.

HOW TO APPLY DESIGN PRINCIPLES IN PRACTICE? WWW.DESIGNSMELLS.COM

Page 7: How to apply design principles in pratice

To summarize: Since high-level principles such as abstraction, encapsulation, modularization and hierarchy are quite generic, it is usually difficult to understand how to apply them in practice. To solve this problem, we can break-down the fundamental principles to more granular “enabling techniques” [1]. Enabling techniques not only help us to understand the fundamental principles to a greater depth but also ease the task of applying the principle in real-world situations.

References:  [1] “Refactoring for Software Design Smells: Managing Technical Debt”, Girish

Suryanarayana, Ganesh Samarthyam, Tushar Sharma, ISBN - 978-0128013977, Morgan Kaufmann/Elsevier, 2014. URL: http://amzn.com/0128013974

[2] “Object-Oriented Analysis and Design with Applications”, Grady Booch, Robert Maksimchuk, Michael Engle, Bobbi Young, Jim Conallen, and Kelli Houston, Third Edition, Addison-Wesley Professional, 2007.

[3] “Design Patterns: Elements of Reusable Object-Oriented Software”, Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, Addison-Wesley, 1995.

[4] “Object-Oriented Software Construction”, Bertrand Meyer, Prentice Hall, 1988.

About  the  Authors:        Ganesh   Samarthyam   ([email protected])   is   an   Independent   Consultant   and  Corporate  Trainer  based  in  Bangalore.    

Tushar   Sharma   ([email protected])   is   a   Technical   Expert   at   Research   and  Technology  Centre,  Siemens  Technologies  and  Services  Pvt.  Ltd.,  Bangalore.  

Girish  Suryanarayana  ([email protected])  is  a  Senior  Research  Scientist  at   Research   and   Technology   Centre,   Siemens   Technologies   and   Services   Pvt.   Ltd.,  Bangalore.    

HOW TO APPLY DESIGN PRINCIPLES IN PRACTICE? WWW.DESIGNSMELLS.COM