1

I have two classes, Class A and Class B, that implement a delegate with Methods A and B. Their implementations of Methods A and B might look like:

Class A {
    Method A {
        Action 1;
        Action 2;
        Action 3;
    }
    Method B {
        Action 4;
        Action 5;
        Action 6;
    }
}

Class B {
    Method A {
        Action 2;
        Action 3;
    }
    Method B {
        Action 4;
        Action 5;
    }
}

The two classes implement two delegate methods that are almost identical except Class B performs less actions than Class A in each method. Is there a way I can factor out Class B's implementation into a delegate class that is shared by both classes, and somehow "inject" Action 1 and Action 6 into the delegate methods when needed (for Class A)? If not, what would be the best way to structure this code?

Edit: Also, in the actual implementation, Class A and Class B are pretty different except for the fact that they implement methods A and B in a similar fashion.

hatooku
  • 423
  • 1
  • 4
  • 11
  • Seems like you're asking [how to use the same category for multiple classes](http://stackoverflow.com/questions/9450556/adding-the-same-category-to-multiple-classes). – stevesliva Aug 09 '16 at 14:47
  • @stevesliva Thanks! That is the approach I went with since it was simple and clean. – hatooku Aug 10 '16 at 23:29
  • which one? The objective-c solution that combines categories and protocols, or the swift one? If you did this with objective-c, I'd personally suggest just writing your own answer here... because the other question doesn't make a great how-to for objective-c. – stevesliva Aug 11 '16 at 13:17
  • I didn't really follow any specific answer, it was mostly the idea of using categories that helped me. – hatooku Aug 11 '16 at 18:36

2 Answers2

1

The best way is inherit. Like this:

Class A: B {
    Method A {
        Action 1;
        super.Method A;
    }
    Method B {
        Action 4;
        super.Method B;
    }
}

Class B {
    Method A {
        Action 2;
        Action 3;
    }
    Method B {
        Action 4;
        Action 5;
    }
}

Updated

After reading your comment, I think dynamic message dispatch maybe help.(all code below is in A) 1.Get IMP of B:

class_getMethodImplementation(Class cls, SEL name);

2.Add IMP:

class_addMethod(Class cls, SEL name, IMP imp, const char *types);

3.Send message:

objc_msgSend(self, SEL name, parameter1, parameter2, parameter3);

It's a little complex but conform to DRY.

Lumialxk
  • 6,239
  • 6
  • 24
  • 47
  • But what if Class A was already a child of a different Class C, but Class B was not? In the actual implementation, Class A and Class B both implement methods A and B but are quite different otherwise. – hatooku Aug 09 '16 at 07:21
  • @hatooku I see. Updated my answer and hope it would help you. – Lumialxk Aug 09 '16 at 07:45
0

Factoring out common code into a new class is always a possibility, and often a good idea. However, there is no way for us to know if the implementations of the methods are similar enough to be shared by different classes. Only you would know that. Also, if the implementations require internal knowledge or access to internal state of the host classes, you will find it difficult to refactor. You may end up creating a bigger mess than you started with.

Ultimately, you need to assess the specific situation and decide if the implementations are really the same, or if the delegate methods are used differently by each class.

Avi
  • 7,469
  • 2
  • 21
  • 22