Understanding Multiple Implementation Inheritance and Roxy Code Generation
Exploring the concept of software building blocks and concerns in Object-Oriented Programming (OOP), highlighting the importance of managing multiple concerns within classes. Delve into the challenges and solutions of multi-concern implementation including the use of mixins and plugin-based imitation of multiple inheritance.
Download Presentation
![](/assets/img/so-down.gif)
Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
E N D
Presentation Transcript
Multiple Implementation Inheritance and Roxy Code Generation
Software Building Blocks and Concerns (review of the previous presentation) Software products are build out of building blocks. In OOP the building blocks are classes. They can be created and tested independently. Software concern is a concept that refers to a single side of the software or a software building block. E.g. suppose you have a class that has some data, allows the object of the class to get selected and removed within some collection of objects and does some logging. In this case Data, Selection, Removal and Logging are separate concerns. Usually class has to implement multiple concerns see PersonVM class from MultiConcernsTest.
Take a closer look at PersonVM class All of the concerns that combine the class have usage and implementation sides. Usage side provides specification of how this concern can be used, while implementation simply implements the concern s functionality. For example Selectable concern s public interface is represented by ISelectableItem<T> interface while its implementation is represented by SelectableItem<T> class. The same goes for Removable concern. Data concern is only represented by a class, which also provides a public interface for the usage side of the concern. Usage and Implementation sides of the concerns often match but not always. For example behaviors simply modify the behavior of some external object and as such they have only implementation concern without any usage concerns, e.g. look at BusinessGroupVM under MultiConcernsBehaviorTest project.
Multi Concern Implementation In order to make it easier to build software, the language needs to provide some means of mixing various concerns both their usage and implementation parts. Usage parts of the concerns are mixed easily in C# and Java using multiple interface inheritance. Major languages (including C++) provide no way of easily mixing the implementation sides of multiple concerns. Even though C++ supports multiple implementation inheritance it does not allow Merging the similar properties or method from super classes together Renaming properties or methods The so called diamond problem can only be resolved by so called virtual inheritance which should be preplanned when you create the superclasses a condition that should not be imposed. Mixins are the closest imitation of the correct multiple implementation inheritance, but even they usually have some severe limitations.
Plugin Based Imitation of Multiple Inheritance There is a standard way of imitating multiple implementation inheritance using plugin (wrapper) pattern, e.g. see Implementing Adapter Pattern and Imitating Multiple Inheritance in C# using Roslyn based VS Extension Wrapper Generator and Simulated Multiple Inheritance Pattern for C# Take a look at PersonVM class within PluginBasedMultipleConcerns project.
This class implements 4 concerns corresponding to 4 interfaces: IPersonData representing the usage side of the Data Concern ISelectableItem<PersonVM> representing usage side of the Selectable concern IRemovable usage side of Removable concern INotifyPropertyChanged usage side of the notifiable concern We implement these concerns using plugins defined within Plugins region of the code. For implementation we use the following classes: PersonVMData for Data concern implementation SelectableItem<PersonVM> for Selectable implementation Removable for Removable implementation Notification concern is also implemented by SelectableItem<PersonVM> - since the class implements INotifiablePropertyChanged interface.
Next we wrap the methods, properties and events. Here is an example of a property wrapper: Method Wrapping is very similar:
Event wrapping is slightly more difficult Note that we sometimes have to replace the object we receive with this reference.
Ways to implement the above paradigms You can see that the plugin implementation of multiple implementation inheritance contains a lot of standard plumbing code that can be generated. Writing all the wrappers is unnecessary waste of time. There are several ways to make this concept easy to use: Modifying the C# compiler and adding the multiple implementation via plugins capabilities to it. This is doable because of the great Roslyn compiler, but I doubt it will be easy to convince people to start using essentially a new version of C# not approved by MS. Generating the plumbing code e.g. using Single File Generation VSIX utility. This is the approach I took in Implementing Adapter Pattern and Imitating Multiple Inheritance in C# using Roslyn based VS Extension Wrapper Generator. This will require all people on the project to use the VSIX extension. Finally the approach I took in Roxy is to use inversion of control and allow container to generate the needed plumbing code. I hope that the software engineers will find it easier to use a IoC container rather than use modifications of the languate.