Develop a Blog - Part 1: Requirements and initial design

Building PHP applications is easy. You create a PHP file, write some code and put it in the root directory of a web server and you have a working dynamic website. This works great for small applications, but as soon as your application becomes more complex it can become quite cumbersome and hard to maintain.

In this series of articles we will discuss how to build a web application in an object oriented programming (OOP) way using Domain Driven Design (DDD). In this first article we will discuss the requirements for a simple blogging application such as the one used at Webdevils.nl. We will use the language used in the provided requirements to define an initial design for our application. Using this technique we will have an easier time talking to our customer and verifying our application as we will be using the same words describing our blogging application.

At the end of this article you will have an initial class design that you can use to develop your own blogging application. In the next articles of this series we will use the design to refine the requirements and develop the blogging application in PHP.

This article is part 1 of a series:

I created a list of requirements for a blog based on the functionality of the blog I use at Webdevils.nl. The requirements are far from complete, but that is also the point of it. In real life the requirements given by a customer aren't complete either. We will use our model and designs to find the gaps and work those out further.

Initial requirements

As a reader I want to

  1. View the latest published blog posts
  2. View the latest published blog posts written by an author
  3. View the latest published blog posts in a category
  4. Read an individual published blog post

As an blog author I want to

  1. (Co-)Write a new blog post
  2. Write the content of a blog post in Markdown or HTML
  3. Update an existing blog post
  4. Remove an existing blog post
  5. Publish a blog post in a category
  6. Schedule a blog post to be published at a later date
  7. View an individual scheduled or draft blog post

To satisfy these requirements we will need some infrastructure: a database, filesystem, probably a web framework, etc. The infrastructure is essential to the final application, but isn't that important during the design phase. We first want to work out the actual business logic and we will treat the infrastructure as an implementation detail.

The advantage of this approach is that we can solely focus on the business logic and work out all the details around it, without being held back by our technology choices. When we finally need the infrastructure to continue our progress we will be in better stage to make informed decisions on what the best frameworks, and databases are for our application.

Reader requirements

We will start with the reader requirements. Below I repeated the requirements, but I highlighted a few terms in the requirements that I think are relevant for our design:

As a reader I want to

  1. View the latest published blog posts
  2. View the latest published blog posts written by an author
  3. View the latest published blog posts in a category
  4. Read an individual published blog post

Every requirement states a published blog post. This seems to be an important concept, so let's make that a class. The next two classes we can make are Author and Category. Requirement 2 mentions an Author and requirement 3 a Category.

That leaves us with the latest part of a PublishedBlogPost. The reader must be able to see a list of the latest PublishedBlogPosts. We can add it as a class to our design as well. It does feel a bit awkward, but that is fine. We will come back to it later.

This brings us to the following UML diagram:

k9QjTSyjnkeBgkmDCwsOIpqvAwwyYGPB5pRI0mdW.pngWe have a LatestPublishedBlogPost which contains 0 or more PublishedBlogPosts. Every PublishedBlogPost is published in a category and has an Author.

Blog Post status

Now that we covered the reader requirements, let's continue with the Blog Author requirements. One thing I notice is that while the reader requirements only mention PublishedBlogPosts, the Author requirements also mention Draft and Scheduled BlogPosts.

The easiest way to model these three different types of blog posts is by creating three classes: PublishedBlogPost, DraftBlogPost and ScheduledBlogPost. All these classes will have similar functionality except for a status. To address this duplication we can use two different techniques:

  1. Inheritance: we create a BlogPost class with the common functionality and put the status specific functionality in the sub classes PublishedBlogPost, DraftBlogPost and ScheduledBlogPost.
  2. Composition: we create a BlogPost class which has a status. The status refers to a Status interface that is implemented by concrete statuses: Draft, Scheduled and Published.

Both options would get the job done, but personally I like the second option more. It communicates the intention of the design better. The status of a BlogPost is an attribute, not a full concept on its own.ybvITXipjHv69SHXHuC5RRf2y2eBvcgvvERZ9bfM.png

Next, let's talk about the Author.

BlogPost authors

Requirement 1 of the the Author requirements state:

(Co-)Write a new blog post

Emphasis on "Co". A BlogPost can have multiple authors. However, in our current design every BlogPost has a single Author.l72HmxaghrqoMm5HFl6Q9qrmaTPoW6BVpMmIErog.pngWe can address this easily, by changing the multiplicity in the diagram.

Parsers

Next, we can have a look at reader requirement 2:

Write the content of a blog post in Markdown or HTML

We can address this requirement by letting the BlogPost class decide how to parse the written content, but the authors already ask for two different techniques for writing their BlogPosts. We can expect that as soon as they hear about something new, such as RestructuredText, they will ask us to add functionality for that too. It is smart to keep our design flexible on places where we already expect additional requirements.

We can do that by introducing another Interface. The BlogPost will use a Parser to parse the content of a BlogPost. We can create two Parsers for now: MarkDownParser and HTMLParser. If the request for RestructuredText comes we can easily address that without the need to change any existing classes by adding a RestructuredTextParser.Z2KUs8urZlqLMtqFudJsSoUYMoJ6jJwFhAvSRQoo.pngOur class diagram is coming nicely together. We satisfy all requirements. Still something isn't looking right. The LatestPublishedBlogPost class is a weird one. Maybe we should dive a bit deeper into the workings of it.

Blog post collection

Currently we only support a list of the latest published BlogPosts. Which is fine if we strictly look at the requirements, but we can expect get more requirements on listing BlogPosts soon. Why only support a collection of published BlogPosts and not a collection of draft or scheduled ones? And what about oldest instead of latest BlogPosts?

In essence there is no difference between a collectionof BlogPosts in Draft status and one with BlogPosts in Published status except for the status attribute. We wouldn't make a collection of BlogPosts with the same title either (or maybe we would). We can simplify our design by replacing the LatestPublishedBlogPost class with a BlogPostCollection class and let the user of the collection figuring out what kind of BlogPosts he wants in his collection.HeVz7I7Py6ef9jkrVxrz8eyAIAvSa6sfunqll8KZ.pngAnd that is it for today. We have an initial design that satisfies our initial requirements and that also seems logical from my perspective. We can start implementing some of these classes in PHP. In the next article we will implement the constructors of the BlogPost, Author and Category classes using Test Driven Development (TDD).

Develop a blog series

The develop a blog series consist of two more articles:

Author

Mark Kazemier's avatar
Mark Kazemier

Hi, my name is Mark. I'm the founder of webdevils.nl and love developing websites and other web applications. Through Webdevils.nl I want to spread my enthousiasm about the web and PHP. In my professional live I'm a security expert specialised in security monitoring.

View all posts