1
\$\begingroup\$

I want to extract the creation of different objects in a factory class for the reason of reusability. The problem is that within the current code the objects are configured also for the specific problem. Now I want to reuse only the creation of the objects within another code place.

 if (FieldConfiguration.FIELD_TYPE.TEXTFIELD == type)
            {
                TextField textField = new TextField(caption);
                textField.setNullRepresentation("");
                bind(textField, propertyId);
                field = textField;
                if (field.getValue() == null && isNestedProperty)
                {
                    ObjectProperty property = new ObjectProperty("", String.class);
                    textField.setPropertyDataSource(property);
                }
            }
            else if (FieldConfiguration.FIELD_TYPE.SEARCHFIELD == type)
            {
                SearchBox searchField = new SearchBox(caption);
                bind(searchField, propertyId);
                field = searchField;
            }
            else if (FieldConfiguration.FIELD_TYPE.DATEFIELD == type)
            {
                DateField dateField = new DateField();
                dateField.setCaption(caption);
                dateField.setDateFormat(UilibI18N.dateFormat.getText());
                dateField.setResolution(Resolution.DAY);
                bind(dateField, propertyId);

I want to reuse only the creation of the objects at another code place too, can anybody give me a hint what's the right way to extract the creation logic?

\$\endgroup\$
  • 1
    \$\begingroup\$ Your code excerpt is incomplete. To get better answers, and for your own benefit it would be nice to include your whole method. \$\endgroup\$ – Bruno Costa Jun 9 '16 at 7:08
  • \$\begingroup\$ Thanks for your answer Bruno. The other logic in the method is the same, depending on a FieldType, a object is created an initalized. Now I need just the creation logic of an object also at another code place (depending also on a FieldType) ... my questions is now: what is the nicest way to do this? :-) \$\endgroup\$ – user108527 Jun 9 '16 at 7:16
1
\$\begingroup\$

I find the right word in you question - 'extract'.

Code style

Logic section

Use blank lines to separate your code into logical sections

Instead of:

DateField dateField = new DateField();
dateField.setCaption(caption);
dateField.setDateFormat(UilibI18N.dateFormat.getText());
dateField.setResolution(Resolution.DAY);
bind(dateField, propertyId);

You can use:

// creation logic part
DateField dateField = new DateField();

// setting the field's properties logic part
dateField.setCaption(caption);
dateField.setDateFormat(UilibI18N.dateFormat.getText());
dateField.setResolution(Resolution.DAY);

// bind operation logic part
bind(dateField, propertyId);

Design issue

I read your code very carefully and I've found that you use 2 variables in all your 3 if/else conditions.

They are caption and propertyID.

Assume that these 2 properties will be an input of some method which we'll call (I don't know the context, that's why I'll use the random name) makeOperationWithField

public void makeOperationWithField(int propertyID, String caption) {
 // some code
}

I'll move deeply and remove this big if/else if statements.

Replace conditional with polymorphism.

Lets do it step by step.

Step1

Create an abstract class that will create objects depending on field's type.

abstract class FieldConfigurationType {
  static final int TEXTFIELD = FieldConfiguration.FIELD_TYPE.TEXTFIELD;
  static final int SEARCHFIELD = FieldConfiguration.FIELD_TYPE.SEARCHFIELD;
  static final int DATEFIELD = FieldConfiguration.FIELD_TYPE.DATEFIELD;

  abstract void makeOperationWithField(int propertyID, String caption);

  public static FieldConfigurationType newType(int code) {
    switch (code) {
      case TEXTFIELD:
        return new TextFieldConfiguration();
      case SEARCHFIELD:
        return new SearchFieldConfiguration();
      case DATEFIELD:
        return new DateFieldConfiguration();
      default:
        throw new IllegalArgumentException("Incorrect Field Type");
    }
  }
}

Now, we can use the simple construction:

FieldConfigurationType fieldType = FieldConfigurationType.newType(type);
fieldType.makeOperationWithField(propertyID, caption);

Step 2

Add separate implementation for each field type.

public class TextFieldConfiguration extends FieldConfigurationType {
  @Override public void makeOperationWithField(int propertyID, String caption) {
    TextField textField = new TextField(caption);
    textField.setNullRepresentation("");

    bind(textField, propertyId);

    field = textField;

    if (field.getValue() == null && isNestedProperty) {
      ObjectProperty property = new ObjectProperty("", String.class);
        textField.setPropertyDataSource(property);
    }
  }
}

public class SearchFieldConfiguration extends FieldConfigurationType {
  @Override public void makeOperationWithField(int propertyID, String caption) {
    SearchBox searchField = new SearchBox(caption);
    bind(searchField, propertyId);

    field = searchField;
  }
}

public class DateFieldConfiguration extends FieldConfigurationType {
  @Override public void makeOperationWithField(int propertyID, String caption) {
    DateField dateField = new DateField();

    dateField.setCaption(caption);
    dateField.setDateFormat(UilibI18N.dateFormat.getText());
    dateField.setResolution(Resolution.DAY);

    bind(dateField, propertyId);
  }
}

If you need to add a new field type, all you need to do is just add new subclass without rewriting the existing code. Open/Closed Principle

\$\endgroup\$
0
\$\begingroup\$

You can easily separate creation from configuration.

    void buildObject() {
    GenericField field;
    switch (type) {
    case FieldConfiguration.FIELD_TYPE.TEXTFIELD:
        TextField textField = new TextField(caption);
        field = textField;
        break;
    case FieldConfiguration.FIELD_TYPE.SEARCHFIELD:
        SearchBox searchField = new SearchBox(caption);
        field = searchField;
        break;
    case FieldConfiguration.FIELD_TYPE.DATEFIELD:
        DateField dateField = new DateField();
        field = dateField;
        break;

    }
    switch (type) {
        case FieldConfiguration.FIELD_TYPE.TEXTFIELD:
            TextField textField = (TextField) field;
            textField.setNullRepresentation("");
            if (field.getValue() == null && isNestedProperty) {
                ObjectProperty property = new ObjectProperty("", String.class);
                textField.setPropertyDataSource(property);
            }
            break;
        case FieldConfiguration.FIELD_TYPE.SEARCHFIELD:
            break;
        case FieldConfiguration.FIELD_TYPE.DATEFIELD:
            DateField dateField = (TextField) field;
            dateField.setCaption(caption);
            dateField.setDateFormat(UilibI18N.dateFormat.getText());
            dateField.setResolution(Resolution.DAY);
            break;

    }
    bind(dateField, propertyId);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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