Card 04/ 05
Practice: Naming the Structural Pattern From Its Code
Seven short listings, each a wrapper, a tree or a shared object.
Naming a structural pattern from its code comes down to comparing interfaces and counting what is held, and this exercise gives seven listings to practise on, one for each structural pattern, in a mixed order. For each, name the pattern and give the line or feature that decided it.
-
py class XmlToJson: def __init__(self, xml_parser): self._xml = xml_parser def to_json(self, text): return json.dumps(self._xml.parse_to_dict(text)) -
py class Menu(MenuEntry): def price(self): return sum(entry.price() for entry in self._entries) -
py class CompressedStream(Stream): def __init__(self, inner: Stream): self._inner = inner def write(self, data): self._inner.write(zlib.compress(data)) -
py class IconFactory: def icon(self, name): if name not in self._icons: self._icons[name] = Icon(load_png(name)) return self._icons[name] -
py class VideoConverter: def convert(self, path, fmt): file = VideoFile(path) codec = CodecFactory.extract(file) audio = AudioMixer().fix(file) return BitrateReader.convert(file, codec, audio, fmt) -
py class LazyImage(Image): def draw(self): if self._real is None: self._real = RealImage(self._path) self._real.draw() -
py class Shape: def __init__(self, renderer: Renderer): self._renderer = renderer class Circle(Shape): ... class Square(Shape): ...
Show the answers
| Listing | Pattern | The deciding feature |
|---|---|---|
| XmlToJson | Adapter | Offers to_json over a parser with a different method |
| Menu | Composite | Sums price over many entries of its own interface |
| CompressedStream | Decorator | Same write as the stream it holds, with compression added |
| IconFactory | Flyweight | Returns one stored icon per name, shared by every caller |
| VideoConverter | Facade | One convert call over four subsystem classes |
| LazyImage | Proxy | Same draw, and the real image is created on first use |
| Shape | Bridge | Shapes vary by subclass and hold a renderer that varies on its own |
Listings 3 and 6 are the pair most often swapped: both keep the interface and hold one object. The compressed stream is handed its inner stream and changes the data, so it adds behaviour; the lazy image creates its real image and decides when, so it controls access. Listing 4 is a factory, and what makes it Flyweight is that the icons it returns are shared, which a plain factory would not do.
← → move through sections and cards