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.

I'm new to OOP and design pattern.

I've a simple app that handles the generation of Tables, Columns (that belong to Table), Rows (that belong to Table and have Columns) and Values (that belong to Rows). Each of these object can have a collection of Property, which is in turn defined as an enum.

They are all interfaces: I used factories to get concrete instances of these products, depending on circumnstances.

Now I'm facing the problem of extending these classes. Let's say I need another product called "SpecialTable" which in turn has some special properties or new methods like 'getSomethingSpecial' or an extended set of Property. The only way is to extend/specialize all my elements (ie. build a SpecialTableFactory, a SpecialTable interface and a SpecialTableImpl concrete)? What to do if, let's say, I plan to use standard methods like addRow(Column column, String name) that doesn't need to be specialized?

I don't like the idea to inherit factories and interfaces, but since SpecialTable has more methods than Table i guess it cannot share the same factory. Am I wrong?

Another question: if I need to define product properties at run time (a Table that is upgraded to SpecialTable at runtime), i guess i should use a decorator. Is it possible (and how) to combine both factory and decorator design? Is it better to use a State or Strategy pattern, instead?

share|improve this question
    
A factory can build disparate objets. You can have an static factory that builds tables, specialTables, Vehicles, Animals, etc. You don't need to write an specialTableFactory. –  user61852 Nov 25 '12 at 15:58
    
even if Table and SpecialTable doesn't share the same interface? –  Gabriele B Nov 25 '12 at 16:12
    
An static Factory can have a getVehicle() method that returns a Vehicle and a getAccount() that returns an Account. It doesn't matter that Vehicle and Account have different interfaces. –  user61852 Nov 25 '12 at 16:53
    
Rows (that belong to Column) ?? –  amphibient Nov 27 '12 at 15:59
    
pardon....rows that belong to table :) –  Gabriele B Nov 27 '12 at 17:21

1 Answer 1

up vote 0 down vote accepted

Yes, SpecialTable can be produced by the same factory (and by the same factory method) that produces Table. This not a problem, as long as SpecialTable provides at least the methods guaranteed by the Table interface (which it does).

This sort of situation makes sense when objects returned from the factory have some guaranteed behaviour/functionality (interface Table), and some optional stuff (interface SpecialTable).

So, in order to make use of the optional extra abilities/stuff available on some concrete objects returned by the factory, you have a few choices:

  • use polymorphism (recommended)

  • make use of instanceof (or similar), which can be used to check for interface compliance/exact typing (avoid this if possible!)

Using polymorphism

An example to illustrate: suppose SpecialTable has extra data and an extra widget 'blarg' which appears on the UI representing special tables. Do you really need the code which uses SpecialTable to know that it needs to add 'blarg' to the UI? Or can you just have your external code ask the thing of type Table to add its necessary UI components to some UI container? Then the calling code doesn't care what exact type the thing is -- SpecialTable deals with it, adding the 'blarg' to the container itself. This pattern can be described as the delegate pattern (also sometimes also known as strategy pattern).

Using instanceof (type checking)

Example of instanceof use:

// Table and SpecialTable are interfaces
Table table = TableFactory.instance().getDefaultTable();

if (table instanceof "SpecialTable") {
  SpecialTable specialTable = (SpecialTable)table;
  specialTable.specialMethod();
}

table.normalMethod();

Note that when you define your SpecialTable interface you can declare it as extending the Table interface and then only list the extra methods.

Your factory will be producing concrete objects of either type. So you might have a concrete class called BoringTable which implements Table, and a concrete class called ExcitingTable which implements SpecialTable.

Beware instanceof!

It's generally better to avoid things like 'instanceof' (or generally speaking, ifs of any kind which depend on what type an object is). You should favour polymorphism instead. By this I mean having multiple different classes, of a common type, enclosing different behaviour in their implementation code.

Ask yourself this: does the class using something of type Table (which might also be of type SpecialTable) need to care if it's a special table or not? Can you not hide that distinction in some sort of implementation of the SpecialTable -- have it do something different, something extra, that plain old Table does?

share|improve this answer
    
tnx for your explaination. I see only one drawback on this design: adding new Table subclasses, I need to chain perhaps tons of if...instanceof...callmethod. And removing a Table subclass (ok, should be) is even worst. In your opinion, could I use Visitor or Strategy pattern, instead? –  Gabriele B Nov 27 '12 at 17:36
    
You want as few occurrences of 'instanceof' (or generally speaking, ifs based on 'what class is it') as possible. Try to use polymorphism instead of if-switching. I'm not sure I understand exactly what you mean though. I'm adding to my answer now to add extra info which may be useful. –  occulus Nov 27 '12 at 18:54

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.