Discussion: Loosen up the inheritance of things to make extending the model easier
What needs to be remodeled?
Their are two possible ways to reuse classes in an object oriented language. The first being inheritance (class U extends/implements T), the second being composition (class U { property: T}). The StApps core model has grown over time and the current principle is to use inheritance to reuse functionality.
The inheritance, as shown in Currently, can be quite complex in some cases (middle part). At other times it seems to work just fine (left side, right side).
A best practise, as written in [Design Patterns: Elements of Reusable Object-Oriented Software, S. 20], is to "Favor object composition over class inheritance". This does not mean to eliminate inheritance at all costs, but to use it, when it's appropriate.
The thing that needs to be remodeld is structure of the classes and their inheritance.
The following diagrams only show the rough inheritance of the classes, not their associations with each other. The diagrams were created by hand and may contain errors or miss some information. Their purpose is to visualize the problem at hand.
Currently
Target (Flat structure)
How is the current model not sufficient?
A flat structure, as show in Target, is easy to understand, maintain and extend, without having to deal with unneccessary additional inherited attributes.
Target is structured by single logical domains, rather than functionality and domain.
Breaking a structure, by adding a new functionality in super-interfaces, that only need to be used by certain implementing types, is less likely using composition.
For example a "payment" functionality (implemented by SCThingThatAcceptsPayment and SCThingsThatCanBeOffered) could be added as required to certain types e.g. Dish payment: Payment, but optional for other types e.g. Room payment?: Payment, thus allowing only certain instances (of Room) to have this functionality.
Another weak point for the flat structure is, that schema.org only allows single logical domain inheritance and using composition for every other used attribute.
Which changes are necessary?
The interfaces on the right (See Target) (starting from the one with the note attached) could be changed into classes. Everywhere, where these interfaces were implemented or extended, there would be a new property with the type of the interface. In fact every connector and app using these interfaces, would need to be changed as well. To use the new properties instead of the inherited properties.
Example
Before
export interface SCRoomWithoutReferences
extends SCPlaceWithoutReferences, SCThingThatAcceptsPaymentsWithoutReferences,
SCThingWithCategoriesWithoutReferences<SCRoomCategories, SCRoomSpecificValues> {
...
}
After
export interface SCRoomWithoutReferences extends SCPlaceWithoutReferences {
categories: SCThingWithCategoriesWithoutReferences<SCRoomCategories, SCRoomSpecificValues>;
paymentAcceptor?: SCThingThatAcceptsPaymentsWithoutReferences
...
}
Do the proposed changes impact current use cases?
Not the use-cases, but their implementation.
@All Please participate in this open discussion. And again: Using inheritance is indeed a viable option!

