bNd
bNd

Reputation: 7640

Best way to pass arguments in constructor

I have a class that create rows in table layout. The row creation depend upon data and metadata. As metadata is same for each row like show/hide visibility properties etc. so I have created metadata property as a static and initialize once using initWidget of RowWidget.

just example:

class RowWidget extends FlexTable{

  public static void initWidget(Form form,
    HashMap<Long, ContractorPermissionEnum> formModePermissionMap,
    GridMode gridMode,
    boolean isApplied,
    boolean isChildExist,
    boolean isChildAttachment)
    { 
      // ...
    }
}

Then I called below constructor for each record data.

public RowWidget(DataRawType dataRawType, Data data, Data parentData) {
 // ...
}

As I thought this is not right approach. because as pattern when anyone see this class then understand it will create one row. I don't want to call initially initWidget. I want to pass each required parameter in constructor only like

public RowWidget(DataRawType dataRawType,
  Data data,
  Data parentData,
  Form form,
  HashMap<Long, ContractorPermissionEnum> formModePermissionMap,
  GridMode gridMode,
  boolean isApplied,
  boolean isChildExist,
  boolean isChildAttachment) {
  // ...
}

But due to this, constructor have no of arguments. and I think it's also bad pattern to have 5+ parameter in constructor.

Is Anyone suggest me:

Note:I know this is possible through static only but don't want to use static.

Note: I don't want to create another class to achieve it. or any getter/setter method.

Thanks In advance.

Upvotes: 8

Views: 2033

Answers (6)

Jarosław Jaryszew
Jarosław Jaryszew

Reputation: 1502

I would suggest builder pattern. You would need one extra class to create RowWidget objects. So the call would look like that:

RowWidget widget = new RowWidget.Builder().withData(data).withParentData(parentData).withDataRawType(dataRawType).build();

Here is neat explanation of the pattern:https://stackoverflow.com/a/1953567/991164

Upvotes: 1

Alpedar
Alpedar

Reputation: 1344

If you did not want to create another class, I'd suggest what A4L suggested. Without creating another class, I would create constructor that takes all parameters and factory method that uses current instance as template and pass its own parameters to constructor parameter.

example (with obvious parts ommited)

class A{
  public A(int p1, int p2){...}
  public A create(int p2) {
    return new A(this.p1,p2);
}

Upvotes: 0

Adrian Shum
Adrian Shum

Reputation: 40056

The static initWidget() thing just doesn't seem right for me. Though probably now you will only have one set of RowWidgets which share some properties, it is also reasonable to have 2 sets of RowWidgets, each set will have its own "shared" properties. Things will be much more fluent and you have much more choices in building more reasonable APIs if you refactor your code to make a more reasonable design

Assume now I introduce something like a RowGroup (which kind of represents the "shared" thing you mentioned)

(Honestly I don't quite get the meaning for your design, I am just making it up base on your code);

public class RowGroup {
    public RowGroup(Form form,
                    HashMap<Long, ContractorPermissionEnum> formModePermissionMap,
                    GridMode gridMode,
                    boolean isApplied,
                    boolean isChildExist,
                    boolean isChildAttachment) { .... }

    public void addRow(DataRawType dataRawType, Data data, Data parentData) {...}
}

When people use, it looks something like:

RowGroup rowGroup = new RowGroup(form, permissionMap, gridMode, isApplied, isChildExist, isChildAttach);
rowGroup.addRow(DataRawType.A, dataA, parentA);
rowGroup.addRow(DataRawType.B, dataB, parentB);

You may even provide builder-like syntax or a lot other choices.

RowGroup rowGroup 
        = new RowGroup(.....)
              .addRow(DataRawType.A, dataA, parentA)
              .addRow(DataRawType.B, dataB, parentB);

Even more important, the design now make more sense to me.

Upvotes: 0

me_digvijay
me_digvijay

Reputation: 5502

How to construct class which have same property required in another instance?

To achive this you can have a super class with all the properties you want. So any class extending this super class will be have these properties. This way you don't need to use static keyword.

What is best way to construct class with having some default fix property for all instances?

For this one you can have an interface with some constant properties. This way any class implementing this interface will be having the fixed properties.

Upvotes: 0

A4L
A4L

Reputation: 17595

You could separate/extract the parameters from the RowWidget-class fro example in a RowWidgetConfig-class.

class RowWidgetConfig {
    // put here all your parameters that you need to initialize only once
    // init using setters
}

Now create once instance of that class and pass it among the other parameters to RowWidget constructor.

Another alternative would be to have factory for creating RowWidget instances. The factory would also contain all the parameters you need for a row instance plus a factory method createNewRowWidget witch creates an instance base on the parameters contained in the factory.

class RowWidgetFactory {
    // put here all your parameters that you need to initialize only once
    // init using setters

    public RowWidget createNewRowWidget() {
        // create
        return ...
    }
}

Upvotes: 0

R Kaja Mohideen
R Kaja Mohideen

Reputation: 917

Why not create method which will accept the newValues for the properties you want to change & return a new instance of the classes with all other properties copied from the instance on which you invoked this method.

Upvotes: 0

Related Questions