The following question adresses a problem I often encounter. Basically, there are solutions like the adaptor pattern, but I find it a bit unsatisfying.
Suppose I have a class Polygon
which implements an - uhm - polygon with quite some functionality. Many of those Polygon
live in my program, some as lonely variables, some in collection structures.
Now, there's a function that needs an argument type that is basically a Polygon, but with some additional features. Let's say, a Polygon
who can return some metrics: his volume, center of gravity, and angular mass. Plus, the function also needs the methods of the original Polygon
.
A first idea is:
class Polygon:
# defines my polygon
class PolygonWithMetrics(Polygon):
# - extends polygon with the metrics
# - takes Polygon as argument upon construction
# - would need to delegate many functions to Polygon
def functionUsingPolygonWithMetrics(p):
# use functions of Polygon and PolygonWithMetrics
# driving code:
p = Polygon(some args here)
... more code ...
p_with_metrics = PolygonWithMetrics(p) # Bummer - problem here...
functionUsingPolygonWithMetrics(p_with_metrics)
The problem: It would require to delegate many many functions from PolygonWithMetrics
into the original Polygon
.
A second idea is:
class Polygon:
# defines my polygon
class PolygonMetrics:
# takes a polygon and provides metrics methods on it
def functionUsingPolygonWithMetrics(p):
# use functions of Polygon and PolygonMetrics
# driving code:
p = Polygon(some args here)
... more code ...
p_with_metrics = PolygonMetrics(p)
functionUsingPolygonWithMetrics(p, p_with_metrics) # Bummer - problem here...
This idea takes the original Polygon
as an argument, plus a second object that provides the metrics functions. The problem is that I would need to change the signature of functionUsingPolygonWithMetrics
.
What I would really need is an idea how to extend an existing object ad-hoc with some more functionality, without the problems given in idea 1 and 2.
I could imagine an idea roughly like this, where the job is mostly done by PolygonWithMetrics
:
class Polygon:
# defines my polygon
class PolygonWithMetrics(maybe inherits something):
# - takes a Polygon and provides metrics methods on it
# - upon construction, it will take a polygon
# - will expose the full functionality of Polygon automatically
def functionUsingPolygonWithMetrics(p):
# use functions of Polygon and PolygonWithMetrics
# driving code:
p = Polygon(some args here)
... more code ...
p_with_metrics = PolygonWithMetrics(p)
functionUsingPolygonWithMetrics(p)
Three questions arise:
- Does this pattern have sort of a name?
- Is it a good idea, or should I resort to some more adviced techniques?
- How to do it in Python?
Aucun commentaire:
Enregistrer un commentaire