I came across this scenario today and wondered if something like this already exists: a built in way to automatically delegate a protocol implementation in Swift.
I know it’d be only syntax sugar on the code, but I’m actually more curious than in need of this feature.
Here’s how it goes:
Because of bad architecture on my company’s project, I ended up having to do something like this:
protocol Cat {
func bark()
}
class A: Cat {
func bark() {
print("I love prog rock")
}
}
class B: Cat {
private let a = A()
// all of Cat implementation on B should return A implemention of Cat
func bark() {
a.bark()
}
}
In the real case, there are several protocol functions that I’m having to use A’s implementation on B implementation :S (not just one, as illustrated).
So, I’m not asking what would be a better approach so that I don’t have to delegate all of B’s Cat implementation to A’s Cat implementation. No.
What I’d like to know is:
- given I have to do this, would there be a better way to do it?
- Is there some built in solution, like, inside B scope:
self.CatImpl = a.CatImpl
. - Can you imagine any scenario where this would be actually useful (and not just a workaround for bad architecture management)?
What are your thoughts?
2
Answers
To me, this implementation sounds pretty similar to the Proxy Design Pattern, where B proxies access to A. I has it’s uses. Fixing bad architectural decisions is not one of them lol. If B always calls A and does nothing else, I’d consider adding tests to B and refactoring to replace it with A
I am not entirely sure what it is your are trying to do, or what exactly your question is. I get that you are doing this because of "bad architecture", though I do not now what that bad architecture might be. But given that you have to do this, you could get the same effect by subclassing A in B. This would eliminate the need to have B’s bark() method call A’s bark() method. It would also eliminate the creation of an instance of A every time an instance of B was created, and hence would take up less memory, and run faster as well. I would see that as something like this;
I do not know if that would fit your needs, but the output we be identical.