I have the following example where CarTypeTesla
is an enum value.
Car *car = [Car carOfType:CarTypeTesla];
+ (instanceType)carOfType:
does an enum check and returns an instance of a given Car
subclass, like this:
+ (instanceType)carOfType:(CarType)carType {
switch (carType) {
case: CarTypeTesla: {
return [[Tesla alloc] init];
}
case: CarTypeMustang: {
return [[Mustang alloc] init];
}
}
}
So that back in the main file something like this can be done (And I don't have to expose my Tesla, Mustang, and 20 other subclasses):
Car *car = [Car carOfType:CarTypeTesla];
NSLog(@"%@", car.batteryChargeRemaining);
or
Car *car = [Car carOfType:CarTypeMustang];
NSLog(@"%@", car.gasFuelRemaining);
How can I use this Factory Design Pattern, to only display properties / methods related to the returned subclass based on the enum value provided (Wouldn't want to show -(float)gasFuelRemaining
when using CarTypeTesla
?
What you are implementing is known as a class cluster in iOS. Some framework classes, like NSArray, NSString and NSDictionary work like this (they optimise by providing different solutions based on the amount of data they hold). This allows you to have a generic, common class that's exposed to the API, while hiding all the intricate details for solutions that are not necessarily relevant for developers, including solutions that are different based on context but should behave the same. What this means is you have a generic base class with common methods that are implemented across all other hidden classes.
The way I see it you have to options:
1 - You implement all methods in all your car classes, and have them return empty values when they are not relevant, in which case your Tesla
instances would return 0 for gasFuelRemaining
OR
2 - You implement protocols for different types of cars, like ElectricCarProtocol
and FuelCarProtocol
and have a common method in your Car
class called fuelRemaining
that does something along the lines of this:
if ([self conformsToProtocol:@protocol(ElectricCarProtocol)]) {
return self.batteryChargeRemaining; // you might need to cast the object here
}
return self.gasFuelRemaining; // idem
Hope this helps!