ArtShowTools: Part 1

Designing the Domain Model

My motivation for writing an artwork management application is my wife. She is a successful artist and belongs to a local co-op gallery (Next Gallery). She has a large body of artwork and participates in several shows per year as well as doing commissions. I wrote a desktop application for her back in 2017 to help manage her artwork as well as design the layouts for her shows. While she still uses this application, she has asked me to expand the software to help manage the gallery as well as allow other artists to use the software.

For the desktop application, I based the requirements and use cases on what I thought my wife needed. Inevitably, this lack of actual domain knowledge caused a lot of confusion about how to use the software. For the new application, I'm trying to use domain-driven design to improve usability.

Talk to the Domain Expert

My first step was to talk to my wife (the domain expert) about what she needed to manage her artwork. As with all domain experts, the hardest part of the process was finding the time to discuss the domain. Fortunately, we had to do a 2-hour road trip to drop off some artwork for one of her shows which was the perfect opportunity to ask questions and gather information about the domain model.

I'm going to start with the inventory system which tracks various aspects of a piece of art -- physical characteristics, ownership, images, and state. The other systems in the application will use this information for scheduling, sales, and show design.

Modeling the Inventory System

The diagram below represents some of the use cases associated with the Inventory system. On a side note, I highly recommend using Miro as a diagram creation tool -- I use it extensively at my day job and liked it so much that I picked up a license to use at home.

From the discussions with the domain expert and the use cases she came up with, I can define the ubiquitous language glossary for the domain model. The purpose of the glossary is to describe the domain unambiguously so I, the developer, do not make any assumptions regarding what the domain expert means they talk about the domain.

Ubiquitous Language Glossary

Here is the first draft of the glossary.

Artist: An entity representing the person who created the artwork. An artwork can have zero, one, or many unique Artists associated with it.

Artwork: A piece of artwork such as a painting, drawing, sculpture, print, etc.

Collection: A collection is an arbitrary grouping of unique artworks. A collection can contain zero, one, or many artworks.

Consign: An artwork can be consigned to a 3rd party that handles the sale of the artwork. In return, the 3rd party receives compensation from the sale of the artwork as a percentage of the sale price or as a flat fee. Ownership of the artwork does not change until the artwork is sold.

Depth: When viewing an artwork, the depth is the size of the artwork extending away from the viewer.

Destroy: An artwork can be destroyed. The ownership of the artwork does not change.

Donate: An artwork can be donated. The ownership of the artwork is changed to the recipient of the artwork.

Height: When viewing an artwork, the height is the vertical size of the artwork.

Loan: An artwork can be loaned to a 3rd party. Ownership of the artwork does not change.

Lose: An artwork can be lost. The ownership of the artwork does not change.

Medium: The materials used to create the artwork.

Owner: The owner of an artwork is an entity such as a person, institution, or company.

Price: The price of an artwork is represented as the amount and type of currency. The amount must be positive.

Sell: An artwork can be sold. Ownership of the artwork changes to the buyer.

Size: The 3D size of an artwork is represented as Width, Height, Depth, and Units of Length. The width, height, and depth must be strictly positive.

Steal: An artwork can be stolen. The ownership of the artwork does not change.

Tag: A unique attribute assigned to an artwork or collection. An artwork or collection can have zero, one, or many tags.

Title: The name of an artwork.

Trade: An artwork can be traded for one or more artworks. The ownership of the artworks being traded is swapped.

Units of Length: The units of length can be either inches, feet, yards, centimeters, or meters.

Units of Weight: The units of weight can be either ounces, pounds, grams, or kilograms.

Weight: The weight of an artwork is represented as the amount and Units of Weight. If the units are metric, the weight is equivalent to the mass. The amount must be strictly positive.

Width: When viewing an artwork, the width is the horizontal size of the artwork.

The next question is where to store the glossary. This information is an integral part of the application so preferably I want to make it part of the code base so the glossary is readily available to the developer. I originally thought about creating a Markdown file containing the glossary and adding it to the GitHub repository. But then I realized having it stored directly in the code would make it inaccessible to the domain expert. Fortunately, GitHub provides a great solution to this problem in the form of wiki pages. Having the glossary in a GitHub wiki page in the application repository keeps the information close to the code and is readily accessible by everyone working on the project. Here's the link to the glossary in the GitHub repository I set up for the ArtShowTools prototyping project: Ubiquitous Language Glossary

Inventory Bounded Context

Here is the first draft of the Inventory bounded context design.

The initial design uses the following implementations for the objects inside the bounded context.

ObjectType
ArtworkEntity
CollectionEntity
OwnerEntity
ArtistEntity
SizeValue Object
WeightValue Object
PriceValue Object
MediumValue Object
ImageValue Object
TagValue Object

The Artwork, Collection, Owner, and Artist objects will be represented as entities and referenced by their IDs. The Size, Weight, Price, Medium, Image, and Tag objects will be represented as value objects.

At this point, I've still got a few questions regarding the domain model.

  1. How do I represent the state of an Artwork? For example, if an artwork is consigned, that state should be represented in the domain model somehow since the state of the artwork will determine what use cases can be applied to it. Can this be achieved by using a Tag? Or should the state be represented directly in the Artwork implementation as a field or possibly by changing the Artwork to an "OR" type?

  2. Can an Artwork be deleted? When I talked with the domain expert, she and I didn't reach an agreement on whether or not an artwork could be deleted from the application. I was thinking about the implementation and what effect the deletion would have on other entities in the system that referenced the deleted artwork. The domain expert, however, thought that artwork should be able to be deleted to fix mistakes and keep the inventory in a simplified state.

  3. Artist is an entity but I'm not sure whether I want to manage the Artist entities as part of the inventory system or move that functionality to a separate system that manages people (a contacts system perhaps?).

  4. Owner is an entity but I'm still debating how to represent it. From the glossary, the owner doesn't exactly fit into a nice simple homogenous object representation. Looking ahead to the implementation, I think I can solve this by using an "OR" type. And like the Artist entity, should Owner entities be managed by the inventory system?

The next step is to prototype the domain model to try to answer some of these questions and validate the design. I've already set up a GitHub repository (artshowtools-prototype) to allow for prototyping and I'll be using that repository in conjunction with these blog posts.