Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Imagine your customer want's to have a possibility to add new property (e.g. color) to product in their eshop in their CMS.

Instead of having properties as fields:

class Car extends Product {
   protected String type;
   protected int seats;
}

You would probably end up doing something like:

class Product {
   protected String productName;
   protected Map<String, Property> properties;
}

class Property {
   protected String name;
   protected String value;
}

That is, creating own type system on top of existing one. It feels to me like this could be seen as creating domain specific langauge, or couldn't?

Is this approach a known design pattern? Would you solve the problem differently? I know there are languages where I can add a field in runtime, but what about database? Would you rather add/alter columns or used someting as shown above?

Thank you for your time :).

share|improve this question
3  
    
Not sure what language you are using, but if it is C# you could use a dynamic type which basically stores a KVP in a dictionary kinda like what you are doing on products and allows you to just tack on properties without having to directly add them to the collection as a collection. You will not have strong typing though. I know you asked for a design pattern but I don't feel you would need anything complex to use them. msdn.microsoft.com/en-us/magazine/gg598922.aspx –  Tony Apr 18 at 12:51
    
Tony: I'm using Java here, but consider it pseudo coude :). Would C# allow me to persist that dynamic object into database? I doubt it, as databse needs to know structure of data up front. –  Filip Apr 18 at 16:53
    
Why not just use map datatype? In DB it may be represented as {id} + {id, key, value}, if you not asking for performance. –  Shadows In Rain 23 hours ago
add comment

4 Answers

I like the question, my two cents:

Your two approaches are radically different:

  • The first one is OO ans strongly typed - but not extensible
  • The second one is weakly typed (string encapsulates anything)

In C++, many would use a std::map of boost::variant to achieve a mix of both.

Disgression: Note that some languages, such as C#, allows the dynamic creation of types. Which could be a nice solution for the general issue of adding members dynamically. However, "modifying/adding" types after compilation does corrupt the type system itself, and makes your "modified" types almost useless (e.g., how would you access such added properties, since you dont even know they exists ? The only reasonable way would be a systematic reflection over each object ... ending with a pure dynamic language _ you can refer to the 'dynamic' .NET keyword)

share|improve this answer
    
Creating types at runtime seams interesting but too exotic for me (I'm programming in Java). Such solution would not work, if I would want to store object in databse, which is always strongly typed I belive. The weakly typed solution I have proposed can be stored in database easily. –  Filip Apr 18 at 8:42
add comment

Creating a type at runtime sounds much more complicated then just creating an abstraction layer. It is very common to create an abstraction to decouple systems.

Let me show an example from my practice. Moscow exchange has the trading core called Plaza2 with trader's API. Traders write their programs to work with financial data. The problem is that this data is very huge, complex, and highly exposed to changes. It can change after a new financial product introduced or rools of clearing changed. Nature of future changes can not be predicted. Literally, it can change every day and poor programmers should edit the code and release a new version, and angry traders should revise their systems.

Obvious decision is to hide all financial hell behind an abstraction. They've used well known SQL tables abstraction. Biggest part of their core can work with any valid schema, the same as trader's software can dynamically parse the schema and find out whether it is compatible with their system.

Returning back to your example, it is normal to create an abstract language in front of some logic. It could be "property", "table", "message", or even human language, but pay attention to the drawbacks of this approach:

  • More code for parsing and validating (and more time off course). Everything what compiler did for you with static typing you must do in the run-time.
  • More documentation of messages, tables or other primitives. All the complexity goes from code to some sort of schema or standart. Here is an example of above-mentioned financial hell schema: http://ftp.moex.com/pub/FORTS/Plaza2/p2gate_en.pdf (dozens of pages of tables)
share|improve this answer
add comment

Is this approach a known design pattern?

In XML and HTML, these would be the attributes to a node/element. I've also heard them called extended properties, name/value pairs, and parameters.

Would you solve the problem differently?

That is how I would solve the problem, yes.

I know there are languages where I can add a field in runtime, but what about database?

A database would be like Java, in some senses. In pesudo-sql:

TABLE products
(
    product_name VARCHAR(50),
    product_id INTEGER AUTOINCREMENT
)

TABLE attributes
(
    product_id INTEGER,
    name VARCHAR(50),
    value VARCHAR(2000)
)

This would correspond to the Java

class Product {
   protected String productName;
   protected Map<String, String> properties;
}

Note that there is no need for a Property class, as the Map stores the name as the key.

Would you rather add/alter columns or used someting as shown above?

I've tried the add/alter column thing, and it was a nightmare. It can be done, but things kept getting out of sync and I never got it to work well. The table structure I outlined above has been much more successful. If you need to do searches and order by's, consider using an attributes table for each data type (date_attributes, currency_attributes, etc.) or adding some of the properties as good old database columns in the products table. Reports are often much easier to write on database columns then sub tables.

share|improve this answer
add comment

There is the State Desing Pattern a-la Gang-of-Four, which makes an object appear to change its type or class at run-time.

Other alternatives are Observer Design Pattern or a Proxy Design Pattern

share|improve this answer
1  
Simply providing links to a site and naming a pattern does not make for a good answer. Please consider expanding each section with an explanation (in your own words, from your understanding) of how these patterns will be used to solve the problem as described. –  MichaelT May 23 at 14:34
    
ok deal, does not make it a bad answer also, the OP asked for similar Design patterns, State is one of them and shortly explained in the answer (appears to change type at run-time), there is no use to copy-paste all of the web every-time, nevertheless i agree with you –  Nikos M. May 23 at 14:45
    
I would urge you to look at How to answer in the help center and consider the level of quality that is expected of answers on Programmers.SE from answers. Each SE site is different in what is expected and we try to set the bar rather high at P.SE. –  MichaelT May 23 at 14:48
    
agree with you again, i just say the answer followed the intent of the question, maybe you disagree with that, its ok –  Nikos M. May 23 at 14:49
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.