Domain Modeling by Example
Associating Objects with Python

I’m currently in the third week of a 4-month software engineering bootcamp at The Flatiron School in downtown Chicago. While I’m not new to programming*, I came here to learn the principles of web development that will take me from hack to architect. Here’s one such lesson I’ve already taken to heart:
When building an application, the first step is always a whiteboard.
Most programmers know that they should start with an idea of what they’re going to build and have thoughts about what the component pieces might be, but how many truly do the necessary work of explicitly laying it out up front? It is all too tempting to just hop on a keyboard and start problem solving on the fly. After all, you’re trying to write a web app, right? You know where you’re going, and you’ll figure out the details along the way!
Wrong.
Starting to write code without proper planning is like trying to build IKEA furniture with a blindfold on. If against all odds you somehow manage to assemble something resembling a dresser, there’s a good chance you’ve forgotten a crucial piece and you’ll be throwing the whole thing out in a week and heading to Pottery Barn (like you should have in the first place).
For the rest of this post, I’d like to zoom in on a particular part of the project planning process I’ve had a lot of experience with recently: Building a Domain Model. I’ll take you through an example below.
* More on my coding story in a future post.
Example: Blackjack

Like everyone in the year 2016, the first programming language I learned was Python. While my bootcamp is taught in Ruby, I decided to take a stab at translating some of the concepts we have been discussing into my native tongue, so to speak. So, I gave myself the challenge of writing a simple Blackjack CLI game in Python. I’ll use this to discuss the process of mapping out a domain model.
Step 1: Entities
The first step in building out a domain model is thinking about what entities (or objects, or models) exist in the domain. Here’s what that might look like for Blackjack:
At minimum, we know that we need a deck of cards to play the game. So…
Deck
Card
Oh, and there is at least one gambler who plays against the dealer.
Gambler
Dealer
Anything else? Well, when the game is played both the gambler and the dealer have a hand of cards. And those cards are dealt to them from a shoe.
Hand
Shoe
And for the sake of completeness, let’s say that all of this is happening at a table, like the ones in casinos.
Table
Great! We now have an idea of the kinds of things that make up the game of Blackjack.
Step 2: Entity Relationships
The next step in modeling out the domain is very precisely defining the relationships between the entities. Canonically, there are some key words that are used to describe these relationships, and here are some of those that we’ll make use of:
- “has many”
- “has a”
- “belongs to”
- “has many through”
Here is a (non-exhaustive) list of how that applies to our Blackjack game:
- A
Deck
has manyCards
- A
Card
belongs to aDeck
- A
Shoe
has manyDecks
- A
Table
has aShoe
- A
Deck
belongs to aShoe
(in the context of our game!) - A
Hand
has manyCards
- A
Card
(optionally) belongs to aHand
- A
Gambler
has manyHands
(because you can split!) - A
Hand
belongs to aGambler
or aDealer
(this may hint at another entity?) - A
Gambler
has manyCards
throughHands
Can you think of some more? Also, note the bi-directional nature of these relationships! For example, that of Deck
→ Card
as opposed to Card
→ Deck
.
Step 3: Entity Relationship Map
Now that we have some concrete examples of how our objects relate to each other, it’s time to formalize that into a diagram. This will be the basis for our DM.

All of this work, and we still haven’t written a single line of code! Newsflash: this is the meat of programming.
I’m still not 100% sure on a few of these relationships as you can see from diagram above. But this is a work in progress! As I think more about how my application will work, these will be finalized.
In this step, you may also want to think about what kinds of attributes the models in your domain may have. For example:
- A
Card
has asuit
and arank
- A
Gambler
has aname
and abankroll
Some of these attributes will depend on your implementation. To me, it makes sense for a Gambler
to also have a wager
attribute, which is their standing bet that would be assigned to each Hand
dealt. I’m thinking they would have the option to change this wager between hands, but wouldn't have to necessarily. This mimics the behavior of real life Blackjack, which is important to remember. However, you could also simply prompt the Gambler
for a new wager from their bankroll every turn, and not store it on the model.
Step 4: Models Proof of Concept
Start playing with your models!
At this point, you’re allowed to touch your computer. Purists may say that you still need to define attributes on all of these entities, but for the sake of brevity here I’ll jump into some code. Doing so I think helps to bring up some important points. Here are a few of my models based on my thinking thus far:
Model Case 1: Create a Shoe containing a single Deck of Cards
NOTE: The models as they are set up now query
<class>.all_
list variables to get instances. This is to preserve a single source of truth, which is beyond the scope of this post. In a more mature app, maybe they would be database calls, or would check a cache first.
Even with just these 3 objects, some questions already start to arise:
- Does a
Card
have to belong to aDeck
? - Does a
Deck
have to belong to aShoe
? - Maybe a
Deck
could be its own thing independent of aShoe
, and thedeck.shoe
instance attribute should be optional?
These are the kinds of questions about the domain in which we are working that need to be thought about carefully before moving forward.
Model Case 2: Gamblers and Dealers are both Players
Remember in the diagram how both a Gambler
and a Dealer
have Hands
? Seems to me like maybe those entities share some functionality. Let's keep our code DRY!
By noticing in the diagram that both a Gambler
and a Dealer
have the same relationship with Hand
, I was able to realize that they are really both examples of a Player
! Their shared functionality can live in the Player
model, while they can have more specific functionality in their subclasses (e.g. gambler.bankroll
, gambler.wager
, and dealer.hand()
).
Extra credit if you write the omitted Hand
class, with correct relationships to Card
and Player
.
Step 5: Build
By now, I’m feeling super good about the foundation of my Blackjack game. I’ve fully mapped out how all the pieces fit together, even if I haven’t written the code for all of them (for example the Table
object that was postulated). I know that from this point, I can start to play with the components and I'm not missing anything crucial, and I've done my due diligence in wrapping my head around the domain that is the game of Blackjack.
I can begin to tackle the logic of the game piece by piece, always keeping in mind the DM I have conceptualized to guide and organize my code. Once I’ve tested a bit more and I’m more confident that my objects are well set-up, I could start to formalize them into ORM models for underlying relational database tables. Or, I could simply keep the project lightweight and rely on the <class>.all_
arrays I have implemented as my way of storing instances if the data doesn't need to persist. Either way, I have a clear roadmap to building out the rest of the app. And I have a good old-fashioned whiteboard to thank for that.