Reputation: 3582
I am refactoring two classes, trying to combine them into one, where previously one was a heavier duty version of the other. The problem is that the heavier duty class does not completely enclose the lighter class. I am thinking of just creating a class that includes all necessary properties of both, where each pre-existing class is now part of the same class but instantiated with a different initializer.
To give you an idea let's say I want to reduce these:
ClassA.h
@interface
@property int shared1;
@property int shared2;
@property int a1;
@property int a2;
@end
ClassB.h
@interface
@property int shared1;
@property int shared2;
@property int b1;
@property int b2;
@end
My plan is to combine these to:
ClassC.h
@interface
@property int shared1;
@property int shared2;
@property int a1;
@property int a2;
@property int b1;
@property int b2;
- (id) initHeavyVersion; // this will set b1 and b2 as well as shared but not a1/a2
- (id) initLightVersion; // this will set a1 and a2 as well as shared but not b1/b2
@end
Is there any harm in doing this when the non-overlapping properties could themselves be fairly large objects? The way I see it, when these properties are unused, they should just be carrying around a few extra nil
s , nothing more. So the performance/memory issues should be minimal. The downside is a confusing public interface.
I reject composition because that would still result in two classes, whereas my goal is to condense these classes into one (at almost any cost). Similarly, a delegate would create the same problem.
The only alternative I see to this is to use associated objects, but this seems unnecessarily tricky/fancy and would still rely on separate initialization functions.
Any critiques or alternative suggestions would be most welcome.
Upvotes: 1
Views: 121
Reputation: 535746
The usual approach with object-oriented programming is to make the shared part an abstract superclass. That way, the first (concrete) subclass has only the A properties and the second (concrete) subclass has only the B properties, but the functionality for the shared material is encapsulated nicely. It is easy to enforce the rule that the superclass itself should never be instantiated.
If you insist on just one class, you are basically doing the opposite of object-oriented programming. That's not wrong; it's just a little strange. If you're going to do that, I would suggest adding some error-checking. For example, you could have a flag that says whether this is the A type or the B type, so that you can throw an exception if someone tries to access an A property from the B type. But this seems nutty to me, because you are reimplementing object-orientation in a baser form. The whole purpose of class hierarchies is to replace conditions with typologies; you are trying to undo that benefit, and I don't see why.
Upvotes: 2