cakefest 2011 - coupling and cohesion
DESCRIPTION
CakeFest 2011 talk on coupling and cohesion. Code examples available on my github account, https://github.com/dogmatic69/cakefest-2011TRANSCRIPT
by: Carl Suttonhttp://dogmatic69.com
Coupling and Cohesion
Before
After
Cohesion
What is "Cohesion"● Modules / Classes do related jobs● Good: High cohesion● Bad: Low cohesion● Three levels to look at (in Cake apps)
○ The Method (does one thing properly)○ The Class (all methods are similar)○ The Plugin (collectively does *a* single job eg: "cart" plugin does not do mini
blog posts)
What is "Cohesion"
● Easier to understand● More robust● Reliability● Maintainable
● Difficult to understand ● Not DRY
Possible Pros
Possible Cons
Examples of CohesionGood:CakePHP's session class- all methods manage one set of data, the sessions (Communicational)
Bad:CakePHP's basics.php file- a bunch of utilities, related because they are not related (Coincidental)
Levels of "Cohesion"Coincidental cohesion
● Lowest level of cohesion, almost none● Parts of a module are grouped arbitrarily● related because they are not related
Eg: ● Utility classes / files● basics.php
Levels of "Cohesion"Logical cohesionParts of a module are grouped because logically they are categorized to do the same thing, even if they are different by nature.
eg: ● Putting all your model files in APP/models
Levels of "Cohesion"Temporal cohesion
● Grouped by when they are processed● the parts are processed at a particular time in program execution
Eg: ● a function which is called after catching an exception
○ closes open connections○ creates an error log○ notifies the user
Procedural cohesion● parts of a module are grouped because they always follow a certain sequence of execution● Similar to Temporal
Levels of "Cohesion"Communicational cohesion
● Parts of a module are grouped because they operate on the same data.
Eg:● SessionComponent + SessionHelper● Cache engines
Bad Model methods:
Levels of "Cohesion"Sequential cohesion
● parts of a module are grouped because the output from one part is the input to another part like an assembly line
Eg: ● a function which reads data from a file and processes the data.● Model methods like Find -> beforeFind -> _find -> afterFind -> $output
Levels of "Cohesion"Functional cohesion
● The best Type● parts of a module are grouped because they all contribute to a single well-defined task of the
module
Eg:● CakeSocket
○ Does one single job (low level network communication)
"Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away."
Checking for low cohesion● ClassesThatSeemDifficultToName● Seems like splitting it up would be easy● Tests are (much) bigger than the class/method itself● Tests fail in the same way for different reasons● Code is not DRY
Notes● Rules of premature optimisations apply● No point having hundreds of one line methods or one method classes● Sometimes a bit of low cohesion code is needed and/or better than high cohesion
(Utility classes)
CakePHP 2.0 - higher cohesion● Auth was broken into two parts
○ AuthComponent○ Authorisation Adaptor
■ Digest■ Basic■ Form■ Custom
● basic.php removed random functions● CakeRequest created
○ parts of RequestHandler, Dispacher and Controller○ request and response objects
See code examples
Before
After
What is "Coupling"● Relation between bits of code● Code A requires Code B to work● Similar to dependency (inter dependency)● Changes in Code A ripples changes to Code B● Less is more
○ Good: ([low][loose][weak]) coupling○ Bad: ([high][tight][strong]) coupling
What is "Coupling"
● Dumb code● Easier to:
○ read○ debug○ test○ reuse (DRY)○ maintain
● Cheaper / quicker to extend
● More overhead● More magic● Longer dev time / more expensive initially
Possible Pros
Possible Cons
Examples of CouplingGood (loose):CakePHP's ORM (1.x -> )- use MySQL, MsSQL, PostgreSQL or Custom with the same code
CakePHP's JS Engine (1.3.x -> )- use jQuery, Prototype, Prototype or Custom with the same codeCakePHP's Cache (1.x -> )- File, APC, XCache, Memcache or Custom
CakePHP's Sessions (1.x -> )- use cake (file), PHP, database or cache
Bad (tight):CakePHP's test suite (1.x -> )- hard coded to use Simple Test
Levels of "Coupling"Content coupling (high)
● One module modifies / relies on the internal workings of another module.
eg: ● Router::* changes● In 1.3 Helpers (without the analogue code you were stuck)
○ 2.0 can replace helper instances on the fly with another instance■ $this->Html could be MyCustomHtmlHelper extends HtmlHelper
Levels of "Coupling"Common coupling
● Two modules share the same global data.
Eg:● SessionComponent + SessionHelper
○ moving where setFlash() saved messages requires changes to flash()
Levels of "Coupling"External coupling
● Two or more modules share an externally imposed data format○ communication protocol (imap, pop3, ftp, http etc)○ device interface○ file format (csv, xml, json etc)
Eg:● EmailComponent
○ RFC 2822 - Internet Message Format● Database Driver MySQL, MSSQL etc
○ need to use SQL language
Levels of "Coupling"Control coupling
● one module controlling the flow of another● passing it information on what to do
Eg: ● Controller starting up a Component
Levels of "Coupling"Stamp coupling (Data-structured coupling)
● modules share a composite data structure and use only a part of it
eg: ● function foo($options){ return $options['bar'] * 10;}● validation methods only get the field they are validating (good)
Levels of "Coupling"Data coupling
● modules share data through, for example, parameters. ● Each datum is an elementary piece, and these are the only data shared.
eg: ● validation methods in a Model class
Levels of "Coupling"Message coupling (low)This is the loosest type of coupling. It can be achieved by state decentralization. JS Engine, Cache Engine, ORM etc
No coupling● Modules do not communicate at all with one another. ● Only time there is *no* coupling is when you have a formatted HDD :P
Eg: ● EmailComponent is not coupled directly to Models
Levels of "Coupling"Message coupling (low)
● This is the loosest type of coupling. ● Achieved by state decentralization.
Eg: ● JS Engine, Cache Engine, ORM etc● you call a main 'engine' class that calls the correct class that you need● Dependency injection● Observable
Levels of "Coupling"No coupling
● Modules do not communicate at all with one another. ● rm -rf /* will remove all coupling
Eg: ● EmailComponent is not coupled directly to Models
Checking for high coupling● Changes to code A requires changes to code B, C etc● Reuse of code is difficult / impossible● Testing is super complicated
CakePHP 2.0 - lower coupling● Auth was broken into two parts
○ Authorisation Adaptor - custom authorisation classes● Dispatcher
○ Parts moved to the Controller so its easy to change / extend (not coupled to the one cake way)
● switch helpers and components on the fly○ no need to use $this->MyCustomHtmlHelper->foo()
See code examples
Related stuff
● Coupling● Cohesion● DRY● Dependency● Cyclomatic complexity● Adapter Pattern● Dependency_injection● Observer● SRP
Links
dogmatic69CakePHPInfinitas