SOLID Principles
These are the basic principles that keep object-oriented code readable, maintainable, and a lot less painful to change.
- S - Single Responsibility: Each class should be responsible for one thing. For example, one class to generate a file, another to save it, not just separate methods in a big class.
- O - Open/Closed: Classes should be open for extension but closed for modification. I saw an example with shapes. Instead of updating the same method every time, you define an interface and add new shapes without changing existing code.
- L - Liskov Substitution: (I still struggle with this name.) Derived classes should not break the expectations of the base class. If you swap a derived class for its base class, things should still behave. It is one of the reasons people recommend interfaces over inheritance when behavior varies a lot.
-
I - Interface Segregation: It is better to have lots of small, focused interfaces than one big one.
If you are adding
throw new NotImplementedException()then your interface is probably too broad. - D - Dependency Inversion: High-level classes should not depend on low-level details. Inject abstractions instead of newing up concrete types directly. That makes code easier to test and swap later.
Class naming
I have always called a subclass a "child class," but the common terms are:
- Superclass / Base Class: A class that is inherited from.
- Subclass / Derived Class: A class that inherits from the base.
Other terminology
I came across the term destructor (as opposed to a constructor). It exists in C#, but it is rarely used. That sent me down a terminology rabbit hole:
- Abstract Class: Cannot be instantiated. It may contain abstract methods (must be implemented) and shared methods too.
- Static Class: Cannot be instantiated. Contains only static members, typically helpers.
- Sealed Class: Cannot be inherited from.
-
Polymorphism: Code can work with different implementations of a type through an interface (e.g.
ILogger). - Encapsulation: Keeping internal state private and only exposing what is needed. We are not great at this in the Warp Engine, so it is something to improve.
- Members of a Class: All the class "gubbins" - fields, properties, methods, constructors, etc.
- Composition: One class owns another and creates it directly. Tightly coupled.
- Aggregation: Similar to composition, but looser. The dependent class can exist without the other (often passed in).
- Association: A general term for when classes are related or know about each other in some way.