0

Disclaimer: I’m new to programming in Java and working with “extreme” OOP in general, so the answer to this might be really simple.


I’m creating a user interface in Vaadin, a Web application framework that supplies lots of useful components for me. Often, I’m not entirely happy with the default settings for these components.

For example, if I want every TextField component to fire value change events immediately when the field loses focus. There are similar settings for UploadField, TextArea, ComboBox etc. that I want to set on every instance of those classes.

Currently, what I have looks like this:

public class ConfiguredComponents {
    public static TextField createConfiguredTextField(String caption) {
        TextField field = new TextField(caption);
        field.setImmediate(true);
        field.setSomeOtherOptions();
        ...
        return field;
    }
    public static UploadField createConfiguredUploadField(...) {
        ...
    }
    // etc. 
}

This doesn’t feel like a class at all! It’s just a collection of static methods, which I’ve been told to avoid. Plus, I would like to place the logic for each component in a separate file. The configuration gets quite involved sometimes, and it just makes more sense that way: these are all very tiny self-contained bits of logic.

Here are the solutions I’ve considered:

  • Keep it simple: I could get rid of ConfiguredComponents, and just make one big package containing small factory classes. For example, myproject.ui.components.TextFieldFactory knows how to create a configured TextField and nothing more.

    Pros:

    • The ugly ConfiguredComponents class is gone.
    • All of the logic is in separate files.

    Cons:

    • There’s no single interface to the creation of my configured components; the only thing keeping them together is the fact that they’re in the same directory. Basically, I have to expose a lot of tiny classes, and there’s no single class or object managing them. (This intuitively feels like a pretty bad thing, but I don’t know if it really is.)
    • There’s also no way to override or extend static methods, so “faking” UI stuff for testing gets harder.
  • The Abstract Factory pattern: I make ConfiguredComponents into an AbstractComponentFactory that manages a lot of smaller factories.

    Pros:

    • All of the logic is in separate files.
    • The logic that actually configures my components is fully behind-the-scenes.

    Cons:

    • I would need an instance of AbstractComponentFactory every time I want to create a component anywhere in the code for my views. This means either keeping a singleton object, which has a lot of downsides, or creating a new AbstractComponentFactory() every time.

    • I have to write new code in two or three places, instead of just one, if I wish to add new components to my little “library”.

  • Some other design pattern I don't know about: I’ve read a bit about Builder, and Facade, which feel like they might apply here, but I don’t understand them very well.

How would you approach this design decision?

Community
  • 1
  • 1
Lynn
  • 8,876
  • 38
  • 66

2 Answers2

1

If your components can be inherited, then go ahead; for each component that you want to alter default settings, create a new derived class and config settings in constructors. Otherwise,

Abstract factory pattern is a good choice. I think you are misunderstanding about this pattern. AbstractComponentFactory is just an interface, it does not manage anything. This interface looks like this:

interface AbstractComponentFactory {
    public TextField createTextFiled(...);
    public UploadField createUploadFiled(...);
    ...
}

In your situation, I think you need only one implementation for this factory:

class MaurisComponentFactory implements AbstractComponentFactory {
    public TextField createTextFiled(...) {
        new ... config ... return;
    }
    public UploadField createUploadFiled(...) {
        new ... config ... return;
    }
    ...
}

As you said, we should neither use Singleton nor create new MaurisComponentFactory everytime. Instead, we should create only one instance in the main() method, and then try to inject this instance to every place that need to create components.

Nghia Bui
  • 3,454
  • 11
  • 21
  • I could use something like Spring to perform the injection, right? – Lynn Jul 09 '15 at 11:23
  • 1
    Sorry, I don't have experience in Spring Framework. But I think you could do the dependency injection by yourself. The framework might make this in a convenient way by the cost is you have to depend on the framework. But the essence is the same. – Nghia Bui Jul 09 '15 at 11:27
  • OK. You also suggested using inheritance; are there any advantages to having a class *extend* from `TextField` as opposed to having a small factory class create `TextField`s that it configures? – Lynn Jul 09 '15 at 11:29
  • 1
    Well, the advantage is that it's more natural and simpler as only one object is created. With the smaller factory, you have to create 2 objects: factory and component. – Nghia Bui Jul 09 '15 at 11:35
0

One possible approach i can think think is to use AbrstractFactory with Service Locator or Registry patterns

Since you have myriad objects that does not have complicated instantiation process (if so resort to build pattern), you create objects with Abstract Factory and register them in registry. And resolve them as needed where ever you are.

or you may resort simple IOC container where your entire application is wrapped around

kuhajeyan
  • 9,602
  • 8
  • 40
  • 66