I am building something like blogging platform, such at Tumblr. Users can add posts. But there are several different types of posts, for example: article, video, photo post, etc… There are many common fields, independent of post type, for example: title, author_id, creation timestamp, etc… But there are also some fields, which are different for specific type, for example text for article, video url for video, list of photos for photo post, etc…
So I came up with such models design:
Post - general class for post, uses table ‘posts’:
id
title
author_id
created
type (article or video)
ArticlePostData - specific model for posts of article type:
id
post_id
text
VideoPostData:
id
post_id
url
It works, but still insufficient. For example, I have a task to build an RSS feed for post. Each post type mush have its representation for RSS feed - raw text for article or embed code for video. So, Post model mush have something like getRssContent() method, which returns representation for RSS. I see different solutions:
-
Switch/case by type in getRssContent(). Very bad, cause it will be very massive in real life (at the moment I have to implement 7 post types, not just to).
-
Make an interface for *Data classes and realise getRssContent() in each. Disdvantage - I need to have getRssContent() method in Post model as well, which calls concrete *Data class method.
-
Add classes like ArticlePost, VideoPost, which extend Post without deleting *Data classes. Disadvantage - each type is represented with two classes - one for behaviour, another (*Data) just for working with db.
Method getRssContent() is just an example, I have many differences in behaviour for post of different types. What solution should I choose, can you suggest yours? Maybe there is OOP pattern, which solves my problem? Strategy looks close, but I’m not sure.