SOLID
Dependency Inversion Principle (DIP)
"Depend upon Abstractions. Do not depend upon concretions." A. High-level modules should not depend on low-level modules. Both should depend on abstractions (Interfaces). B. Abstractions should not depend upon details. Details should depend upon abstractions.
Interface Segregation Principle (ISP)
*"many client specific interfaces are better than one general purpose interface."* ISP splits too large interfaces into smaller and more specific ones so that any client it will only know about the methods that are of interest. In a nutshell, no client should be forced to depend on methods it does not use.
SOLID
*S*ingle Responsibility, *O*pen/Closed, *L*iskov Substitution, *I*nterface Segregation, *D*ependency Inversion.
Code Smell : Uber-callback
A callback function that is trying to do everything.
Code Smell : Refused bequest
A class overrides a virtual method of a base class in such a way that the contract/intention established in the base class is not honored by the derived class. See *Liskov Substitution principle*.
SRP Example
A class that compiles and prints a report has two responsibilities and therefore *two reasons to change*. One reason could be to change its content, the other could be to change its format. By changing the class for one reason (content), there is a greater chance that it could break (side-effects) its other responsibility (format) than if there were separated. *robustness to change, maintainability*.
Code Smells
A code symptom that isn't critical (not a bug) but indicate weaknesses in design that may be slowing development or increasing chances of failure or bugs in the future.
Anti-Pattern
A programming pattern that is commonly used but ineffective or counterproductive in its use.
DIP Example
Adapter Pattern, where the high-level module (e.g, Window Manager) sends events to it's own adapter interface which is an abstraction that it depends on. The low-level module implements this abstraction which it is also dependent on (Main Window event handler), but neither are dependent on each other.
Single Responsibility Principle (SRP)
An object should only have a single responsibility that is entirely encapsulated by the class. All it's services *should be narrowly aligned with that responsibility*.
Code Smell : Large Class
Class that has grown too large 'God class' (innefficient if most instantiations don't use all state...indicates no separation of concerns).
Code Smell : Duplication
Duplicate code that exists in more than one location; over-long method or over-large class (*god class*). Too many parameters in a method call doesn't help readability.
What is SOLID ?
Five basic principles of object oriented programming and *design*.
Liskov Subsitution Principle (LSP)
Guarantees semantic interoperability of types in a hierarchy. Ie. with an object of base class A can be replaced by an object of subclass B without altering the semantic *correctness* of the task performed. E.g. An overridden DisplayStatus() function prints status to a file.
LSP Example
If a Square inherits from a Rectangle and a Square object is used in the context where a Rectangle is expected it would be expected that width and height could be changed independently. However a square must have equal sides which could be ensured by making sure any change to width or height updates the other variable. *However* this violates the post-conditions for the Rectangle setters which state that the dimensions can be modified independently.* In practise this may not be a problem but would be an unexpected side-effect.
Why SOLID ?
Intended to guide programmer to make systems that are easy to *maintain* and *extend*. Intended to help identify and remove *code smells*.
Code Smell : Excessive Use of Literals
Magic numbers, should be coded as named constants rather than literals to improve readability. Literals should also be externalised to files and scripts, especially strings for localisation.
Code Smell : Long Method
Method has grown too long and should be broken into smaller methods with more targeted purposes. (readability, re-use).
Code Smell : Contrived Complexity
Obfuscation by using overly complex design patterns where a simpler pattern would be more appropriate.
Code Smell : Inappropriate Intimacy
One class that relies on *implementation details* of another (should be decoupled by the interface, encapsulation and information hiding).
ISP Example
One large class 'Job' that had methods for print jobs, staple jobs and everything else. A change to Job meant re-building everything else. So smaller interfaces were made specifically for each client which were implemented by the Job class. The clients were therefore dependent on their own interface, not all the other methods of Job and so changes had less impact.
Interface
Provide *layers of abstraction* that facilitate *conceptual explanation* of the code and creates a barrier *preventing dependencies*. Decouples (removes dependencies) implementation details from the interface which is used by a client object. Implementation can therefore be changed without changing the client object(s).
Meyers Open / Closed Principle
Software entities (classes) should be open for extension but closed to modification. Ie. extending behaviour of an object can happen without changing it's existing source code by creating a new class which may re-use base class code but not change it. However the new class may have a different interface.
Polymorphic Open / Closed Principle
Where a classes interface specifications and implementation can't be changed rather extended using a new class that overrides the same interface specification with specialised implementations.
Code Smell : Excessively Long Identifiers
Where names of variables, classes etc are very long, perhaps as a result of disambiguation (which would be better served by software architecture which intrinsically gives enough context for a shorter identifier, perhaps through the use of namespaces or classes).
Code Smell : Excessively Short Identifiers
Where the name of a variable doesn't reflect its function due to its briefness (unless it is obvious, e.g. for(int i...).