|
|
Wednesday, July 02, 2014 |
The Diamond Problem
Posted: 4:25:00 PM
|
When I was learning .NET, one of the things I learned early was that .NET does not support multiple inheritance. Multiple inheritance is having one class be inherited by more than one class. I never had a need to do anything like this for the longest time, so I never really thought twice about this.
Recently, however, I came across a potential use for multiple inheritance. I came across an open source library used in a project I was working on. The library was heavily modified, with multiple fields and methods, both private and public, being added, removed, and changed. It was pretty serious. Of course, the open source project was updated over the years, but since our copy of it was so heavily modified, we could not upgrade.
At first, I thought a good resolution would be splitting out the customized logic from the main project into a derived class, which would allow us to upgrade the project without breaking the custom logic. And this sounded great.
That is, until I realized that there were a number of classes in the open source project that ALREADY inherited from classes within the same project.
I now have a problem. Let's say I have 3 classes:
* Class A, which is the base class from the open source project.
* Class B, which is the class from the open source project that inherits the base class.
* Class C, which is the base class with our customizations that inherits the open source project's base class.
I now need to implement the custmoizations that were made to Class B into a new class, which I'll call Class D. The customizations that were made to Class B depend on the customizations that exist in Class C, but I also need some of the base methods and fields in Class B. Ideally, I want to create Class D to inherit from BOTH Class B AND Class C. But I can't: .NET doesn't allow it. Why?
Because of something known as The Diamond Problem. If I create Class D which inherits from Class B and Class C, and each of those classes inherit from Class A, I could theoretically create methods in Class B and Class C that are based on methods in Class A. When I call those methods from Class D, how do I know whether I need to call the method from Class B or from Class C?
It's called The Diamond Problem because of how the class diagram would look if you mapped out the classes: Class A would be the top point, Class B and Class C would be the left and right points with a line coming to each of them from Class A, and Class D at the bottom with a line coming to it from each of Class B and Class C.
The problem is clear. However, the solution is not. There is no clear cut way for me to construct a Class D that has the functionality I need. There are some very ungraceful workarounds, including copy and pasting code, using multiple interface inheritance, or instantiating the classes you want to inherit as properties of the derived class. None of these solutions are perfect for varying reasons.
In this case, we want to be able to update the open source project as needed, but we want to maintain the customizations that were made to it. Other than multiple inheritance, how would you resolve this?Labels: Coding, Diamond Problem
0 Comments
|
|