Now add the abstraction side. A Shape holds a reference to a Renderer (the bridge) rather than inheriting from it. That reference is the whole trick: the Shape never knows which backend it is talking to.
Implement Circle.draw so it delegates to the bound renderer by calling self.renderer.render_circle(self.radius) and returning the result. The same Circle logic then works with any renderer you pass in.
class Renderer:
def render_circle(self, radius):
raise NotImplementedError
class VectorRenderer(Renderer):
def render_circle(self, radius):
return "vector circle r=" + str(radius)
class RasterRenderer(Renderer):
def render_circle(self, radius):
return "raster pixels for circle r=" + str(radius)
class Shape:
def __init__(self, renderer):
self.renderer = renderer
def draw(self):
raise NotImplementedError
class Circle(Shape):
def __init__(self, renderer, radius):
super().__init__(renderer)
self.radius = radius
def draw(self):
"""Draw this circle by delegating to the bound renderer."""
# TODO: call self.renderer.render_circle(self.radius) and return it
pass
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
Now add the abstraction side. A Shape holds a reference to a Renderer (the bridge) rather than inheriting from it. That reference is the whole trick: the Shape never knows which backend it is talking to.
Implement Circle.draw so it delegates to the bound renderer by calling self.renderer.render_circle(self.radius) and returning the result. The same Circle logic then works with any renderer you pass in.
Press Run Tests or ββ© to check your solution.