This is based on a tangential alternative that arose from my other post on dispatch tables.
In objective-c object-oriented design, suppose I am designing a class that requires external data to execute. The class has a number of variations, and each variation executes differently, at different times, based on different external data. What is the best way to execute/implement this design?
As a concrete example, suppose the class is to represent a medical condition. There are 100-200 different medical conditions, each of which reacts to different stimuli, and each of which does different things once triggered.
The primary difficulty with which I need help is how to pass in the data necessary for each variation to execute once triggered -- data that cannot be encapsulated, and data that cannot be simply used as argument to input into an overridden function by the nature of being different for every variation of medical condition.
For instance, when the sunburn condition triggers, it needs data for the weather passed in, to determine the severity. When insomnia triggers, it needs a recent history of other medication taken. Indigestion needs weight of food consumed. The trigger points also differ, of course, but I've enumerated that and stored it as a enum value in my superclass. The question is how to handle data: do I subclass for every possible input that any subclass could possibly need? Or use a design pattern like Visitor?
Thanks for your help.
EDIT: Here's an example situation that I hope can make my question more concrete:
A bunch of patients are admitted into a room, and each one has a different MedicalCondition (in my current code, I do not subclass MedicalCondition, I only call them different NSString names). It's a property of Patient. Then, through the flow of the program, various MedicalTests are conducted on each Patient. MedicalTest has data like "int power" and "BOOL putsPatientToSleep" and "float chanceOfCausingFainting" and also vary greatly from MedicalTest to MedicalTest. The room itself also has qualities like isSunny, isDark, fullOfContagiousPatients, etc. that become data that I will need once a MedicalCondition flares up.
Now, through the battery of tests, suppose one happens that is one of the triggers for the tested Patient's MedicalCondition. Let's say it's called @"sunburn" The MedicalTest had a quality that causes the tested Patient's MedicalCondition to activate. My problem, in essence, is, where and how do I write the activation code for ExecuteWhenThisConditionFlaresUp(...input that varies from MedicalCondition to MedicalCondition...)? When the sunburn Patient has his MedicalCondition fire, how do I vary that response from the response of a chills Patient, for example? I can write the function fairly simply given the input data, but the problem is that the input data (i.e. function signature) will differ from Condition to Condition, and I also have 100s of MedicalConditions that do different things, so I'm not sure if it's the right thing to subclass MedicalCondition just to have different behavior on flare-up. Is there any way to index or store a functor in objective-c? Maybe write 100 different functions, all with different signatures but given access to a general input NSArray, and then store the appropriate functor with the appropriate NSString? (keeping only ONE MedicalCondition class)
This sounds like a perfect example of the composition vs inheritance problem.
If you try to use inheritance for this, you'll run into the a problem. Imaging you have a class Employee with sub-classes Technician and Manager. Now imaging you have a class Customer, with various sub-classes. What happens when you have a Customer that is also a Manager? In Objective-C there is a single inheritance chain (fortunately), so this would be difficult to model with inheritance.
The solution to this problem is to use composition instead. This is deceptively simple - it simply means you create a container class and add traits (ie protocols or concrete collaborators to it).
It would go something like this:
It sounds as though you could add a collection of Trigger objects to a MedicalCondition. This might be a Protocol or an abstract base class.
You might be interested in exploring domain-driven design.
As far as other specific patterns that might be relevant, its difficult to say given the high-level requirements that you described in your question. I would say try to focus on the requirements themselves and the process of modeling them, rather than looking for a pattern to apply early on. As you continue to model the appropriate pattern will shout out out you.
Update: (based on comments discussion)
Consider using the observer pattern. In this you can have triggers. Any time you call the setActivated method on a trigger, any disease observing this can perform an action. The Apple framework for this is key-value observing (KVO). . there's also an open-source framework called ReactiveCocoa, that you might find interesting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With