Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use multiple constructors to remove duplicated code while maintaining readability?

int a, b, c;  Constructor() {     a = 5;     b = 10;     c = 15;     //do stuff } Constructor(int x, int y) {     a = x;     b = y;     c = 15;     //do stuff } Constructor(int x, int y, int z) {     a = x;     b = y;     c = z;     //do stuff } 

To prevent duplication of "stuff" and a few assignments, I tried out something like:

int a, b, c;  Constructor(): this(5, 10, 15) { } Constructor(int x, int y): this(x, y, 15) { } Constructor(int x, int y, int z) {     a = x;     b = y;     c = z;     //do stuff } 

This works for what I want to do, but sometimes I need to use some lengthy code to create new objects or do some calculations:

int a, b, c;  Constructor(): this(new Something(new AnotherThing(param1, param2, param3),     10, 15).CollectionOfStuff.Count, new SomethingElse("some string", "another     string").GetValue(), (int)Math.Floor(533 / 39.384)) { } Constructor(int x, int y): this(x, y, (int)Math.Floor(533 / 39.384)) { } Constructor(int x, int y, int z) {     a = x;     b = y;     c = z;     //do stuff } 

This code is pretty much the same as before, only the parameters that are being passed aren't very readable. I would prefer doing something like:

int a, b, c;  Constructor(): this(x, y, z) //compile error, variables do not exist in context {     AnotherThing at = new AnotherThing(param1, param2, param3);     Something st = new Something(aThing, 10, 15)     SomethingElse ste = new SomethingElse("some string", "another string");      int x = thing.CollectionOfStuff.Count;     int y = ste.GetValue();     int z = (int)Math.Floor(533 / 39.384);      //In Java, I think you can call this(x, y, z) at this point.     this(x, y, z); //compile error, method name expected } Constructor(int x, int y): this(x, y, z) //compile error {     int z = (int)Math.Floor(533 / 39.384); } Constructor(int x, int y, int z) {     a = x;     b = y;     c = z;     //do stuff } 

Basically I'm building the parameters within the constructor body. Then I'm trying to pass those built parameters to another constructor. I think I remember being able to use the "this" and "super" keywords to call constructors while inside the body of another constructor when coding in Java. It doesn't seem possible in C#.

Is there a way to do this easily? Did I do something incorrectly? If this is not possible, should I just stick with the unreadable code?

I guess I could always cut the duplicated code into another method completely outside the constructors. Then each constructor would just do its own thing and call the code shared by the other constructors.

like image 435
Cheese Avatar asked Apr 30 '12 02:04

Cheese


People also ask

What is the purpose of multiple constructors?

That's the purpose for multiple constructors. To give the programmer flexibility on saying what an object can be created from and which variables need to be initialized in the first place.

How to avoid code duplication in c++?

The C++11 delegating constructors reduce the code duplication and make effective use of the member initializer lists.

Can you have multiple constructors?

The technique of having two (or more) constructors in a class is known as constructor overloading. A class can have multiple constructors that differ in the number and/or type of their parameters. It's not, however, possible to have two constructors with the exact same parameters.

What can be the purpose of having multiple constructors in the same class?

One way to achieve this is by providing multiple constructors in the class at hand. Each constructor will allow you to create instances of the class using a different set of arguments. Some programming languages, such as C++, C#, and Java, support what is known as function or method overloading.

How do I pull up duplicate code from another class?

Use Extract Method for both classes, followed by Pull Up Field for the fields used in the method that you’re pulling up. If the duplicate code is inside a constructor, use Pull Up Constructor Body.

Would you tolerate duplicate code?

The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor. Although this is pretty much arguable, this post also considers cases where you would tolerate duplicate code.

Is code duplication acceptable in software development?

People might consider code duplication acceptable but in reality, it poses greater problems to your software than what you may have thought. Even code that has similar functionalities are said to be duplications. The main reason for creation for the duplicate code is Copy and Paste Programming.

What are the disadvantages of duplicate code?

Duplicate code makes your program lengthy and bulky : Many programmers feel that if the software is working properly there is no reason to fix code duplications. You forget that you are just un-necessarily making your software bulky. Your argument can be that a few blocks of code would just use a few milliseconds to run.


1 Answers

As an alternative to calling an initialization method from all constructors (which prevents you from using readonly fields) or factory methods (which introduce additional complexity when you have derived classes), you can use a parameter object:

int a, b, c;  public Constructor()     : this(new ConstructorParameters()) { }  public Constructor(int x, int y)     : this(new ConstructorParameters(x, y)) { }  public Constructor(int x, int y, int z) {     a = x;     b = y;     c = z;     //do stuff  }   private Constructor(ConstructorParameters parameters)     : this(parameters.X, parameters.Y, parameters.Z) { }  private class ConstructorParameters {     public int X;     public int Y;     public int Z;      public ConstructorParameters()     {         AnotherThing at = new AnotherThing(param1, param2, param3);          Something st = new Something(at, 10, 15)          SomethingElse ste = new SomethingElse("some string", "another string");           X = st.CollectionOfStuff.Count;          Y = ste.GetValue();          Z = (int)Math.Floor(533 / 39.384);      }      public ConstructorParameters(int x, int y)     {         X = x;         Y = y;         Z = (int)Math.Floor(533 / 39.384);     } } 
like image 179
Michael Liu Avatar answered Oct 12 '22 11:10

Michael Liu