I want to create a little todo app, with a "pedagogic focus" on clean software design. I spent some time reading about design patterns lately and I am trying to wrap my mind about which of them I could and should use.
Features I want my "todo items" to provide:
Timing
- has a due date
- has a due date and due time
- is "timeless"
Completion
- simple (you fulfill the task and cross it from the list)
- cumulative
- turns (you have to perform 3 sets of pullups to fulfill the task)
- time (you need to gather 30 minutes in total of piano practicing to fulfill the task)
Continuity (with given frequency, e.g. 3 days)
- once (once done it's gone)
- multiple (task is repeated n times with given frequency)
- continuous (task is repeated indefinitely with given frequency)
Optional reminder
I then tried to find design concepts to implement these features; here are my thoughts:
Feature families 1-3 suggest three independent "properties" of a todo item, which could be three distinct strategy interfaces like
TimingStrategy
,CompletionStrategy
andContinuityStrategy
.Yet, considering timing strategies, all three available concrete strategies, i.e.
DueDateTimingStrategy
,DueDatetimeTimingStrategy
andTimelessTimingStrategy
, would use different sets of parameters (time, datetime or no time fields) which can not be put into practicve using the standard strategy pattern.I could also introduce a
TimingParameter
class which is used byTimingStrategy
to address this problem, but then again...: Is this too much in this case?For my understanding, a decorator pattern is not suitable here because I want to pick one behavior for the todo's "guts" and not "augment" behavior on the todo's "skin". Also using decorator would allow me to pick more than one timing behavior which should not be possible.
The completion feature could actually be provided by using the strategy pattern, because one-interface-for-all is thinkable: The
SimpleCompletionStrategy
could be seen as a special case ofCumulativeTurnsCompletionStrategy
where the number of turns is 1.The continuity property could be implemented by using the strategy pattern
The reminder feature could be part of the basic "todo" class, but what does this mean when picking the
TimelessTimingStrategy
? Such a todo can't have a reminder! If the todo class checks whether reminding is allowed this breaks separation of concenrns. Should theTimingStrategy
interface provide acanReminderBeSet()
method?If one of the feature families (or a new one) would allow for pick-n-out-of-m-options, this would demand a decorator pattern? Or an
OptionManager
class?Am I trying to force in patterns just because I read about them recently?
Not using composition/patterns but inheritance would lead to class explosion
DueDateSimpleOnceTodo
,TimelessCumulativeTurnsContinuousTodo
, ...Maybe one of the feature families could be implemented via inheritance (e.g.
Todo
base class with anisDue()
method and strategies for completion and continuity and then child classes according to Timing, thusDueDateTodo
,DueDatetimeTodo
andTimelessTodo
, for instance.
I'm very open to your suggestions and comments. Your propositions for an architecture and comments on specific bullets in my lists are both very welcome!