Exercise 7: Higher Level Design

The purpose of this exercise is different than those that came before it. Rather than focusing on different programming techniques that can be used to achieve different system properties, the goal in this exercise is to leverage all of that knowledge to design small systems that addresses a higher level problem.

The goal is not to pass tests, to achieve a specific set of detailed functionalities, or to demonstrate language level competencies. Instead, you should construct a design that is able to satisfy the constraints provided by the underlying problem definition. Your solution could be written in code, but there may be some parts of the code that are unspecified in the problem descriptions. You should clearly identify all classes, functions/methods, calls, and control flow that are relevant. The behavior of these pieces and how they interact to enable meeting the given constraints matters most.

In all cases, you have the additional constraints of good design. Prefer a design that is easier to maintain, easier to use, and harder to misuse.

Task 1) Deduplicreation

You are working on a small drawing application. As a part of this process, you have a Paintbrush class that determines a host of attributes like the color, shape, texture patterns, or even images with which a user may paint. In order to make this work, users must be able to specify the properties of their own paint brushes. In addition, it is often the case that users may switch between brushes and create many different brushes while painting a picture. They should be able to list the brushes available and select one to use.

Main Goal: Design the subsystem for Paintbrushs meeting the above scenario. It should allow a user to define parameters for a Paintbrush and acquire an instance of that Paintbrush in the future in order to paint with it.

In addition, you realized that users have a tendency to recreate the same paint brushes over and over again. This eventually leads to frame drops and bad user experience. Design your system so that you only ever create one instance of a Paintbrush with a specific set of properties. NOTE: This is not a Singleton.

Task 2) Superlative Serialization

You are designing an API for managing requests to a few third party APIs. The APIs vary in nature:

But they are all in the same domain and expose the same higher level properties: action1, action2, action3, action4. They just happen to give these different names. For example, you might have four functions that perform RESTful actions

1
2
3
4
void doRestfulThing1();
void doRestfulThing2();
void doRestfulThing3();
void doRestfulThing4();

or you might have a local service exposed via four functions:

1
2
3
4
void oneLocalThing();
void anotherLocalThing();
void thirdLocalThing();
void aFinalLocalThing();

You may assume that the behaviors of the different third party systems can be called through functions. You may not know all of the different systems in advance. You can assume that which action corresponds to action 1, 2, 3, or 4 is known.

Main Goal: Design a subsystem for ThirdPartyAPIs that allows the rest of your code to transparently interact with with different APIs regardless of which form/API provider is being used.

In addition, you have realized that you sometimes want to use the APIs such that, e.g.

  1. action 1 is always performed before any normally requested action, OR
  2. action 2 is always performed after any normally requested action, OR
  3. actions 3 and 4 are performed around any normally requested action (e.g. action3 original action4),

The separating these constraints is inclusive. That is, multiple such tweaks may be applied to a service.

Notice, a user does not always want these additional constraints to apply, but they may decide that some additional tweak like this is necessary for one of the third party APIs.

Your system should be designed such that these constraints are also transparent to users of the API. When I try to invoke a behavior, I should not need to care which service or which additional behaviors will be invoked.

So, if a provider was configured to support both tweaks 1 and 3 as listed, then invoking "action 1" would result in one of the following sequences of observed behaviors:

1
2
3
4
action 1
action 3
action 1 // The originally requested action
action 4

OR

1
2
3
4
action 3
action 1
action 1 // The originally requested action
action 4

Task 3)

People are complex and multifaceted. Sometimes, they are productive in a work oriented fashion. Sometimes, they are productive in a leisure oriented fashion. In both cases, people will often develop a set of tasks that they wish to perform. Your task is to model this.

A Person may be given either WorkTasks or LeisureTasks at an time. When a person is working, they will perform WorkTasks, and when they are playing they will perform LeisureTasks. A task is performed whenever a Persons performTask method is called. Tasks of a given type are completed in the order they arrive, and once a task is completed, a `Person safely may forget about it. A person may switch between work and leisure as needed.

While performing WorkTasks, a person can either be working normally or working in "crunch" mode. When working normally, a person only perorms one task, but when working in "crunch mode", a person will perform 2 tasks every time performTask is called. But this is unsustainable. They can only perform 6 total tasks before they must leave crunch mode for a healthier working process.

Main Goal: Design the API and core implementation for Person that enables the above design.

Submission

Unlike the previous exercises, this one is more freeform. Instead of submitting runnable code, you should submit a PDF with your solutions.

Your solution should still be as precise as code would be, and you might want to express some parts as code. However, because you are not implementing the entirety of a system, you only need to express the parts relevant to your solutions. If you feel that diagrams help to convey your design in some places, you are free to use them.

You can submit your PDF via CourSys as usual.