Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fc98e50

Browse files
Some words about multiple inheritance and methods
1 parent 6ec4440 commit fc98e50

File tree

1 file changed

+86
-13
lines changed

1 file changed

+86
-13
lines changed

gang-of-four/bridge/index.rst

Lines changed: 86 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ There are often several options.
130130
as separate classes from the main ``Logger`` class.
131131

132132
To keep our example here simple,
133-
let’s split out the handler:
133+
let’s split out the handler
134+
and leave filtering in the superclass.
134135

135136
code
136137

@@ -145,29 +146,98 @@ and then compose them together:
145146

146147
code
147148

148-
The result is quite elegant,
149-
and can result in an API that feels very much like a Lego set.
150-
A box of useful classes is provided to the programmer
151-
that can snap together to create complex configurations
152-
out of simple pieces.
149+
The result is quite elegant —
150+
an API that offers separately configurable classes
151+
that click cleanly together to make a working logger.
153152

154153
Dodge: use multiple inheritance
155154
-------------------------------
156155

157-
problem is init methods
156+
Instead of decomposing a complicated class into simpler classes,
157+
some Python programmers try to combine the features
158+
of several subclasses by using multiple inheritance:
159+
160+
code
161+
162+
A first obstacle is that multiple inheritance
163+
will not always produce working code.
164+
We were lucky in this case
165+
that only Emit needed to completely rewrite log(),
166+
while Filter was able to use super()
167+
to delegate the actual message printing to its superclass.
168+
If both subclasses had needed to entirely rewrite log(),
169+
then their two implementations of the method
170+
would not have cooperated at all.
171+
And even in their current state,
172+
our subclass only works because we listed Filter before Emit
173+
in our base classes;
174+
if the order were reversed, the class’s features would not compose.
175+
176+
Second, __init__() methods are notorious in Python
177+
for the problems they cause for multiple inheritance.
178+
179+
180+
not always possible
181+
182+
init parameters no longer compatible
183+
184+
init fragile and can break later?
185+
186+
158187

159188
Dodge: decompose into methods instead of classes
160189
------------------------------------------------
161190

162-
Some classes try to dodge the problems that the Bridge Pattern solves
163-
by decomposing a complicated class’s code into separate methods.
164-
Given our example,
165-
this approach would recognize that filtering and emitting
166-
are separate steps that will often need separate customization,
167-
but would grant them each a method instead of a class:
191+
Instead of decomposing a complicated class into several classes,
192+
some designers try to split its operations into separate methods instead.
193+
In our example,
194+
the two steps of filtering and emitting
195+
would each be granted its own method:
168196

169197
example
170198

199+
This prevents new filter code and new output code
200+
from trying to override the same method
201+
and colliding with each other.
202+
Instead, the code for each operation is cleanly separated.
203+
204+
example
205+
206+
Given the modularity of these replacement methods,
207+
some programmers opt to provide them as standalone “mixins”
208+
that don’t inherit from the base class
209+
and can’t operate as standalone loggers themselves.
210+
This forces the programmer to always build a class of their own.
211+
212+
example
213+
214+
But there are disadvantages
215+
to decomposing several design axes
216+
into mere methods rather than fully separate classes.
217+
218+
First,
219+
class instances are easier to compose at runtime
220+
than are class objects themselves.
221+
Imagine that logging will now be driven by a configuration file.
222+
The configuration will choose one logger for writing,
223+
and how they are filtered.
224+
How will Python code build a logger?
225+
226+
if fully decomposed easy
227+
choose and instantiate a filter
228+
choose and inst the logger,
229+
passing it the filter.
230+
A filter and printer can be combined at runtime quite simply,
231+
by instantiating one and passing it to the other.
232+
233+
but a logging system freighted with mixin or m i system
234+
will require the filter and printer
235+
to be composed into a single class
236+
The programmer will either need to instantiate ahead of time
237+
all _m×n_ possible combinations of filters and printers,
238+
or else build classes ahead of time.
239+
(See the Appendix below for the details.)
240+
171241
problem
172242
still remains complicated
173243
what is its job “everything”
@@ -214,6 +284,9 @@ Appendix: functions instead of classes
214284

215285

216286

287+
288+
289+
217290
object oriented folks will have seen situations
218291
where a single class needs to be specialized
219292
along many different axes at once

0 commit comments

Comments
 (0)