• billy (unregistered)

    F1RST!

  • ParkinT (cs)

    It looks to me like a cleverly hatched plan by a developer to;

    convince the client modifications could be accomplished without a developer's involvement, while, in fact requiring the very developer with the most intimate knowledge of the system!

     

    Wait, that sounds like something the Sales Rep would devise!!

  • JBL (cs)

    Seventeenth.

    What happens when Mario tries to implement an Inner Platform on his Inner Platform? And this sounds a bit like recent comments that people have ended up re-implementing M$ Access.

    Maybe Mario's not the best programmer in his Field, or maybe he's just not our (Data)Type of programmer...

  • Zoink (unregistered) in reply to JBL

    Is there a inner query language to query the tables table and the fields fields?

    pubic abstract first interface PaulaBean extrudes WTFBean {
      personal static noid getBrillant() {
        return "FIST!";
      }
    }

  • Mr Beeper (unregistered)

    This problem was solved by Lisp 40 years ago (tm)

  • JBL (cs) in reply to Mr Beeper
    Anonymous:
    This problem was solved by Lisp 40 years ago (tm)


    Yop, 3 lines to implement a LISP(tm) interpreter in LISP(tm). Try that, (insert other language here)!
  • lizardfoot (cs) in reply to Mr Beeper
    Anonymous:
    This problem was solved by Lisp 40 years ago (tm)


    I wonder if Lithp could the tholve all the problemth with the Enterprithe Ruleth Engine.
  • jo42 (cs)

    Wot? No XML??

  • loneprogrammer (cs) in reply to Mr Beeper
    Anonymous:
    This problem was solved by Lisp 40 years ago (tm)

    How, by forcing everybody to learn Lisp in order to use EMACS?

  • Jeff S (cs)
    Alex Papadimoulis:
    As you may have gathered, the DSM organized data using a structure it called a "Table". These tables had one or more Fields, with each Field having a specific "DataType". A single datum was then stored as a FieldValue. All of these were stored inside of a relational database.

    I think it's quite ingenious.  I would pay a lot of money for a system like this that lets me model my data using these concepts of "Tables" and "Fields" and "DataTypes" and all that; all we have at my shop is SQL Server.
  • ammoQ (cs)

    Even the Orable guys aggree with Alex on this one...

    Do not use Generic Data Models

    I see this antipattern all too often, and the worst thing is, uneducated bosses ask for it, dreaming of a system "so flexible that we never have to change the program, just the parameters"

  • JBL (cs) in reply to ammoQ
    ammoQ:
    ... and the worst thing is, uneducated bosses ask for it, dreaming of a system "so flexible that we never have to change the program, just the parameters"


    Concur. Point often missed: Code == Data much like any other data, and one layer keeps it simple (hence maintainable, ...).

  • Digitalbath (cs) in reply to Jeff S

    Jeff S:
    Alex Papadimoulis:
    As you may have gathered, the DSM organized data using a structure it called a "Table". These tables had one or more Fields, with each Field having a specific "DataType". A single datum was then stored as a FieldValue. All of these were stored inside of a relational database.

    I think it's quite ingenious.  I would pay a lot of money for a system like this that lets me model my data using these concepts of "Tables" and "Fields" and "DataTypes" and all that; all we have at my shop is SQL Server.

    I build all my "databases" in Notepad.  It's much cheaper.

  • skicow (cs)
    Alex Papadimoulis:

    cmd.CommandText = "SELECT * FROM tblTable WHERE Name = '" + tableName + "'";
    

    ...

    cmd.CommandText = "UPDATE tblFields SET DataType = '" + newDataType + "' " + " WHERE fieldId = " + fieldId.ToString();

    ...

    cmd.CommandText = "SELECT fieldValueId, dataValue FROM tblFieldValues " + " WHERE fieldId = " + fieldId.ToString() + " ORDER BY defaultOrder";

    SQL Injection what?!? Parameters Who!?!

  • You Fail (unregistered) in reply to JBL
    people have ended up re-implementing M$ Access.

    You fail for typing "M$".

  • e.thermal (cs) in reply to ammoQ

    ammoQ:
    Even the Orable guys aggree with Alex on this one...

    Do not use Generic Data Models
    I see this antipattern all too often, and the worst thing is, uneducated bosses ask for it, dreaming of a system "so flexible that we never have to change the program, just the parameters"

    Interesting I agree that this pattern is anti, but I think the example the user gave in your Orable link is a valid construct given the circumstances, (think about a company that sells everything from electronics to waflles) how would you allow multiple product lines with varying attributes?  In the article/question, the user asks if there is a query that would return the results he is looking for in one query and the answer is yes, however he goes on to tell him how bad a design it is and doesn't state how one would accomplish the same thing in the real world. I personally think what the user is looking for can accomplished with what he currently has.

     

  • Bus Raker (cs)

    Well they would have been all set if they created an application to manage the appilcation to manage the RMS.

    tbltblTable would hold the tables like tblTable, tblFields...then the users could manage the application that manages the users and they would save much $$.

    The real WTF is that tblTable is singular and tblFields is plural

     

     

  • Digitalbath (cs) in reply to JBL

    JBL:
    Seventeenth.

    What happens when Mario tries to implement an Inner Platform on his Inner Platform? And this sounds a bit like recent comments that people have ended up re-implementing M$ Access.

    Maybe Mario's not the best programmer in his Field, or maybe he's just not our (Data)Type of programmer...

    The real WTF is that they didn't just use Access in the first place.

  • Bus Raker (cs) in reply to e.thermal
    e.thermal:

     

    Interesting I agree that this pattern is anti, but I think the example the user gave in your Orable link is a valid construct given the circumstances, (think about a company that sells everything from electronics to waflles) how would you allow multiple product lines with varying attributes? 

    One way:  tblProduct holds the generic product table, with a typeID pointing to specific tables such as 'tblwaffle' and 'tblElectronics' depending on the values stored in dimension table 'tblProductType' with field 'DataTableName'.  Users can add new product types through a maintenance screen, which under the hood can manage these tables with the logic required, never exposing the essential tables such as tblProduct etc.  

  • Wesley Shephard (unregistered)

    I see a lot of these overly generic systems. Often they are guided by good intentions such as the desire to make a user (non-programmer) modifiable system but then fail to deliver two critical components:

    1. A user interface that actually encapsulates what the user will generally need in a simple to use form.
    2. The underlying infrastructure to hide implementation details while still giving enough power to succeed at a task.
    As pointed out by others: if the system is too generic the end result is a poor Access clone. On the other hand, if you define your modifiable sections clearly, you can actually succeed with such a system.

    If you look at Excel, it is really a domain specific programming environment for financial computations. It uses a model that is understandable even to those without programming experience. The reason it works is that it figures out order of operations on its own and the variables are all visible to the user of the system as cells.

    I have in the past built systems which are intended to be modified by end users. I usually fall back on Excel as the model for the UI. This does two things: one, it reuses knowledge that most business people already have. Second, it forces the underlying system to provide simple, easy to use functionality, because if you don’t, the spreadsheet model will fail to deliver the requirements. This ends up being a good thing, because it isn’t so generic that some poor user can accidentally implement functionality that should be in the system proper.

  • Rank Amateur (cs)
    Alex Papadimoulis:

    Ironically, Mario was brought into the system because the client wanted to add a new Field to a form.

    Well, that's the whole problem. If they didn't use forms, programming wouldn't have to change anything to add a field. A more flexible approach is to give the enduser a UI where they can modify their interaction on the fly. Using human language as a model (now that's flexibility), all you need is to define a some key words and simple syntax rules.

    I call this new approach Command-Oriented Database Environment.

    --Rank

  • Nick (unregistered) in reply to ammoQ

    The company for which I previously worked based their entire business on a system that they believed was 'code free' and 'modifiable by the clients' for 'immediate onsite customization'.  The crazed CEO boasted that this concept of 'application configuration' was revolutionary and that his product would some day rival those released by the likes M$.  The base product attempted to utilize a database modeler in which the user would construct relational DB schemas via a primative GUI, and then design interfaces to the DB model using a screen integrator (much like VB).  The modeler was also supposedly able to generate the corresponding SQL statements. 

    Long story short, I knew it was time to quit when they actually had to take an entire computer onsite with them and hand it to the client because they were unable to make a stable build anywhere else except this one machine. 

  • mjonhanson (cs) in reply to JBL
    JBL:
    Anonymous:
    This problem was solved by Lisp 40 years ago (tm)


    Yop, 3 lines to implement a LISP(tm) interpreter in LISP(tm). Try that, (insert other language here)!


    Just try to implement the enterpriseyness of this WTF in LISP(tm).  Imagine all the car() and cdr() statements to access a table inside a table inside a WTF.
  • TomCo (cs)

    <FONT size=2><FONT face="Courier New"><FONT style="BACKGROUND-COLOR: #ff0000" color=#7fffd4>final int BeginEnterpriseObjectRepositoryAndMethods(String tblTable, String fldFields) enterpriseMultiInherits Balding, BadTemper, ZeroBalanceBankAccount {
      EnterpriseObjectRepository enterpriseobjectrepository = new EnterpriseObjectRepository(startEnterpriseObjectRepository(tblTable,fldFields));
      EnterpriseObjectMethods enterpriseobjectmethods = new enterpriseobjectrepository.getEnterpriseObjectMethods();
       return enterpriseobjectmethods.KillAllOfMankindByUsingWTFPatternAndReturnFileNotFound();
    }</FONT></FONT></FONT>

    [6]

  • VGR (cs)

    As I mentioned just a few days ago, this anti-pattern already has a name:  Second System Sydrome.

    That's where after you've done a simple, direct version of something, you come up with dreams of creating a Grand Unification of Everything, a program that does everything by being totally generic at every level.

    An example of this at a smaller scale is a vararg function or method that takes generic "instructions" for its parameters:

    void *doeverything(String command1, void *parameters1, String command2, void *parameters2, ...);

    It's a very easy trap to fall into.  If you aren't aware of the phenomenon, it's hard to realize you're in the trap at all, even though you are surrounded by clues, such as the fact that it seems to make development harder instead of easier.

    Exposing it to the user is even worse;  few users care about infinitely configurable software.  (Ever see anyone actually bother to configure their menu bar in Word?)

  • masklinn (cs) in reply to Bus Raker
    Bus Raker:

    Well they would have been all set if they created an application to manage the appilcation to manage the RMS.

    WTF? Stallman is innocent from this one, don't drag the poor guy into this !

  • Bus Raker (cs) in reply to VGR

    VGR:
    As I mentioned just a few days ago, this anti-pattern already has a name:  Second System Sydrome.

    That's where after you've done a simple, direct version of something, you come up with dreams of creating a Grand Unification of Everything, a program that does everything by being totally generic at every level.

    Well Plato said Art is an imitation of an imitation, thus is three times removed from the truth.  Same goes for these enterpri$e systems ... a database is created to reflect the real world.  The system tries to reflect the database.  That means it is art!

    So the answer is to frame the code and put it is some museum somwhere because that's all it is good for.

  • Free (cs) in reply to e.thermal
    e.thermal:

    Interesting I agree that this pattern is anti, but I think the example the user gave in your Orable link is a valid construct given the circumstances, (think about a company that sells everything from electronics to waflles) how would you allow multiple product lines with varying attributes?  In the article/question, the user asks if there is a query that would return the results he is looking for in one query and the answer is yes, however he goes on to tell him how bad a design it is and doesn't state how one would accomplish the same thing in the real world. I personally think what the user is looking for can accomplished with what he currently has.

    The problem with the example is that it is too generic, if you are building a catalog of products, you should have all the fundamental properties of products. All the things they want to query are fundamental. Its ok to have a table of extended attributes to hold things that are only for specific products and properties but not to put everything there.

     

     

  • Howard M. Lewis Ship (unregistered)

    I've been in design meetings where someone, usually with very minimal database experience, has suggested this kind of thing.  I mean, I designed something like this when I was 21 and discarded it then as impractical (CRUD was easy but query would be intensely difficult).

    In fact, I had been following up on another problem with Oracle when I found an Oracle technical note that described this kind of pattern and stated flatly: "projects based on this design WILL FAIL".  I then quoted this to Mr. Designhead (as gently as I could, though there was no love lost between us).  That design got tabled, and we followed up with something that would generate DDL to modify tables, adding columns as necessary (a tricky design because DDL is not transactional in any database I can name, and it can cause some grief when upgrading software when database schemas change).

    Joel Splosky talks about this, programmers are often like cavemen because we tend to count "zero, one, many".  Sometimes two or three is just the right number!  This design is just someone chanting "many! many!" and refusing to commit to a practical, concrete, maintanable design.

  • Benjamin Smith (unregistered) in reply to JBL
    JBL:
    Anonymous:
    This problem was solved by Lisp 40 years ago (tm)


    Yop, 3 lines to implement a LISP(tm) interpreter in LISP(tm). Try that, (insert other language here)!


    Well, let's be fair: those are three very very long lines of LISP code...
  • v (unregistered) in reply to Howard M. Lewis Ship

    Anonymous:
    That design got tabled, and we followed up with something that would generate DDL to modify tables, adding columns as necessary (a tricky design because DDL is not transactional in any database I can name, and it can cause some grief when upgrading software when database schemas change).

    I don't know which RDBMSes you have worked with but in MS SQL Server DDL is transactional. I assume it will also be transactional in Sybase and DB2 and probably a few others.

    The funny things ofcourse with the Inner-Platform Effect antipattern, is that the designers don't realise that the table definitions in MS SQL Server (and Sybase and DB2 and probably a few others) are already stored in tables. In system tables. Once you realise that your design duplicates the functionality of a piece of software that has costs you a few $ 10,000s, you might realise that your design might not be as good as you think

  • Dustman (unregistered) in reply to ammoQ
    ammoQ:
    Even the Orable guys aggree with Alex on this one...

    Do not use Generic Data Models

    I see this antipattern all too often, and the worst thing is, uneducated bosses ask for it, dreaming of a system "so flexible that we never have to change the program, just the parameters"



    We use something somewhat similar at our shop, although the pattern is only used for our client's products, not the entire database in general. It works fairly well, because of a number of things:

    1) We make no pretense that this pattern is the best way to store all the product's data. Some things, like price or category, are universal and kept directly in the product table. When we find an attribute that a client actually wants to query against, we have a script that tears an attribute out of the values table and makes a column out of it in the product table.

    2) Our product makes no claims of being inventory control software, so we generally don't end up trying to query against these attributes. The client tells the database what values the products could have, not the other way around.

    3) When a sale is recorded, we don't store the attribute data in the same way. Each item sold has a column that contains nothing but the keys to the values of these attributes. This enables fairly straightforward queries (WHERE Id='shirt' and Values Like 'red' would find all the redshirts) and they execute with reasonable speed.

    4) Our attributes values are unique, and have a direct relationship to unique attributes. Thus each client only has access to one list of colours, defined by himself, and if he finds a key in a the sales table that corresponds to the value 'Red', it implies 'Colour'. Thus, we never run into situations where we have to query against the attributes table.

    Basically, by limiting the scope of the anti-pattern, we've made it useful to us.

  • Lee (unregistered) in reply to JBL

    return eval(prompt("code"))

  • Reality (unregistered) in reply to Lee

    return "dick";

  • ithika (cs) in reply to Bus Raker
    Bus Raker:
    So the answer is to frame the code and put it is some museum somwhere because that's all it is good for.


    Well, it's currently taking pride of place in an Online Gallery of Shame, is that close enough? :-)
  • BiggBru (cs)
    Alex Papadimoulis:

    This Inner-Platform Effect has been seen here before (most recently in the Enterprise Rules Engine), but it wasn't until I read Mario's submission that I thought it was time to name and identify the antipattern.

     

    <FONT face=Georgia>And I thought that Mario was a plumber, not a programmer. Silly me...</FONT>

    >BiggBru

  • Ianb (unregistered) in reply to Howard M. Lewis Ship
    Anonymous:
    a tricky design because DDL is not transactional in any database I can name


    Take a look at PostgreSQL.
  • Dave (unregistered) in reply to Howard M. Lewis Ship

    I'm currently working on a web application that is intended to function as an electronic form processor to capture proof-of-claim data.  Form metadata is used to define form content, and workflow.  So all of the captured form data is stored as key value pairs in a generic "data" table.  This allows us to easily add or remove questions from a form without having to add a new column to a data table.  It also allows us to store all of the data in single table, rather than requiring a new table for each form, which is problematic because admin users can add a new form at any time.  However captured data is the only portion of the data model that is generic.  The relationships between forms and questions, questionTypes, etc. are all concrete and well-defined.

    So I think it's wrong to say that generic data models aren't useful.  They are useful.  However you have to know when they are appropriate.

  • CornedBee (cs)

    I've just finished implementing something not dissimilar for a content management system. Basically, what I wrote is a somewhat simplified system to define SQL tables and keep the definitions of these tables in yet more tables. The purpose of the whole thing is to create catalogs of data, which can then be displayed as predefined or dynamic queries on the data set.

    The difference to the presented system probably is that in my case, it has already been proven that non-programmers can maintain it.

  • onovotny (unregistered) in reply to Ianb

    Anonymous:
    Anonymous:
    a tricky design because DDL is not transactional in any database I can name


    Take a look at PostgreSQL.

    Take a look at SQL 2005 -- it has DDL triggers that let you rollback if they violate your checks...

  • Cheong00 (unregistered) in reply to ammoQ
    ammoQ:
    Even the Orable guys aggree with Alex on this one...

    Do not use Generic Data Models

    I see this antipattern all too often, and the worst thing is, uneducated bosses ask for it, dreaming of a system "so flexible that we never have to change the program, just the parameters"


    Agreed.

    An my first question to ask is: wouldn't it be better if the program is written in any of the scripting languages at the beginning.

    The second thought is: perheps we can write a WinForm will each button bind to a vbscript file that can be assigned by registry values/ini file/.config file you name it.


  • td_ (cs) in reply to jo42
    jo42:
    Wot? No XML??


    ``If you want to trick a pointy-haired boss into letting you write software in Lisp, you could try telling him it's XML.''
  • thatguy (unregistered) in reply to VGR

    VGR:
    As I mentioned just a few days ago, this anti-pattern already has a name:  Second System Sydrome.

    That's where after you've done a simple, direct version of something, you come up with dreams of creating a Grand Unification of Everything, a program that does everything by being totally generic at every level.

    These are totally separate. The INNER PLATFORM refers to specifically developing a platform on top of a platform using that platform. It could be the first system some idiot develops or the tenth or the second.

  • ammoQ (cs) in reply to Dustman
    Dustman:
    ammoQ:
    Even the Orable guys aggree with Alex on this one...

    Do not use Generic Data Models

    I see this antipattern all too often, and the worst thing is, uneducated bosses ask for it, dreaming of a system "so flexible that we never have to change the program, just the parameters"



    We use something somewhat similar at our shop, although the pattern is only used for our client's products, not the entire database in general. It works fairly well, because of a number of things:
    ...


    To be honest, in a very limited range I've used that pattern too, without problems. Some years ago, I made a database system for a mobile telecommunications company that kept info about available cellphone models. Each cellphone has a lot of "features", e.g. "Java enabled", "Color Display", "Real Tones", "MP3 player", ... Since the makers of the phones add new features often, I did not make a column for every feature, but a "feature" table with a many-to-many relationship to the phone table.

  • tufty (cs) in reply to ammoQ
    ammoQ:
    To be honest, in a very limited range I've used that pattern too, without problems. Some years ago, I made a database system for a mobile telecommunications company that kept info about available cellphone models. Each cellphone has a lot of "features", e.g. "Java enabled", "Color Display", "Real Tones", "MP3 player", ... Since the makers of the phones add new features often, I did not make a column for every feature, but a "feature" table with a many-to-many relationship to the phone table.


    Yeah, but that's not a generic data model, is it?  It's a correctly (at least as far as you have described it) normalised data model.  Well done.  Carry on.

    Simon
  • felix (cs) in reply to Free
    Free:

    The problem with the example is that it is too generic, if you are building a catalog of products, you should have all the fundamental properties of products. All the things they want to query are fundamental. Its ok to have a table of extended attributes to hold things that are only for specific products and properties but not to put everything there.

     


    What if the customer wants the extended attributes to be searchable? That's exactly what I had to implement a few months ago. And those extended attributes were not just plain text fields. Some of them were number ranges, other were lists of options, both mutually exclusive and not, and so on. Only some of them had to appear on the search form. And all of this had to be customizable on the fly, 'cause they could never make up their minds (of course).

    I made it, but I wouldn't show the source code to anyone...

  • Sascha Kulawik (unregistered) in reply to Bus Raker

    First of all - the real WTF here is - you can't use Firefox to write messages in thedailywtf.com.

    However - I would propose to use a discriminator and a good O/R layer like Hibernate to solve that issue. So you are using one table "Products" (naming tables with hungarian prefixes is a WTF as well) and each a table "Electronics" and so on.
    It's a bad design practice to use different tables and joining them with UNION statements.

  • RevEng (cs) in reply to felix
    felix:

    What if the customer wants... [snip]

    I made it, but I wouldn't show the source code to anyone...


    I think you've just described the problem we see in every one of these applications.

    As an engineer (electrical, not SE, but with a lot of programming background) it's our job to take what the customer wants and either find a way to do it, OR explain to them why it's infeasible (perhaps suggesting a close approximation).  I know when it comes down to the money, you always end up having to bite the bullet and make the POS anyway, but that really is the problem.

    If a customer wants a CMS that's completely generic and customizable, give them SQL (or your DB of choice).  If they want a program that can perform anything they ask of it, give them a compiler.  You can't just slap a pretty GUI on something and expect it to be easier and just as powerful and you can't expect to write a large application without knowing anything about programming.

    With knowledge comes power, and with power comes responsibility.  That's why we learn all these damn languages in the first place.  I take it as an insult (and complete lack of understanding) for any customer to ask for a program to replace the job of the programmer.

    That's what Inner-Platform Effect is really about: trying to write a whole new programmable system that the user can understand.  Far be it for any of us to even consider that we could rewrite the whole system in a simpler but equally powerful way.  We've had an entire industry doing that for decades and we have Windows and Java to show for it.+o(

    </rant>

  • ammoQ (cs) in reply to tufty
    tufty:
    ammoQ:
    To be honest, in a very limited range I've used that pattern too, without problems. Some years ago, I made a database system for a mobile telecommunications company that kept info about available cellphone models. Each cellphone has a lot of "features", e.g. "Java enabled", "Color Display", "Real Tones", "MP3 player", ... Since the makers of the phones add new features often, I did not make a column for every feature, but a "feature" table with a many-to-many relationship to the phone table.


    Yeah, but that's not a generic data model, is it?  It's a correctly (at least as far as you have described it) normalised data model.  Well done.  Carry on.

    Simon


    Or so it seems, until you try to query all cellphones with several features, like: "color display" and ("WAP" or "HTML") and  "Java" and ("polyphone ringtones" or "real tones") and "dualband" and "organizer functions"; it's not an uncommon or unreasonable request, but the query is large, ugly and probably slow. Granted, there were only a few hundred phones in the database, so performance was not a problem.
  • ammoQ (cs) in reply to Sascha Kulawik
    Anonymous:

    First of all - the real WTF here is - you can't use Firefox to write messages in thedailywtf.com.



    Bullshit. I'm using Firefox all the time, look at my posting count ;-)

Leave a comment on “The Inner-Platform Effect”

Log In or post as a guest

Replying to comment #:

« Return to Article