Closed odungern closed 6 years ago
I think both solutions are possible. For the handling of the SpecIF data objects it makes it easier, but you have then a superset of properties in the type class. For example you need to have the subject and object types to support the statements, but these properties are not necessary for Hierarchies and Resources. An example where a similar solution is used is the data model for Enterprise Architect (UML tool). All UML elements are using the data model class Element and this class defines an attribute Type to define the UML element type (e.g. Class, Use Case, Action etc.) This makes it easy to change the elemnt type by just setting the type string. In opposite to that the OMG UML metamodel defines one class foer each UML element type and uses inheritance and other meta modeling features. It is not so easy to transform an element type into another, because not all element types have the same attributes and just a parent with very few common attributes. In SpecIF it is not necessary to change the element type from Resource to Hierachy, so I think you can use the approach of just one type element, but it is better to stay on the current solution with 3 different type classes. What you can define is a common base class (perhaps abstract) to define the common attributes like ID, Revision, Title, Description and so on.
I am not sure whether we discuss the same thing. Today, we say: "resources": [{ "id": "Fld-5b6a99f10000bca80137b78cda65fc07", "title": "Dimming", "resourceType": "OT-Fld", "properties": [{ "title": "dcterms:title", "propertyType": "AT-Fld-Name", "value": "Dimming" }, { "title": "dcterms:description", "propertyType": "AT-Fld-Text", "value": "" }], "revision": 20, "changedAt": "2017-06-19T20:13:04+02:00" }], "statements": [{ "id": "RVis-Pln-5a4755dd0000bca801375293a62c90a8-MEl-5bd6bd890000bca8013739588a3f43d6", "title": "SpecIF:shows", "statementType": "RT-Visibility", "subject": "Pln-5a4755dd0000bca801375293a62c90a8", "object": "MEl-5bd6bd890000bca8013739588a3f43d6", "revision": 93, "changedAt": "2017-06-19T20:13:33+02:00" }]
.. and taking the path of polymorphism, we would say: "resources": [{ "id": "Fld-5b6a99f10000bca80137b78cda65fc07", "title": "Dimming", "type": "OT-Fld", "properties": [{ "title": "dcterms:title", "type": "AT-Fld-Name", "value": "Dimming" }, { "title": "dcterms:description", "type": "AT-Fld-Text", "value": "" }], "revision": 20, "changedAt": "2017-06-19T20:13:04+02:00" }], "statements": [{ "id": "RVis-Pln-5a4755dd0000bca801375293a62c90a8-MEl-5bd6bd890000bca8013739588a3f43d6", "title": "SpecIF:shows", "type": "RT-Visibility", "subject": "Pln-5a4755dd0000bca801375293a62c90a8", "object": "MEl-5bd6bd890000bca8013739588a3f43d6", "revision": 93, "changedAt": "2017-06-19T20:13:33+02:00" }]
Inheritance / Polymophism seems to be the issue here. The attribute that makes the difference is called the discriminator. E.g. if you have man and woman the discriminator is the gender. So you could model a base type human/person with the attribute "gender" and you'd all be set. The modelling of derived classes specializations only make sense if there is a difference in structure and or behavior.
The difference in implementation is then that you need a "case" statement for each specific case if you only go by one attribute in the general type. The bad news is that it it might be necessary to know the whole inheritance tree for the case statement if you don't properly "propagate" the discriminator values. In most implementation languages you end up with "is instance of" calls an if comparisons.
Enterprise Architect and MagicDraw are indeed good examples. The EA model has only five base concepts with which they do all their diagrams. The MagicDraw approach is much more specific. These are two opposite design goals: be flexible and general or be precise and specific.
If you look at the metamodel that is used in Profiwik you'll see that there is only 6 elements:
and with these 6 elements it is possible to describe anything you could describe with UML or any Ontology. It is just a question of the level of abstraction you choose. See also:
http://www.bitplan.com/index.php/Meta
The decisison of a common "type" attribute should be based on how much resourceType, statementType and so on have "in common". If they are just homonyms than it is better to have just one attribute "type". The name for this attribute should be well chosen though you might want to use "kind" instead because a type might be interpreted as "class" or "datatype" by some. And a hyphenated version - "spec-kind" might even be better because you are not talking about kind without a context but in the context of specification.
Just my two cents. ...
This is indeed a in-depth discussion. The original post is just about a property name to be used in different contexts. In all cases it labels a property value pointing to the type of the respective instance. In my eyes there is no value in defining some sort of inheritance for that issue/concept ... In essence, there is a choice between readability of the SpecIF data structure and code efficiency, see my last post 23 days ago.
Actually I opt for better code efficiency, because there will be not very many who will read the data structure, anyways. That means, in all contexts we will equally call the property 'type'.
But there is another interesting point: Is 'type' the correct name or is it better to call it differently. In fact, Dublin Core uses 'Resource Class' to describe a group of similar resources. The SpecIF vocabulary reflects this, already. To be consistent we would say: resourceClass, statementClass, hierarchyClass and propertyClass. The instance's properties pointing to these classes are all labelled 'class', then.
Picking up the example:
"resourceClasses": [{ "id": "OT-Fld", ..., propertyClasses[{ "id": "AT-Fld-Name", ... }], ... }, { ... }], "statementClasses": [{ "id": "RT-Visibility", ..., propertyClasses[{ ... }], ... }, { ... }], 'hierarchyClasses": [{ .., propertyClasses[{ ... }], ... }, { ... }], "resources": [{ "id": "Fld-5b6a99f10000bca80137b78cda65fc07", "title": "Dimming", "class": "OT-Fld", "properties": [{ "title": "dcterms:title", "class": "AT-Fld-Name", "value": "Dimming" }, { "title": "dcterms:description", "class": "AT-Fld-Text", "value": "" }], "revision": 20, "changedAt": "2017-06-19T20:13:04+02:00" }], "statements": [{ "id": "RVis-Pln-5a4755dd0000bca801375293a62c90a8-MEl-5bd6bd890000bca8013739588a3f43d6", "title": "SpecIF:shows", "class": "RT-Visibility", "subject": "Pln-5a4755dd0000bca801375293a62c90a8", "object": "MEl-5bd6bd890000bca8013739588a3f43d6", "revision": 93, "changedAt": "2017-06-19T20:13:33+02:00" }], "hierarchies": [{ ... }],
Does it make sense?
With SpecIF 0.10.4 the polymorphic approach has been adopted, see my last post. The context defines unambiguously whether a resourceClass, statementClass, hierarchyClass or propertyClass is referenced.
Currently a 'resource' has an attribute ‚resourceType‘ and a 'statement' has an attribute ‚statementType‘; similarly 'hierarchy' and 'property'. The idea was to express with the attribute-name what it is. While this makes the data easier to read and to understand (who actually wants to do that ;-), it is more difficult to process. Thus another approach: Anyways, the context defines what a valid value is in each case (a 'resource' needs a ‚resourceType‘ and so on). Thus a constraint check can easily ascertain that a meaningful reference has been made in a particular situation. From a programming point of view a polymorphic approach is by far preferrable: All instances of type 'resource', 'statement', 'hierarchy' and 'property' get a commonly named attribute 'type'. Then a common code can process all instance types without distinguishing the cases.
Opinions?