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 Column) and Values (that belong to Rows). Each of these object can be 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.
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)? Let's say I would still like to use standard methods like addRow(column, name) that has no need to be inherited...
I don't like the idea to inherit factories and interface, but since SpecialTable has more method 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), I guess I should use a decorator. Is it possible (and how) to combine both factory and decorator design?
SpecialTable needs its own creation mechanism, so yes, it will need its own factory method (or factory class, if you are creating a group of items that must be related).
Alternatively: You could use Design pattern Strategy for your factory. In that case you would configure the factory with the desired creation mechanism at runtime.
As for the remaining question:
The three most common ways to add functionality to a class are:
You have already considered subclassing.
Design pattern Adaptor/Proxy is basically this: Create a new class that has the desired interface, and implements some (or all) of its methods by calling an instance of your existing class.
For Design pattern Visitor you in a sense combine Proxy with "Double Dispatch". Your added functions reside in an object that can call an instance of your existing class. See Visitor pattern - adding new ConcreteElement classes is hard? for an example.
Strategy:
It works like this:
public interface MyStrategyInterface {
public void doWork();
}
public class MyStrategyAccessPoint implements MyStrategyInterface {
private MyStrategyInterface current;
public MyStrategyAccessPoint(final MyStrategyInterface initial) {
current = initial;
}
public void doWork() {
current.doWork();
}
public void setStrategy(final MyStrategyInterface newCurrent) {
current = newCurrent;
}
}
As you can see, you can now change which actual implementation of MyStrategyInterface is used at runtime. This pattern is often combined with Singleton, making MyStrategyAccessPoint and its doWork method static.