S. O. L. I. D. As a Rock Copyright © 2015-2016 by Curt Hill Introduction • The SOLID acronym has been called the first five principles of OO Design • Introduced by Robert Martin – Acronym by Michael Feathers • Before we consider this lets consider bad design Copyright © 2015-2016 by Curt Hill Three Traits of Bad Design • Rigidity – It is hard to change because every change affects too many other parts of the system • Fragility – When you make a change, unexpected parts of the system break. • Immobility – It is hard to reuse in another application because it cannot be disentangled from the current application Copyright © 2015-2016 by Curt Hill SOLID • • • • • S – Single Responsibility principle O – Open Closed principle L – Liskov Substitution principle I – Interface Segregation principle D – Dependency Inversion principle Copyright © 2015-2016 by Curt Hill Single Responsibility • A class should have only a single responsibility – It should do just one thing • One alternative to responsibility that is suggest is a reason to change – If you can think of more than one motive for changing a class, then that class has more than one responsibility • If a class has multiple responsibilities we say that they are coupled Copyright © 2015-2016 by Curt Hill Example • We have a Rectangle class that is used by two other classes – A computational geometry class – A GUI drawing class • The Rectangle class now has two distinct responsibilities – Provide a model for of geometry – Provide the ability to draw on a surface • If the GUI drawing class changes we may need to also change geometry class Copyright © 2015-2016 by Curt Hill More • Coupled responsibilities tend to lead to fragility • A change in one class forces a change in another – This may cause breakage Copyright © 2015-2016 by Curt Hill Open Closed • You should be able to extend a classes behavior without modifying it • Modules should be designed to never change – If the code works leave it alone • When requirements change the behavior is extended – Add new code but not by changing code that works Copyright © 2015-2016 by Curt Hill Extensions • Extensions take mostly two forms • We add a new method that may utilize some of the existing and working code • We derive a new class from the existing class and add extensions there • Violations of this principle tend to cascade changes into other modules, which often break – The code becomes fragile Copyright © 2015-2016 by Curt Hill Liskov Substitution • Derived classes must be substitutable for their base classes • Any module that uses a class, should be able to use any descendent class without knowing it • Attributed to Barbara Liskov, a recent Turing award winner Copyright © 2015-2016 by Curt Hill Violations • When the Liskov substitution principle is is violated then the module must know about all the descendants – Even those not created when the module was designed • What we typically see in this case is lots of Ifs that determine the type of the object – This is a bad thing Copyright © 2015-2016 by Curt Hill Digression on Interfaces • An interface in a general sense is that collection of public methods that a class presents • An Abstract Base Class is an interface • In Java there is an Interface construct which is a contract – An implementing class promises to provide certain methods • In C++ we do not need the Interface – We have multiple inheritance Copyright © 2015-2016 by Curt Hill Interface Segregation • Make fine grained interfaces that are client specific • We would like our interfaces to be cohesive • Non-cohesive interfaces typically have groups of interfaces – Different clients will use different groups of interfaces Copyright © 2015-2016 by Curt Hill Interface Pollution • Interface pollution is when a class has an interface that only some of its sub-classes require • Consider the door example next Copyright © 2015-2016 by Curt Hill Doors • Suppose we want a door class – It may be locked or unlocked – It may be open or closed • Now we derive from that a timed door that sounds an alarm if the door is open too long – The timed door registers with a a timer object – When the time elapses the timer object does a call of a method to alert the timed door object Copyright © 2015-2016 by Curt Hill Door Again • • • • We create a timer client We then derive door from that We then derive timed door from door Now door has a timer client that it does not need – Its subclass does, but not it • This is an example of interface pollution – Door has been polluted with what it does not need Copyright © 2015-2016 by Curt Hill Continuing • Timer client was one interface while door was another • They are completely different • Thus they should be separated, ie. Interface Segregation • Stated again, the Interface Segregation Principle says that clients should not be forced to depend on interfaces that they do not use Copyright © 2015-2016 by Curt Hill • Dependency Inversion High level modules should not depend upon low level modules – Both should depend on abstractions • Abstractions should not depend on details – Details should depend on abstractions • Said another way – Concrete classes may depend on abstract classes or on concrete classes – Abstract classes should not depend on concrete classes Copyright © 2015-2016 by Curt Hill Layers • In many software systems we have layers – Such as operating systems • Each layer provides an interface to the upper layer • Each layer uses the lower layer to accomplish the tasks • This is a well known technique Copyright © 2015-2016 by Curt Hill Inversion? • The layering appears to make more abstract things dependent on more concrete items • In the Dependency Inversion Principle we are not considering the same thing • Rather we are talking about interface dependencies Copyright © 2015-2016 by Curt Hill Finally • These five principles form a foundation for object design • Like several “rules of thumb” they may be violated – But only with very good cause – Convenience is not such a cause • These are principles we will also apply in refactoring Copyright © 2015-2016 by Curt Hill
© Copyright 2026 Paperzz