locked
inheritance in M: relational vs. OO modeling RRS feed

  • General discussion

  • In the Oslo FAQ, as a response to why M doesn't support inheritance, it says:

    "M" does not have inheritance because the relational data model does not have inheritance.

    Why should M position itself on the side of the storage model as opposed to the conceptual model that OO developers are used to working with when contemplating their problem domain, and would prefer to deal with?  The Entity Framework and other ORM frameworks support mapping of inheritance in object models to tables and relationships within RDBMSs, and I've used inheritance in my own models with excellent outcomes.

    In MSchema, I can perform some inheritance-like typed things, such as:

    type Contact
    {
        FirstName; LastName; MobilePhone; HomePhone;
        StreetAddress; City; PostalCode; State; Country;
    }

    type Employee : Contact
    {
        EmployeeNumber; WorkPhoneExtension; Manager;
    }

    type Customer : Contact
    {
        CustomerNumber; RewardPoints;
    }

    Disregarding the triviality of this common example and focusing on this pattern of reuse, this states that the Employee and Customer types contain all of the fields defined in Contact.  However, because there is no inheritance, extents of these types generate three separate tables, each with all of the fields it needs, with no overlap.  In order to get a list of all contacts, I therefore have to remember to union a subset of all of these tables together.

    I guess I see M as a better replacement for EF's CSDL (conceptual schema definition language) than the relational representation.  Being an object oriented designer, when I model a domain, I think in objects, and that means inheritance relationships, too.  Of course, in a structural type system, it doesn't make any sense to inherit behavior (and therefore to include polymorphism), but reference associations are not the only valid relationships that I want to model in my domain.

    Actually, what it looks like is that M does inherit structural information--it pulls those columns right into the inheriting type.  What I want is for it to stop doing that, and to infer an inheritance relationship to a separate type instead.

    Friday, January 23, 2009 11:48 PM

