for definitions in ISO 9126 Projects sometimes fail due to not having any clear definitions of "success” This standard tries to develop a common understanding of project objectives and goals, e.g. software qualities
can • diagnose it for § deficiencies § causes of failure • identify the parts to be modified “Analysability is basically the ability to understand software”
allows you to • implement a specific modification • add, modify, or enhance a feature at a reasonable cost “almost all Design Patterns are geared towards increasing design’s changeability”
can add/enhance functionality purely by adding software units and specifically not by modifying existing software units” Flexibility a special case of changeability
code Changeability is a desirable quality, but it relies on Change by Modification Change by Modification “The less I ever modify a class, the higher the probability that it will remain free of defects” Modifications carry the risk of introducing defects, and the necessary cost of avoiding them: testing, code reviewing, etc.
Change by Modification Change by Addition Behavioural changes that are introduced by adding new production code instead of modifying existing code Contrast Change by Addition avoids (risky) modifications altogether with
take a stand point with regards to the way a specified modification is implemented Flexibility In contrast, Flexibility does take this stand point and requires that no modifications are made
avoids unexpected effects when modified “I advocate the practice to avoid modifying existing code but preferably add features or modify existing ones by other means” Flexibility “any change to existing software carries a risk of introducing defects”
require that s/w can adapt to changing requirements without modifying the production code then you need to employ a SPECIAL set of design and programming techniques as well as adopt a SPECIAL mindset
still available for extension or add fields to its data structures Data Structures fields + operations e.g. it should be possible to expand its set of operations
available for use by other modules Has a well-defined, stable description (its interface – in information hiding sense) public part secret part interface 1 can be compiled, stored in a library, and made available for clients to use 2 in the case of a design or specification module: • approved • baselined in version control • its interface published for benefit of other module authors 3
module will need in its lifetime X The need for ness so developers wish to keep the module open for as long as possible so that they can address changes, and extensions by changing elements or adding new elements
until it is certain that it contains all the needed features x every developer would always be waiting for completion of another developer's job then multi-module s/w can never reach completion x in a system consisting of many modules, most modules will depend on some others but it is also necessary to close modules
it yet and any change or extension can trigger a painful chain reaction of changes or you close it in many other modules which relied on the original module directly or indirectly
A’ F G H I New clients which need A’, an adapted or extended version of A Typical situation where the needs for Open and Closed modules are hard to reconcile = client of
variants of the original module, many of them very similar, but never quite identical if you extrapolate its effects to • many modules • many modification requests • a long period of time
add/modify logic you have to: • Do it for each source tree • Write the same test cases for each source tree you have to do it in each source tree when you need to remove a defect
into completely different directions: they drift apart. After a while it is more or less like maintaining a set of completely different applications At that point, before you do any of the operations, you have to first analyse each source tree!!
We have modified A into A+, which can switch between two modes of execution In one mode it behaves like A, and in the other it behaves as expected of A’ Solution
We have modified A into A+, which can switch between two modes of execution In one mode it behaves like A, and in the other it behaves as expected of A’ Solution
if (variant == VARIANT_1) then { …. } else { …. } At points of variation, A+ looks like this: We have modified A into A+, which can switch between two modes of execution In one mode it behaves like A, and in the other it behaves as expected of A’ Alternatively, this can be a switch Solution
The potential for disaster is obvious: changes to A may invalidate the assumptions on the basis of which the old clients used A. So the changes may start a dramatic series of changes in clients, client of clients....etc Solution – Meyer’s Assessment
The potential for disaster is obvious: changes to A may invalidate the assumptions on the basis of which the old clients used A. So the changes may start a dramatic series of changes in clients, client of clients....etc B C E D this is a nightmare for the proj. mgr. the system regresses and several modules have to be re- opened for dev/test/debug/documentation
it is still better than the Copy solution. On the surface, the copy solution seems better because it avoids the ripple effect of change but in fact it may even be more catastrophic…it only postpones the day of reckoning We saw earlier the risks of an explosion of variants, many of them very similar, but never quite identical: Solution – Meyer’s Assessment solution solution
by Modification Reliability Concerns – solution relies on with risk of introducing new defects Analysability concerns – as more and more requirements are handled by parameter switching, the code becomes less easy to analyse … Responsibility erosion – the software has, without much notice, been given an extra responsibility drives towards Procedural Design Blob aka God Class Solution (Parametric solution) Christensen’s Assessment
I like to call this switch The flow of the switches themselves becomes confusing, hard to read, hard to decipher. When a new case comes in the programmer must find every place it can be involved (often finding all but one of them). Suddenly things get bad in a hurry.
Reliability solution - - - With non-OO methods, there are only only 2 solutions available to us, BOTH UNSATISFACTORY multiple maintenance problem Change by Modification CHANGE COPY
So how can we have modules that are both and ? How can we keep A and everything in the top part of the figure unchanged, … …while providing A’ to the bottom clients, and avoiding duplication of software?
With the OO concept of inheritance Inheritance allows us to get out of the CHANGE OR COPY dilemma… …because inheritance allows us to define a new module A' in terms of an existing module A, …by stating only the differences between the two A’ defines new features, and redefines (i.e. modifies) one or more of A’s features inherits from Change by Addition
able to address the needs of the moment, more general than the software’s original purpose. Hacker Spurred by a laudable desire not to redo what can be reused, our hacker starts modifying the original to add provisions for new cases solution
pollute the software with many clauses of the form if that_special_case then… if (<special case D>) then … if (<special case C>) then … if (<special case B>) then … if (<special case A>) then … switch
different hackers, the software starts resembling a chunk of Swiss cheese that has been left outside for too long in August – it has both holes and growth Hacking
the consequent OO techniques is to think of them as organised hacking Hacking The organised form of hacking will enable us to cater to the variants without affecting the consistency of the original version. Inheritance Change by Modification Change by Addition
adaptation of healthy modules If there is something wrong with a module you should fix it… …not leave the original alone and try to correct the problem in the derived module Derived Base neither OCP nor redefinition in inheritance is a way to address design flaws, let alone bugs Design Flaw