- Automatic Message Delegation - Defining a path for forwarding messages an object does not understand.
- Defining an inheritance relationship will automatically forward messages from the child to the parent if they are misunderstood (or if they are explicitly called with
super
- Multiple Inheritance VS. Single Inheritance
- Create highly related types that share common behavior but differ along some dimension.
- EX: All classes that inherit from
ActiveRecord::Base
exist to communicate with a DB table, the difference is just the columns on the table and the extra behavior added to that class.
- EX: All classes that inherit from
- When code has a generalization -> specialization relationship
- Abstract classes are simply the shared bits, they should never be instantiable of their own.
- Concrete classes inherit from the abstract and implement specializations.
- Wait until your abstraction is mature.
- Know what behavior is alright to share, and what should remain private
- Feel confident it is worth introducing the dependency to the codebase
- Have a clear separation between the concrete and the abstract.
- It is inherently easier to move code from a subclass up to a superclass than from a superclass down to a subclass.
- When refactoring a class to use inheritance, try to start by implementing a concrete class, and pulling behavior into the superclass as peers require it.
- Promoting abstractions is easier than demoting concretions.
- Abide by the "Hollywood Principle", that is, "Don't call us, we'll call you".
- Write 'template methods' that defines an algorithm in abstract operations that subclasses can override to implment concrete behavior
- Implement the invariant parts of an alorthithm once, subclasses will fill in the variants.
- Raise a helpful error message if a programmer fails to implement a required method
- Knowing things about other classes creates coupling, so inheritance can create very tightly coupled code.
- Forcing a subclass to know how to interact with a superclass is a common cause of errors
- Explicit hooks allow subclasses to know less about the parent class
- Adding a
post_initalize
hook instead of relying on programmers to callsuper
in the subclass.
- Adding a
- Good examples of inheritance:
ApplicationController
ApplicationModel
(orActiveRecord::Base
)
- Bad examples:
Provider < User
HospitalityBooking < Booking
- Sandi discusses how fields like 'category', 'type' and 'style' can be signs of embedded types. What embedded types might we have in Handybook that are dying to break free?
- In the
AccountingService
,TipsDecorator
is going to get some company, what methods currently inTipsDecorator
will be needed inFeesDecorator
as well?