Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preferred way of declaring methods in a class

I am having a doubt with method creations in a class for setting information.

  1. creating separate methods for setting each attribute

    class Address{
        private String name;
        private String city;
    
        public setName(String name) { ... }
        public setCity(String name) { ... }
    }
    
  2. creating single method for setting all attributes

    class Address{
        private String name;
        private String city;
    
        public setAddress(String name,String city) { ... }
    }
    

from above two ways which is preferable in memory point of view?

like image 556
satheesh Avatar asked Aug 30 '11 15:08

satheesh


3 Answers

Common practice is to use JavaBean style

class Address {
  private String name;
  private String city;

  public setName(String name){
    this.name = name;
  }

  public String getName() {
     return name;
  }

  public setCity(String city){
     this.city = city;
  }

  public getCity() {
    return city;
  }

}

Another common practise, which is quite similar to you second approach is to create immutable object. Parameters are passed to constructor instead of big setter method.

class Address {
  private final String name;
  private final String city;

  public Address(String name, String city) {
      this.name = name;
      this.city = city;
  }

  public String getName() {
     return name;
  }

  public getCity() {
    return city;
  }
}

From memory point of view, difference would be that second example is setting all attributes in constructor and all those attributes are immutable. In general, object constructed this way are safer when used by multiple threads.

In second example, there is no need for synchronization. You'd need to handle synchronization/memory issues when multiple threads using standard JavaBean object.

like image 101
Arnost Valicek Avatar answered Oct 22 '22 20:10

Arnost Valicek


I can't see how the two approaches would be any different memory-wise.

Choose the approach that makes most sense to have in the interface of the class.

I would recommend to go with approach 2 only if both properties are logically strongly related, or if there is some class invariant that you don't want to temporarily break (even temporarily).

In your Address example, I would definitely go with two setter methods, since when talking about addresses, the name and city are quite unrelated.


For methods in general I'd say that whether or not you split a method up in two has little effect on memory consumption. Each object doesn't get its own set of methods allocated. The memory containing the methods is shared between all instances of a class.


Rule of thumb: Strive to make the interface of your class clean and logical.

like image 31
aioobe Avatar answered Oct 22 '22 20:10

aioobe


Why not to use method #2

Your second example is not recommended because if you added a new field to the Address class, then do you add it into the existing setter method or do you create a new setter method? If you add it into the existing setter method, then any classes that called that method would be broken. And if you created a new setter method, then it is confusing for anyone who wants to use that class why certain fields are grouped together that way while others are not.

Using a separate setter method for each field that you wish to expose

The common practice is to have a single setter method for each field in your class that you wish to expose (i.e. your first example). Whether or not this is a good practice is debatable because it forces a class to be mutable. It is best to make an object immutable, if possible, for a number of reasons.

Initializing your fields using a constructor

One way to make a class immutable is by getting rid of the setter methods and instead making your fields settable via your class constructor, as below. The downside to implementing it this way is that if your class has a lot of fields, it may potentially lead to large, unreadable constructor calls.

public class Address {
    public String name;
    public String city;

    private Address(String name, String city) {
        this.name = name;
        this.city = city;
    }
}

Initializing your fields using the Builder pattern

Below is a completely alternative implementation (inspired by this article) that is a variation of the Builder pattern. It simulates object mutability without sacrificing readability.

public class Address {
    public String name;
    public String city;

    private Address() {}

    private void setName(String name) {
        this.name = name;
    }

    private void setCity(String city) {
        this.city = city;
    }

    static class Builder {
        private Address address = new Address();

        public Builder name(String name) {
            address.setName(name);
            return this;
        }

        public Builder city(String city) {
            address.setCity(city);
            return this;
        }

        public Address build() {
            return address;
        }
    }
}

With the above class, you could create an immutable instance of the Address class as follows:

Address address = new Address.Builder()
        .name("Mansoor's address")
        .city("Toronto")
        .build();

Which approach uses more memory?

From a memory point of view, there shouldn't be any difference since the size of a class in memory is dependent on the fields in the class. Since all three implementations have the same fields, they should take the same amount of space in memory, regardless of which approach you use.

like image 21
Mansoor Siddiqui Avatar answered Oct 22 '22 20:10

Mansoor Siddiqui