All replies

  • Yes. I found the same thing strange.

    As coincidence I discussed a little bit here yesterday:

    http://www.bpmnforum.net/blog/?p=78

    Saturday, January 24, 2009 1:40 PM
  • Considering that Oslo is an attempt to usher in Model Driven Development, the question is: which model do you want to start with?  As a developer, all of the workflow and business logic revolves around the conceptual schema in my head.  How that actually maps to a relational database is a set of implementation details.

    In the project I'm starting now, I'm using M to model the problem domain to get up and running as fast as possible.  If M is a storage-specific language for relational databases, then I feel like I need another way to do "model first" at the conceptual level (e.g., for use with Entity Framework solutions).

    When using DevExpress's XPO ORM product, for example, I'd define a set of C# classes (using inheritance, etc.) and XPO would use that conceptual model to create a database schema, which worked really well.  You don't always want to generate things in this direction, but having the option to do so is important.  Being able to update the mappings and make changes to the structure of either model (conceptual or physical) is also important, of course.

    I can see the challenge of treating M this way.  It requires the ability to transform the model from conceptual to physical, and there's more than one way to do these transformations, so it would also require a way to define the transformation rules.

    Is there any thought or work going into M/Oslo around this?

    Saturday, January 24, 2009 4:43 PM
  • dvboom said:

    Considering that Oslo is an attempt to usher in Model Driven Development, the question is: which model do you want to start with?  As a developer, all of the workflow and business logic revolves around the conceptual schema in my head.  How that actually maps to a relational database is a set of implementation details. [...]

    I can see the challenge of treating M this way.  It requires the ability to transform the model from conceptual to physical, and there's more than one way to do these transformations, so it would also require a way to define the transformation rules.


    If M does not support inheritance, it is merely a repesentation modeling language, but in my view does not qualify as a conceptual.

    It is decisive that a conceptual modeling language is representation independent. For a discussion see

    Frankel, David. The Meta Object Facility. [book auth.] David S. Frankel. Model Driven Architecture. Applying MDA to Enterprise Computing.: Applying MDA to Enterprise Computing . s.l. : Wiley & Sons, 2003.

    We do not start from scratch, but there are a lot of metamodels, that have already been defined making extensive use of inheritance.

    Also I do not see why the M language "user" must define a transformation. That can be done canonically intrinsic in the language just like with n:m relationships, where an intermediate table is generated in SQL. Even if there are several possibilities, the M language architects could opt for one.

    Saturday, January 24, 2009 7:21 PM
  • As I see it, having another relational schema tool is only so useful.  Having a powerful conceptual modeling tool would be much more useful.  The former can be generated from the latter and either some kind of mapping file, or like you say, some default/automatic mapping.

    Saturday, January 24, 2009 7:37 PM
  • Object oriented programming is just another methodology.  I'm sure you didn't think in OO before it was supported in your development environment.  I'm equally sure that you'll leave OO behind as soon as there is a better way of thinking about software development.

    Maybe Microsoft are starting to work out out that subclassing, inheritance and polymorphism aren't what they are cracked up to be.

    Tuesday, January 27, 2009 11:45 AM
  • OO isn't "just another" methodology.  It's a way of thinking and designing that has been so important, it's eclipsed everything that came before it (procedural).  I didn't think in OO before it was supported?  First of all, object oriented programming has been supported for a very long time.  I remember learning it as part of Turbo Pascal 5 MANY years ago, and it wasn't a new concept then.  OO has been so successful because it matches our natural mode of thinking.  The relationship between a Person and an Employee, going from general to more specific, is something that is very natural to our brains.

    Throwing out support for OO design without broad support from the community would be terribly foolish.  Whether it belongs in Oslo for modeling is another matter, but I recommend highly that inheritance be supported.  It's useful, period.

    Tuesday, January 27, 2009 2:00 PM
  • If the community are as passionate about inheritance as you are, then it would be foolish to throw it out.  That is, if they don't evolve the environment and educate the community.

    OO is a good methodology.  You can get a lot of work done in it.  But it's strength really is in development of code, rather than maintenance of code.  It falls down in really large projects.  You end up with your SomethingReallySpecific class many levels deep from your parent AnythingAtAll class.  Worse, you are not just overriding to opt into new functionality, you are also overriding to opt out of base functionality.

    WPF is a great example.  Amazing piece of functionality but what a mess.

    You can program without the inheritance pattern because the aggregation pattern is equivalent.  There's barely even that much more syntax required. In my experience the cons of inheritance outweigh the pros.  I stopped using inheritance a year ago and my code has never been better.  As a community, will be helping Microsoft if we can give up our inheritance addiction.  Just consider how much complexity could be removed from the development environment.

    I wrote an article you might be interested in.  It's not a complete proof of why OO fails but I think it explores some interesting ideas.

    http://kestral-katalist.blogspot.com/2009/01/code-is-user-interface-part-i.html

    And note that I don't really think subclassing is for jerks, that title is a throw-away line for controversy sake.

    Tuesday, January 27, 2009 11:57 PM
  • OO and inheritance have more strengths than merely development of code.  In my original post here, it allows for all data of the base type to be stored in one table, instead of spreading the same subset of data across many different tables.  I agree that inheritance has a potential for abuse, but I think any tool or technique does.  I also agree with the principal to "favor object composition over inheritance", but inheritance does have a use.  In single inheritance languages, you need to identify what an object IS in contrast to what an object needs to interact with, but once you've established that pattern of thinking, it really isn't difficult.  I don't think WPF is a mess at all, at least not for any reason related to inheritance.  It's a deep hierarchy of inheritance, true (moreso than Windows Forms even), but it seems appropriate for such a complex system.  Without inheritance, you'd have to implement many interfaces and delegate with a ton of additional code to achieve the same thing.  In a framework as large as WPF, the delegation code would grow to ridiculous proportions, would bloat the code unimaginably, and would provide thousands of points of potential failure.  Inheritance keeps the code slim and clean.

     

    In your article you say you don't know where polymorphism exists in the real world, but it's everywhere, and I use it frequently.  There are entire common design patterns that revolve around it being available.  When you draw shapes, for example, your Draw or OnPaint method is polymorphic, and determines its actual drawing behavior from the specific class, and yet a collection of shapes can be managed as abstract Shapes.  I've been looking through examples of games written in Silverlight, and when I use Reflector to look through the .NET Framework code, polymorphism is used all over the place.  You're just not looking very hard.  And your article's statement about it being naive to interact with an interface without knowing about implementation?  That's the point!  If you can't treat an interface naively, then you are doing something horribly wrong.

     

    This is an interesting topic, but not really the forum for it.  My point was simply that, for those of us who use inheritance and other object oriented features with great success, leaving it out of Oslo would be a mistake.

     

    This article on the Entity Framework is a case in point.  One of the subject headings contains the text, "Modeling at the Right Level of Abstraction".  That's what I'm looking for: to use M to model at the right (conceptual) level of abstraction.

    http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx#ado.netenfrmovw_topic2


    Wednesday, January 28, 2009 3:49 PM
  • I'll try to stay on topic, but first:

    • It's probably a little unfair to criticise WPF.  It's the best UI framework I've ever seen.  The point I was trying to make is that the inheritance may have helped the original development team.  But it will hinder the maintenance team, so don't expect rapid development anymore.  And it hinders the end user because we have to wade through hundreds of members when we click Ctrl+Space.  Everyone complains about the WPF learning curve but there's really not a lot of new concepts to learn.
    • We create abstract concepts to categorise real world objects.  As with all categorisation, there is no one single dimension (or single inheritance) that will make sense.  Shape is a useful abstract concept.  What do you lose if you describe it with composition instead?

    On with the real topic.  I'm suggesting that OO inheritance is not the right level of abstraction.  Forcing it into the entity model might be a bad idea.

    Perhaps your relational database requirements are conflicting with your OO programming requirements?

    You want:  select * from Shape

    Because that is a really useful thing to do in a relational database.  You don't want to have to do unions to get this information.  Fair enough.  But I'm not aware of support in .NET framework for retrieving all instances for a particular conformant type (in memory).  You'd have to manage the list yourself.

    I don't think that you can escape that the contraints of the underlying relational database.  They don't support inheritance.  You could be trading one conceptual gain for massive performance problems.

    You would need to join to all the possible (and potentially nested) child tables so that you can have the correct polymorphic type in memory.  That is, you don't want a list of Shape instances.  You want a list of Triangles, Squares and Circles instances.  These joins are really expensive and there is no current support in the downstream data access.  If you are using ADO.NET you'll have to resolve this yourself.  Linq to SQL would need to be extended to be aware of this extra complexity.

    SQL joins are really expensive.

    I would very much agree that we need a new data storage layer.  Relational SQL doesn't express what we want to do.  If you are interested, there are posts on my blog on this topic.

    Thursday, January 29, 2009 12:38 AM
  • How will inheritance hinder the maintenance team?  I've spent a good deal of time studying source code for the .NET Framework and other frameworks and libraries, and unless there is some really bad design, I don't have any problems understanding the inheritance relationships involved.

     

    Granted, Intellisense gets to be unwieldy at times, but this is a shortcoming of the tool rather than application design, and can be easily remedied with a new version of Visual Studio or a third party add-in.  (I've always wanted the ability to view only certain kinds of members, only members of the current type, or a base type, etc.)  Within the code itself, with tooling that lets me "go to definition", I can easily jump from a derived class to a base class, etc.

    There may not be a single way to define inheritance for concepts in general, but in the much more restricted scope of our application with its well-defined purpose, I've never had a problem finding the appropriate abstractions and inheritance relationships.  My designs do contain object composition primarily, the use of interfaces instead of inheritance, and so on.  It's only when I must inherit from a specific class, or when creating my own base class provides a lot of value (like greatly reducing the code I need to write on a regular basis) that I use inheritance.  So while not used everywhere, in every large system that I design, I do find uses for these base classes and inheritance relationships.  Inheritance can be overused and abused, but it would be foolish to take it out of our programming languages altogether, and force people to never use it.

    Inheritance is not a "level of abstraction".  It's a powerful tool for describing a common type of relationship.  When I model something, I want a rich assortment of good tools to describe my entities and their relationships, just as a painter wants a good palette of colors and a good assortment of brushes.  I don't want a poor, constrained, limited set of tools that someone is forcing me to work with based on some "principled approach" that doesn't match how these things are used in my job or the rest of the real world.  If you want to paint in black and white and you think that's a great style, more power to you.  But don't tell me I can't use red when red has been used successfully and with great affection since the 1960's.  That's not the way to develop a framework that appeals to the majority of developers.  Inheritance has proven the test of time, and continues being incorporated into new compilers because of the value that developers perceive in it.

    To say that inheritance is "forced into the entity model", I don't see any profound resisting force.  It takes effort, but like I said, this effort is regularly and routinely spent because of the great benefit and value.  It's a great investment.

    Think of it this way: if your anti-inheritance arguments have significant merit, you'll be able to convince the masses not to use that feature, and we'll be no worse off for having it.  (We have "goto" in C# but I wouldn't ever use it.)

    My relational database requirements are conflicting with my OO programming requirements.  It's called the Object-Relational Impedence Mismatch, and has been studied broadly and in depth.  Microsoft's initiative with Entity Framework is so important because they are beginning to address this, and now .NET development has a fairly clean (and getting better soon) way of modeling in terms of a code object model.  How it's persisted to a relational storage engine is an implementation detail.  The same with WCF: we define our messages and endpoints in code, but the protocols or formats used are an implementation detail, stored in some kind of configuration file. That's the whole crux with Oslo, that we should consider writing our applications in a model-driven way.  We need our conceptual level model, which is easiest to work with, most natural for our brains to understand and manipulate, and the transformations for how to store that information in a relational database are a configuration detail.  Up to a DBA to reconfigure, perhaps.

    This is due to the natural progression of raising the abstraction level to make us more productive.  To say that inheritance doesn't work in a relational model, it sounds like you haven't seen one of the many successful object-relational mappers that have been around for many years now, and how they map inheritance relationships to joins and other patterns in a database.  Not every operation needs to perform a join, and there are tricks to optimizing queries to acceptable levels of performance for all but the most speed-demanding problems out there.  As explained in .NET Rocks! interview with Ward Bell (author of IdeaBlade's DevForce ORM), developer productivity and not raw performance has been the dominant force for a long time now.  If that weren't the case, we'd all still be programming in assembly language.

    There's no such thing as passing a parameter to a method in Assembler, just as there's no inheritance in a relational database, but you can push some values onto the stack, push your current instruction pointer, and make a call to a memory address or label.  It's all about transforming one layer of your model to another, translating or mapping these high-level constructs to a set of low-level constructs.  This is also exactly in line with what Oslo is putting front and center: creating new languages and generating dynamic parsers that transform a model in one format to another which is better suited for driving your application or system.

    What I'm trying to say is that Oslo is this next layer of abstraction, and the way forward involves making good use of the layer below it, not leaving gaping omissions in the set of supported tools.

    We need inheritance in M and in Oslo.

    Thursday, January 29, 2009 5:52 PM
  • If you're interested in knowing how to use inheritance with the Entity Framework, Zeeshan Hirani posted a 514 page book, that explains it step-by-step, among many other EF techniques.
    Thursday, January 29, 2009 5:56 PM
  • Callan, 

    ImhO you miss the point. It is not about OO programming, but about OO modeling.

    Just look at your BPMN models in M. What is your message, when you made these models? That each and every entity is scattered across so many tables?

    You used inheritance - but only on the type level. And not with the BPMN type hierarchy, but with some helper type. At the extent level you did not use inheritace. At the extent level you used a manually modeled foreign key relationships - that are all canonically derivable from the BPMN type hierarchy.

    So what do these modeld teach me other, than that inheritance is missing in M at the extent level?

    So M claims to be MSs answer to the model driven architecture and development. Which model in that area does not use inheritance?

    Thursday, January 29, 2009 8:09 PM
  • frank.michael.kraft: my apologies, but I don't think I follow your message.  Some clarification would be appreciated?

    dvboom: I respect your reasoned argument and accept that my words aren't compelling on their own.

    I'll confess that I'm on this forum because I have been doing parallel research to Oslo for the past year.  One of the base assumptions of this research is no inheritance and was reassured when Oslo seemed to agree.  Hence I couldn't resist joining your thread!  I hope to be able to share the results of my research in the future.  Put my money where my mouth is and all that...

    Anyway, I've always thought that Oslo is missing a specialised data access layer (or ORM I guess).  The M in a nutshell powerpoint says:

    You can program against the generated SQL with whatever data access technology makes you happy, e.g. sqlcmd.exe, ADO.NET, LINQ to SQL, Entity Framework, Access, Excel, ODBC, OLEDB, EIEIO…

    My posts on your thread have been based on this assumption.  I don't see how you can have the OO modelling you want while using relational data access technology.  Do you think we need a thread for 'Oslo needs its own data access story'?

    Thursday, January 29, 2009 11:51 PM
  • Callan, 

     look in C:\Program Files\Microsoft Oslo SDK 1.0\Models\Business\BPMN

     Take for example

    Activity.m

        type Activity : DerivedItem
        {
            IsLoop : Logical = false;

           .... shortened for brevity ....

       }

    The type Activity inherits from DerivedItem, which is nothing else than an artificial type which has nothing to do with the BPMN inheritance hierarchy.

    Instead in BPMN Activity is a subclass of a FlowObject. So what do you do?

        Activities : Activity* where
            item.Id in FlowObjects.Id;

    You have two extents, one for Activities, one for FlowObjects. You hook them up by id. Manually!!!!!

    Is that a good idea? It makes all impressions of a workaround. Why don't you hook them up generically, if you have inheritance - which you do anyway all over the model files.

    Friday, January 30, 2009 1:59 AM
  • Frank, I'm not entirely sure I follow your point.  Apologies if I have misunderstood you.

    I think your example could equally be interpreted as evidence that inheritance itself is the problem.  But rather than start that argument again, can put this down to bad modelling?

    M type inheritance is structural.  It just kinda looks like OO inheritance.  The BPMN author needs the Activty's FlowObject to exist in the FlowObject table - rather than inlined into the Activity table itself. 

    I would have aggregated a reference to FlowObject (a foreign key).  Instead, the author has cheated by using an ID constraint.

    Friday, January 30, 2009 2:50 AM
  • Callan Hodgskin said:

    M type inheritance is structural.  It just kinda looks like OO inheritance.  The BPMN author needs the Activty's FlowObject to exist in the FlowObject table - rather than inlined into the Activity table itself. 

    I perfectly agree to this point. There is no use of scattering the FlowObject Aspect (i.e. the fields, that belong to each and every FlowObject) across different extents. That would destroy polymorphy - i.e. getting all FlowObjects with one select. That was the original complaint of this discussion.

    So the solution ImhO chosen is somewhat smart. The only thing I complain about why there is the need to manually hook up the tables. This should be a built-in feature and there should exist a built-in member collection "super" for this kind of construction. Also there should be a built-in view to get all of an Activity (including the FlowObject aspect) at one select (if needed).  (By the way today it is not even possible to construct a join view manually - I did not get it managed. So all the logic has to be in the client coding, which ImhO is bad design.)

    Then ImhO you will find, that OO isn't the problem any more. With that you would even have multiple inheritance. I can't think of a reason why this should not work.


     


    Friday, January 30, 2009 3:27 AM
  • Callan,

    The M in a Nutshell quote, ... I saw that, too.  I would venture a guess (Oslo team, feel free to correct me if I'm wrong) that because the Oslo project is so young, it's still not completely formed in concept as to what it's potential is, what it hopes to accomplish, or precisely what direction things are going with every detail.  One of the great things about the team's approach of "release early and often" is that they can get a lot of feedback from those of us thinking about it and getting involved with it early.  In other words, I think it's just too early to know how Oslo will interact with EF/ORM.  What I interpret from that quote is, "we don't have anything special for Oslo in this regard, but in the meantime, there's nothing stopping you from using it with all this stuff..."

    Friday, January 30, 2009 5:04 AM
  • dvboom,

    Should we start thinking about how Oslo will interact with EF/ORM?  Seems like you can't have your OO modelling until there is a strong story on data access?

    There are some other storage requirements that I'm really keen on:

    • value based update conflict detection
    • implicit record version control
    • support for fetching objects as they were at a timestamp
    • comparison tooling for logical documents
    • language and tools for migrating the model

    Then there's some ideas that seems possible (because it has been achieved in the source control world).  But it will be difficult to implement in structured data:

    • Save but do not publish (the shelving concept)
    • Permissions and immutability rules for instances
    • Branch, join and labels
    Friday, January 30, 2009 5:21 AM
  • This is  a great discussion.  It is exactly what is meant by the next sentence of the FAQ answer:

     

    We are both listening to users’ issues and thinking about ways to make implementing inheritance more easily.

     

    Ignore the grammatical error for now.  We'll fix that.

     

    Let me explain what is going on.  We really are working on representing inheritance and ontologies.  It is a tricky subject especially if you are trying to be as precise as M is and want to support all of the different flavors (pun intended).  If you don't believe this try a search on citeseer and count the number of academic papers that come back. 

     

    That said, M is a high level modeling language based on first order predicate logic plus recursion. This formalism has proven itself over time and encodes a huge amount of descriptive power.  While many people will use M to model storage the potential is much greater.  The challenge to the M community (you, me, everyone) is to find new ways to exploit that power.

    Friday, January 30, 2009 4:02 PM
  • Callan, I'm interested in knowing what the Oslo and EF teams have been thinking to start with, if/when they're ready to disclose any of that.  I share your list of concerns, though I see much of that landing on the EF side, conflict detection and resolution by the Sync Framework team, immutability of objects by the BCL team, comparison tooling by the VS team, etc.  It's going to take a lot of collaboration among teams to get it all right (as well as a cross-discipline approach within the Oslo team).

    All of your version control points may be better left up to specific application design, as there are so many ways to model and implement that functionality.  Although, perhaps Oslo will facilitate enough of an advance in model sharing that "open source models" for things like version control could be published to some kind of "model gallery" website.  Think of how we share design patterns today.  Perhaps in the future, Oslo will let us share model designs for common problem spaces, to act as a starting point to customize and build on.  If we had the M models for Northwind, AdventureWorks, and more, we could potentially use those models to generate layers on top of them, AFTER modifying them to suit our purposes, and a lot more effective experimentation could take place.

    The biggest challenge I see facing us is model versioning.  In other words, I modeled my system originally with Oslo or some other approach, and now I want to update my model/schema, all the while preserving my data.  What needs to be updated?  This is a big deal due to the effort currently involved.  I need to upgrade my database with schema update scripts (hopefully generated by some Oslo tool), update my Entity Framework partial classes, update data bindings in XAML, and possibly update LINQ queries and data update statements.  How can we make this process safer and more productive, and give ourselves more confidence to refactor complex data-driven applications?  How can the incremental model changes made by a developer during a release cycle be preserved and later used for an in-place update of a database on a client's computer?  If we can solve this problem, I think we'll really open the door for the evolution of data-driven systems without the huge barrier and cost such changes normally incur.  How many systems become stagnant because it's just too difficult and expensive to make these low-level changes?  (And yes, I know this doesn't solve all model versioning problems, but it would be an important and large part of the total effort.)
    Sunday, February 1, 2009 6:07 PM
  • I think record version control is definitely a framework consideration.  I don't want to apply a pattern for versioning in every entity in my model.  However, I agree that some of the more advanced features such as shelving might have to be deferred to domain models.

    At the risk of overly flogging my blog, I discuss record version control here:

    http://kestral-katalist.blogspot.com/2009/01/record-version-control-part-i.html

    and

    http://kestral-katalist.blogspot.com/2009/01/record-version-control-part-ii.html


    I think upgrade framework is the responsibilty of the ORM.  It is conceivable to create a DSL for describing MSchema upgrades.  However, without a fetch and modify DSL, you can't do everything you may need.

    Once you have ORM support for alter, fetch and modify - then you get to consider the manual vs automatic upgrade processing problem.  This is where it gets really cool.  Another post you might be interested in:

    http://kestral-katalist.blogspot.com/2009/02/upgrade-procedures.html
    Friday, February 6, 2009 7:49 AM