Simple composite objects
A composite object can also be called a container. We'll look at a simple composite object: a deck of individual cards. This is a basic collection. Indeed, it's so basic that we can, without too much struggle, use a simple list
as a deck.
Before designing a new class, we need to ask this question: is using a simple list
appropriate?
We can use random.shuffle()
to shuffle the deck and deck.pop()
to deal cards into a player's Hand
.
Some programmers rush to define new classes as if using a built-in class violates some object-oriented design principle. Avoiding a new class leaves us with something as shown in the following code snippet:
d= [card6(r+1,s) for r in range(13) for s in (Club, Diamond, Heart, Spade)] random.shuffle(d) hand= [ d.pop(), d.pop() ]
If it's that simple, why write a new class?
The answer isn't perfectly clear. One advantage is that a class offer a simplified, implementation-free interface to the object. As we noted previously, when discussing factories, a class isn't a requirement in Python.
In the preceding code, the deck only has two simple use cases and a class definition doesn't seem to simplify things very much. It does have the advantage of concealing the implementation's details. But the details are so trivial that exposing them seems to have little cost. We're focused primarily on the __init__()
method in this chapter, so we'll look at some designs to create and initialize a collection.
To design a collection of objects, we have the following three general design strategies:
- Wrap: This design pattern is an existing collection definition. This might be an example of the Facade design pattern.
- Extend: This design pattern is an existing collection class. This is ordinary subclass definition.
- Invent: This is designed from scratch. We'll look at this in Chapter 6, Creating Containers and Collections.
These three concepts are central to object-oriented design. We must always make this choice when designing a class.