CSC/ECE 517 Summer 2008/wiki3 3 lc: Difference between revisions
No edit summary |
|||
(45 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
=Low Coupling= | =Low Coupling= | ||
This document seeks to explain low coupling and how exactly you may recognize the degree of coupling in your existing code. Hopefully you will then be able to integrate this concept into your own programs to reduce coupling where necessary. | |||
==Problem Description== | ==Problem Description== | ||
We introduced the idea of low coupling in Lecture 20, and used the Observer pattern as an example in Lecture 23. But we | We introduced the idea of low coupling in Lecture 20, and used the Observer pattern as an example in Lecture 23. But we have really only scratched the surface on what there is to know about achieving low coupling. Browse the Web and the ACM DL for other information, both theoretical and practical, and produce a guide to what there is to know about low coupling. Be sure to highlight those aspects that would be appropriate for inclusion in CSC/ECE 517. | ||
== | ==Coupling== | ||
Coupling, also known as dependence, is a measurement of the degree in which two program modules | [[Image:dependency.jpg|thumb|right|150px|Figure 1: Dependency]] | ||
Coupling, also known as dependence, is a measurement of the degree in which two program modules rely on each other to complete a task. | |||
Recognizing dependencies: | |||
*A member function of class A uses an object from class B. | |||
*When making CRC cards the "collaborators" column denotes classes which depend on one another. | |||
*As seen to the right in UML diagrams a dashed line with an open arrow points to a dependent class. | |||
When two modules have a very stable interface between one another, one which does not require or even concern itself with the internal structure of the other module and you have "low" coupling between those modules. Other terms used to describe this situation may be "loose" or "weak" coupling. | |||
When a | |||
=== | Recognizing low coupling: | ||
*The number of connections between classes is low and seems more like a tree structure than spaghetti code. | |||
*Interfaces between two classes are well defined and usually only communicate through messages (independent modules) | |||
*Changes to individual classes do not require modification to their dependent classes | |||
*The number of dependent classes program wide are low | |||
=== Types of Couping === | |||
*'''Pathological/Content Coupling''' was discussed earlier and occurs when a function of class A actually uses or modifies objects/data from class B. | |||
*'''Global Coupling''' can be recognized by the use of global data variables to communicate between two classes. ie Keeping a count of the number of objects initialized using a global count variable. | |||
*'''Control Coupling''' uses a control flag to send instructions between two classes, similar to the way semaphore files were used to exchange data between multiple sessions of the same MS-DOS application. | |||
*'''Data-Structure Coupling''' occurs when a predifined amount of data must be passed between modules, much of this data may not be used but must be present to satisfy the requirements for the message to be successfully transmitted or passed. | |||
*No Data Coupling occurs when two modules do not transfer data or interact in any way. They are said to be two independent modules. | |||
==Benefits of Low Coupling== | |||
===Reduced Code=== | |||
[[Image:highcoupling.jpg|thumb|right|150px|Figure 2: High Coupling]] | |||
[[Image:lowcoupling.jpg|thumb|right|150px|Figure 3: Low Coupling]] | |||
When a module is modified in a well-structured system, one which makes use of low couping, very few subsequent modules must be modified as a result. This has obvious benefits in regards to the speed at which changes may be implemented and subsequent testing that must be performed as a result. | |||
'''Figure 2''' is a UML diagram which is meant to quickly display a system of classes that are highly coupled. Note the multitude of dependency arrows in the diagram. These dependencies are so numerous that any programmer would have a lot of classes to modify if just one change to the system was requested. This means that when testing any changes to the code a programmer may actually have problems in classes that were not actually modified while implementing the new code. This inherently increases the time and amount of code necessary to implement a single feature. Not to mention the testing which will be discussed more later. | |||
'''Figure 3''' is a low coupled system which can be easily identified by the more branch like structure of the dependency arrows. Adding a feature to this system would require only a small amount of classes to be affected and thus would limit the amount of code and testing to those classes. | |||
Code can be further reduced by simply reusing classes which have low coupling. Since they are not dependent on a lot of other classes you may use the code over and over in many different situations. Of course care must be taken that the code is not simply copied and pasted but referenced in some other means (unless you are using it in a totally different program) Code reuse is very important but not if the same code must be copied hundreds of times within the same application. | |||
===Reduced Yo-Yo Affect=== | |||
Anytime a programmer must flip back and forth between numerous classes or files to examine code you are lowering their efficiency and increasing the amount of possible mistakes in interpreting the code. The lower the coupling the less flipping between code segments or different classes one must do to read your code. For your own future code maintenance and the sanity of anyone who may later read your code reduce the Yo-Yo affect by lowering coupling between your classes. | |||
===Better Testing=== | |||
By lowering coupling a module may be tested without including a multitude of other classes or modules. By making testing easier programmers are more likely to thoroughly test code and less bugs will reside in the final version of the code. The test cases that must be created by the programmer will be simplified in a loosely coupled environment and in some cases the original test cases may be reused or only slightly modified to create a complete testing solution. | |||
===Better Encapsulation=== | |||
Anytime you can hide the design details of your program so that other modules and services may utilize a standard rarely changing interface your program will be less likely to break other modules as a result of design detail modifications. | Anytime you can hide the design details of your program so that other modules and services may utilize a standard rarely changing interface your program will be less likely to break other modules as a result of design detail modifications. | ||
This is essential to coding a well-structured system which may grow and change to the users requests or external requirements beyond the programmers control. In the every changing workplace as soon as a program has been coding and fully tested, it seems that modifications are needed or often required. | This is essential to coding a well-structured system which may grow and change to the users requests or external requirements beyond the programmers control. In the every changing workplace as soon as a program has been coding and fully tested, it seems that modifications are needed or often required. | ||
== | ==Consequences of Low Coupling== | ||
[[Image:xml.jpg|thumb|right|300px|Figure 4: XML DTD]] | |||
One of the unavoidable consequences of low coupling is reduced performance | One of the unavoidable consequences of low coupling is reduced performance, usually reduced performance is highly tolerable when compared to the increased programming efficiency and ease of future modification. The reduced performance can result from the message handling between modules or classes. Issues such as transaction integrity, data duplication, and synchronization must be taken into consideration when creating a low coupled system. If the type of messages used is under your control it is encouraged to use a flexible file format such as XML which uses [http://www.xmlfiles.com/dtd/dtd_intro.asp '''Document Type Definitions'''] to allow for clear explanations of what type of data is included and how the data should subsequently be used. | ||
==Design Patterns and Coupling== | |||
Several design patterns have big implications on the coupling of your system. These use of such patterns can increase the coupling or lower it depending on how you use them. For example a great pattern for lowering coupling is the [http://java-x.blogspot.com/2007/01/implementing-observer-pattern-in-java.html '''observer pattern''']. This pattern can be used to solve the problem of objects notifying other objects of a change in their state. The solution requires the use of a central object, called the subject, which keeps a list of all objects interested in hearing about updates to one particular object. The subject knows only a list of observers that implement the observer interface and thus loose coupling between the subject and observers can be maintained. Other patterns such as the [http://wiki.rubyonrails.org/rails/pages/MVC '''Model/View/Controller'''] can be used to separate the business logic of an application from it's GUI allowing one to be modified without necessarily affecting the other. These patterns, as well as others, can be utilized to lower coupling and ensure your programs may be maintained for many years to come. For more information on these patterns as well as any other topic covered in this wiki please view the links below. | |||
==References== | ==References== | ||
[http://javaboutique.internet.com/tutorials/coupcoh/ Java Boutique Article on Coupling and Cohesion] | |||
[http://en.wikipedia.org/wiki/Modularity_(programming) Modular Programming] | [http://en.wikipedia.org/wiki/Modularity_(programming) Modular Programming] | ||
[http://en.wikipedia.org/wiki/Information_Hiding Information Hiding] | [http://en.wikipedia.org/wiki/Information_Hiding Information Hiding] | ||
[http://en.wikipedia.org/wiki/Information_Hiding Loose Coupling] | [http://en.wikipedia.org/wiki/Information_Hiding Loose Coupling] | ||
[http://thecomcor.blogspot.com/2008/06/low-coupling.html Blog Entry on Low Coupling] | |||
[http://www.adobe.com/devnet/flex/articles/loose_coupling.html Loose Coupling in Flex Applications] | |||
[http://wiki.rubyonrails.org/rails/pages/MVC Ruby's Model/View/Controller Explained] | |||
==Tools== | ==Tools== | ||
[http://semmle.com/documentation/ Semmle Code Querying Tool (works with Eclipse)] | [http://semmle.com/documentation/ Semmle Code Querying Tool (works with Eclipse)] |
Latest revision as of 20:27, 20 November 2008
Low Coupling
This document seeks to explain low coupling and how exactly you may recognize the degree of coupling in your existing code. Hopefully you will then be able to integrate this concept into your own programs to reduce coupling where necessary.
Problem Description
We introduced the idea of low coupling in Lecture 20, and used the Observer pattern as an example in Lecture 23. But we have really only scratched the surface on what there is to know about achieving low coupling. Browse the Web and the ACM DL for other information, both theoretical and practical, and produce a guide to what there is to know about low coupling. Be sure to highlight those aspects that would be appropriate for inclusion in CSC/ECE 517.
Coupling
Coupling, also known as dependence, is a measurement of the degree in which two program modules rely on each other to complete a task.
Recognizing dependencies:
- A member function of class A uses an object from class B.
- When making CRC cards the "collaborators" column denotes classes which depend on one another.
- As seen to the right in UML diagrams a dashed line with an open arrow points to a dependent class.
When two modules have a very stable interface between one another, one which does not require or even concern itself with the internal structure of the other module and you have "low" coupling between those modules. Other terms used to describe this situation may be "loose" or "weak" coupling.
Recognizing low coupling:
- The number of connections between classes is low and seems more like a tree structure than spaghetti code.
- Interfaces between two classes are well defined and usually only communicate through messages (independent modules)
- Changes to individual classes do not require modification to their dependent classes
- The number of dependent classes program wide are low
Types of Couping
- Pathological/Content Coupling was discussed earlier and occurs when a function of class A actually uses or modifies objects/data from class B.
- Global Coupling can be recognized by the use of global data variables to communicate between two classes. ie Keeping a count of the number of objects initialized using a global count variable.
- Control Coupling uses a control flag to send instructions between two classes, similar to the way semaphore files were used to exchange data between multiple sessions of the same MS-DOS application.
- Data-Structure Coupling occurs when a predifined amount of data must be passed between modules, much of this data may not be used but must be present to satisfy the requirements for the message to be successfully transmitted or passed.
- No Data Coupling occurs when two modules do not transfer data or interact in any way. They are said to be two independent modules.
Benefits of Low Coupling
Reduced Code
When a module is modified in a well-structured system, one which makes use of low couping, very few subsequent modules must be modified as a result. This has obvious benefits in regards to the speed at which changes may be implemented and subsequent testing that must be performed as a result.
Figure 2 is a UML diagram which is meant to quickly display a system of classes that are highly coupled. Note the multitude of dependency arrows in the diagram. These dependencies are so numerous that any programmer would have a lot of classes to modify if just one change to the system was requested. This means that when testing any changes to the code a programmer may actually have problems in classes that were not actually modified while implementing the new code. This inherently increases the time and amount of code necessary to implement a single feature. Not to mention the testing which will be discussed more later.
Figure 3 is a low coupled system which can be easily identified by the more branch like structure of the dependency arrows. Adding a feature to this system would require only a small amount of classes to be affected and thus would limit the amount of code and testing to those classes.
Code can be further reduced by simply reusing classes which have low coupling. Since they are not dependent on a lot of other classes you may use the code over and over in many different situations. Of course care must be taken that the code is not simply copied and pasted but referenced in some other means (unless you are using it in a totally different program) Code reuse is very important but not if the same code must be copied hundreds of times within the same application.
Reduced Yo-Yo Affect
Anytime a programmer must flip back and forth between numerous classes or files to examine code you are lowering their efficiency and increasing the amount of possible mistakes in interpreting the code. The lower the coupling the less flipping between code segments or different classes one must do to read your code. For your own future code maintenance and the sanity of anyone who may later read your code reduce the Yo-Yo affect by lowering coupling between your classes.
Better Testing
By lowering coupling a module may be tested without including a multitude of other classes or modules. By making testing easier programmers are more likely to thoroughly test code and less bugs will reside in the final version of the code. The test cases that must be created by the programmer will be simplified in a loosely coupled environment and in some cases the original test cases may be reused or only slightly modified to create a complete testing solution.
Better Encapsulation
Anytime you can hide the design details of your program so that other modules and services may utilize a standard rarely changing interface your program will be less likely to break other modules as a result of design detail modifications.
This is essential to coding a well-structured system which may grow and change to the users requests or external requirements beyond the programmers control. In the every changing workplace as soon as a program has been coding and fully tested, it seems that modifications are needed or often required.
Consequences of Low Coupling
One of the unavoidable consequences of low coupling is reduced performance, usually reduced performance is highly tolerable when compared to the increased programming efficiency and ease of future modification. The reduced performance can result from the message handling between modules or classes. Issues such as transaction integrity, data duplication, and synchronization must be taken into consideration when creating a low coupled system. If the type of messages used is under your control it is encouraged to use a flexible file format such as XML which uses Document Type Definitions to allow for clear explanations of what type of data is included and how the data should subsequently be used.
Design Patterns and Coupling
Several design patterns have big implications on the coupling of your system. These use of such patterns can increase the coupling or lower it depending on how you use them. For example a great pattern for lowering coupling is the observer pattern. This pattern can be used to solve the problem of objects notifying other objects of a change in their state. The solution requires the use of a central object, called the subject, which keeps a list of all objects interested in hearing about updates to one particular object. The subject knows only a list of observers that implement the observer interface and thus loose coupling between the subject and observers can be maintained. Other patterns such as the Model/View/Controller can be used to separate the business logic of an application from it's GUI allowing one to be modified without necessarily affecting the other. These patterns, as well as others, can be utilized to lower coupling and ensure your programs may be maintained for many years to come. For more information on these patterns as well as any other topic covered in this wiki please view the links below.
References
Java Boutique Article on Coupling and Cohesion
Loose Coupling in Flex Applications
Ruby's Model/View/Controller Explained