I am learning about the builder pattern, and so far I understood that, it is a great alternative to the commonly patterns used for initialization:
Telescoping Constructor Pattern
JavaBean Pattern
The thing is, I don't really like to remove the getters and setters from the objects in my domain model. I always like to keep them as POJOs. One of the reasons I don't like it is:
If i don't use POJOs, then it is not easy to annotate the variables when using ORM frameworks...
So here are my doubts:
-Is it possible to implement the builder pattern without using static inner classes?
-If I have to use the builder pattern by using the inner class, do you think it is correct to keep the getters and the setters?
-I did a little example for practice where I tried to avoid the inner class.
Could you let me what do you think about it?
Product
public class Product
{
private String color;
private int price;
public Product() {
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String toString() {
return getColor() + "\n" + getPrice();
}
}
Builder
public class Builder
{
private Product product;
public Builder() {
product = new Product();
}
public Builder withColor(String color) {
product.setColor(color);
return this;
}
public Builder withPrice(int price) {
product.setPrice(price);
return this;
}
public Product build() {
return product;
}
}**
Client
public class Client
{
public static void main(String[] args) {
System.out.println(new Builder().withColor("Black").withPrice(11).build());
System.out.println("-----------------------------------------------------");
System.out.println(new Builder().withColor("Blue").withPrice(12).build());
}
}
The Builder pattern is useful to create immutable objects and avoid several constructors with optional parameters.
IMO using Builder pattern to build a POJO which can be updated using setters is useless. You only create an additional class.
Depending on the ORM framework used, it might not need the presence of setter method. But only assigning members values through reflection.
Product class:
public final class Product {
private final String color;
private final int price;
public Product(Builder builder) {
this.color = builder.getColor();
this.price = builder.getPrice();
}
public String getColor() {
return color;
}
public int getPrice() {
return price;
}
public String toString() {
return getColor() + "\n" + getPrice();
}
}
Builder class:
public final class Builder {
private String color;
private int price;
public Builder() {
// Assign any default values
}
public Builder color(String color) {
this.color = color;
return this;
}
public Builder price(int price) {
this.price = price;
return this;
}
protected String getColor() {
return color;
}
protected int getPrice() {
return price;
}
public Product build() {
return new Product(this);
}
}
The builder pattern is most useful in the context of immutable objects. Immutable objects don't have setters by definition. So all of their properties have to be squeezed into the constructor. This is where the builder pattern comes in handy. It allows you to split the initialization of a complex immutable object into multiple, self-explaining instructions so you don't need to have constructor calls like this fictional example all over you code where you can't tell which argument does what:
Thing foo = new Thing(1, 125, Thing.SOMETHING, new Whatchamacallit(17, 676), getStuffManager(StuffManager.ZOMG), true, false, false, maybe);
I don't find that the Builder pattern creates any signficant value when the created object is mutable. Everything you do through the builder can also be done with the created object directly.
Also, I think that your program above is not a textbook example of the builder pattern. You usually don't create an object by passing the builder to the constructor. You create an object by calling a create method on the builder which then passes all its properties to the constructor of the object. This pattern has the advantage that it gives the builder the opportunity to check its internal state for consistency and maybe throw an exception before starting to build the object.
The java StringBuilder class is a good example (the create method being tostring in this case).
What does using a builder here actually gain you?
Nothing as far as I can see: you could just create a new Product and use the getters and setters on it directly. If you have a simple POJO then there is absolutely nothing wrong with:
Product p=new Product();
p.setColour("Black");
p.setPrice(11);
doSomethingWith(p);
Saving a few characters of typing is IMHO not worth introducing a new class / builder abstraction.
Builders are more useful in situations like the following:
You want to create an immutable object (and hence can't use setters)
If you have complicated factory logic that cannot easily be expressed with simple getters and setters or that you want to re-use in different ways
(Occasionally) when you want to have different parts of the code base configure different aspects of the builder for some reason.
The builder pattern lends itself well to producing immutable classes, but it can still be a good option for mutable classes too.
A builder is a reasonable design choice in any situation where an object contains many fields that need to be set during construction; particularly if sensible defaults can be chosen for several of the values.
Whether you use an inner class depends upon your goals. If you wish to force construction through the builder, you can define the builder as an inner class and ensure the outer class only has a private constructor.
Here are Builder collaborations from GoF book:
Collaborations
1. The client creates the Director object and configures it with the desired Builder object.
2. Director notifies the builder whenever a part of the product should be built.
3. Builder handles requests from the director and adds parts to the product.
3. The client retrieves the product from the builder.
The Builder pattern focuses on constructing a complex object step by step. Builder returns the product as a final step. The returned class in absence of the setters may be as good as immutable. With setters, it can be modified. And inner classes help mask the details.
Another point worth noting is that a major motivation behind creational design patterns is that the client doesn't worry about creating the product. The object creation process is delegated to factory, builder, etc. The client doesn't have to worry about object creation. It will specify what it wants and will get it as a result of delegated creation process.
Is it possible to implement the builder pattern without using static
inner classes?
Absolutely, yes. As far as the Builder design pattern is concerned, it does not make any difference if the Builder is an inner class or not.
-If I have to use the builder pattern by using the inner class, do you think it is correct to keep the getters and the setters?
Yes, it is ok. it is kind of like, build the object using a certain template and then customize it, if needed.
-I did a little example for practice where I tried to avoid the inner
class. Could you let me what do you think about it?
Two problems -
the example does not justify the usage of Builder pattern. Builder pattern is used to build a complex object. So if you can simply build product as :
Product p = new Product();
p.setColor(c);
p.setPrice(prc);
Then there is hardly any benefit in the way you have shown.
Product should not have a dependency on Builder.
I found myself thinking if getters are any good in a builder. A builder shouldn't generally be used as a return value - a single method or class should be responsible for creation of the entity using builder. Thus, the method (or class) should keep the information it needs instead of getting it back.
For those reasons, I decided not to use any getters in the builder class. Builder only has setters (be it withAbc(...), setAbc(...) or abc(...)), build() and possibly some private methods like validate().
Using class Product, a sample entity looks like this:
class Product {
private final String color;
private final int price;
private Product(ProductBuilder builder) {
this.color = builder.color;
this.price = builder.price;
}
// equals, hashCode, toString
public builder() {
return new ProductBuilder(this);
}
public static emptyBuilder() {
return new ProductBuilder();
}
public String getColor() {
return color;
}
public int getPrice() {
return price;
}
Now, a builder class is an inner class of the entity, which allows me to use private constructors.
public static class ProductBuilder {
private String color;
private int price;
private ProductBuilder() {
}
private ProductBuilder(Product entity) {
this.color = entity.color;
this.price = entity.price;
}
public ProductBuilder withColor(String color) {
this.color = color;
return this;
}
public ProductBuilder withPrice(int price) {
this.price = price;
return this;
}
public Product build() {
return new Product(this.validate());
}
private ProductBuilder validate() {
if (color == null) {
throw new IllegalStateException("color is null");
}
return this;
}
}
As you can see, I added method builder() to get builder as a copy of the instance and emptyBuilder() as a factory method to hide constructor (maybe there is a better name for it).
Also, when constructing an immutable class, make sure everything inside is immutable as well. Collections are tricky, you have to make a copy, then use Collections.unmodifiable*(...) on it to ensure nobody has a reference to the collection lying under the unmodifiable wrapper.
EDIT: Allegedly, you need getters if you have abstract superclass. That is an overstatement. You only need it if you have a constructor with all params. If you pass the builder instead, like me, you get:
class Product extends Something { ...
private Product(ProductBuilder builder) {
super(builder); // that one must be protected, not private
...
}
public static class ProductBuilder extends SomethingBuilder { ...
protected ProductBuilder validate() {
super.validate();
...
}
}
}
So, do we need getters? This time, not really. We're still fine without them. Some other ideas?
Builder is about several things and you may want to utilize only one aspect: fluent API. You may attain the best fit for your needs by just changing your setters to return this instead of void. Then you can use the chained-setter idiom: return new MyBean().setCheese(cheese).setBacon(bacon);
On a side note, the term "POJO" does not mean the same as "JavaBean". In fact, sometimes these two terms are used as opposites. The point of a POJO is that it doesn't conform to anything else than being a Java object. It may use public variables, for example.
Related
Foo foo = Foo.builder()
.setColor(red)
.setName("Fred")
.setSize(42)
.build();
So I know there is the following "Builder" solution for creating named parameters when calling a method. Although, this only seems to work with inner static classes as the builder or am I wrong? I had a look at some tutorials for builder pattern but they seem really complex for what im trying to do. Is there any way to keep the Foo class and Builder class separate while having the benefit of named parameters like the code above?
Below a typical setup:
public class Foo {
public static class Builder {
public Foo build() {
return new Foo(this);
}
public Builder setSize(int size) {
this.size = size;
return this;
}
public Builder setColor(Color color) {
this.color = color;
return this;
}
public Builder setName(String name) {
this.name = name;
return this;
}
// you can set defaults for these here
private int size;
private Color color;
private String name;
}
public static Builder builder() {
return new Builder();
}
private Foo(Builder builder) {
size = builder.size;
color = builder.color;
name = builder.name;
}
private final int size;
private final Color color;
private final String name;
}
Use composition. To make things easier and cleaner, do not replicate all attributes in source (Foo) and builder (Builder) class.
For example, have Foo class inside Builder instead of each of Foo attribute.
simple code snippet:
import java.util.*;
class UserBasicInfo{
String nickName;
String birthDate;
String gender;
public UserBasicInfo(String name,String date,String gender){
this.nickName = name;
this.birthDate = date;
this.gender = gender;
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("Name:DOB:Gender:").append(nickName).append(":").append(birthDate).append(":").
append(gender);
return sb.toString();
}
}
class ContactInfo{
String eMail;
String mobileHome;
String mobileWork;
public ContactInfo(String mail, String homeNo, String mobileOff){
this.eMail = mail;
this.mobileHome = homeNo;
this.mobileWork = mobileOff;
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("email:mobile(H):mobile(W):").append(eMail).append(":").append(mobileHome).append(":").append(mobileWork);
return sb.toString();
}
}
class FaceBookUser {
String userName;
UserBasicInfo userInfo;
ContactInfo contactInfo;
public FaceBookUser(String uName){
this.userName = uName;
}
public void setUserBasicInfo(UserBasicInfo info){
this.userInfo = info;
}
public void setContactInfo(ContactInfo info){
this.contactInfo = info;
}
public String getUserName(){
return userName;
}
public UserBasicInfo getUserBasicInfo(){
return userInfo;
}
public ContactInfo getContactInfo(){
return contactInfo;
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("|User|").append(userName).append("|UserInfo|").append(userInfo).append("|ContactInfo|").append(contactInfo);
return sb.toString();
}
static class FaceBookUserBuilder{
FaceBookUser user;
public FaceBookUserBuilder(String userName){
this.user = new FaceBookUser(userName);
}
public FaceBookUserBuilder setUserBasicInfo(UserBasicInfo info){
user.setUserBasicInfo(info);
return this;
}
public FaceBookUserBuilder setContactInfo(ContactInfo info){
user.setContactInfo(info);
return this;
}
public FaceBookUser build(){
return user;
}
}
}
public class BuilderPattern{
public static void main(String args[]){
FaceBookUser fbUser1 = new FaceBookUser.FaceBookUserBuilder("Ravindra").build(); // Mandatory parameters
UserBasicInfo info = new UserBasicInfo("sunrise","25-May-1975","M");
// Build User name + Optional Basic Info
FaceBookUser fbUser2 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
setUserBasicInfo(info).build();
// Build User name + Optional Basic Info + Optional Contact Info
ContactInfo cInfo = new ContactInfo("xxx#xyz.com","1111111111","2222222222");
FaceBookUser fbUser3 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
setUserBasicInfo(info).
setContactInfo(cInfo).build();
System.out.println("Facebook user 1:"+fbUser1);
System.out.println("Facebook user 2:"+fbUser2);
System.out.println("Facebook user 3:"+fbUser3);
}
}
output:
Facebook user 1:|User|Ravindra|UserInfo|null|ContactInfo|null
Facebook user 2:|User|Ravindra|UserInfo|Name:DOB:Gender:sunrise:25-May-1975:M|ContactInfo|null
Facebook user 3:|User|Ravindra|UserInfo|Name:DOB:Gender:sunrise:25-May-1975:M|ContactInfo|email:mobile(H):mobile(W):xxx#xyz.com:1111111111:2222222222
Explanation:
FaceBookUser is a complex object with below attributes using composition:
String userName;
UserBasicInfo userInfo;
ContactInfo contactInfo;
FaceBookUserBuilder is a static builder class, which contains and builds FaceBookUser.
userName is only Mandatory parameter to build FaceBookUser
FaceBookUserBuilder builds FaceBookUser by setting optional parameters : UserBasicInfo and ContactInfo
This example illustrates three different FaceBookUsers with different attributes, built from Builder.
fbUser1 was built as FaceBookUser with userName attribute only
fbUser2 was built as FaceBookUser with userName and UserBasicInfo
fbUser3 was built as FaceBookUser with userName,UserBasicInfo and ContactInfo
In this example, composition has been used instead of duplicating all attributes of FaceBookUser in Builder class.
EDIT:
Group all related attributes into logical classes. Define all these classes in FaceBookUser. Instead of adding all these member variables again in Builder, contain FaceBookUser in Builder class.
For simplicity, I have added two classes: UserBasicInfo and ContactInfo . Now explode this FaceBookUser class with other attributes like
NewsFeed
Messages
Friends
Albums
Events
Games
Pages
Ads
etc.
If you duplicate all these attributes in both Builder and FaceBookUser, code will become difficult to manage. Instead, by using composition of FaceBookUser in FaceBookUserBuilder itself, you can simply construction process.
Once you add above attributes, you will build FaceBookUser in step-by-step process as usual.
It will be like this:
FaceBookUser fbUser3 = new FaceBookUser.FaceBookUserBuilder("Ravindra").
setUserBasicInfo(info).
setNewsFeed(newsFeed).
setMessages(messages).
setFriends(friends).
setAlbums(albums).
setEvents(events).
setGames(games).
setAds(ads).build();
You can sure change the fields of your Builder class to be private - then you just need a (public) getter method for each "property" on the builder; and the constructor in Foo calls those methods; instead of just fetching the fields in the Builder object.
Then you can just move your Builder class out of Foo. Simple and straightforward.
But keep in mind: in the end, Builder and Foo are very closely related. They share a common set of fields by design. So any change to Foo affects Builder; and vice versa. Thus it makes a lot of sense to keep them "close together". Maybe not as inner/outer class, but maybe still within the same source file! But then ... only one of them can be public. Is that really what you want?!
In other words: don't rip things apart just "because you can". Only do it if you have good reasons to do so, and if the thing that comes out of that is better than your current solution!
Edit: your problem might not be separation of Foo and Builder, but the fact that your Foo class has too many fields in the first place. Dont forget about the single responsibility principle ... when your class needs more than 5, 6 fields ... it is probably doing too much and should be further sliced! Keep in mind: good OO design is first of all about behavior; not about having 10, 20 fields within some object!
It's difficult to strictly define "The Builder Pattern™", and there are several degrees of freedom regarding the design choices. Some concepts can easily be mixed or abused, and beyond that, it is generally hard (and nearly always wrong) to say "you always have to do it exactly like that".
The question is what should be achieved by applying a "pattern". In your question and the example, you already mixed two concepts, namely the builder pattern and the fluent interface. Playing devil's advocate, one could even sneakily argue that the "Builder" in your case is just the Parameter Object that Thomas already mentioned, which is constructed in a special way (fluently) and enriched with some tricky combination of public and private visibilities.
Some of the possible goals of the builder pattern are overlapping or go hand in hand. But you should ask yourself what the primary goal is in your case:
Should the resulting object be immutable?
Should it be really immutable, with only final final fields, or could there also be setters that just should not be public? (The builder could still call these non-public setters!)
Is the goal to limit visibility in general?
Should there be polymorphic instantiation?
Is the main goal to summarize a large number of constructor parameters?
Is the main goal to offer an easy configuration with a fluent interface, and to manage "default" values?
...
As all these question will have an effect on the subtle differences in the design. However, regarding your actual, high level, "syntactic" question:
You could design the builder as a public static inner class (what you did in the example).
public class Person {
...
public static PersonBuilder create() { ... }
public static class PersonBuilder {
...
public Person build() { ... }
}
}
This offers the strictest form of privacy: The constructors of Person and PersonBuilder may both be private.
You could also place the actual class and its builder in separate files:
public class Person {
...
}
and
public class PersonBuilder {
...
}
A reasonable degree of privacy can be achieved here: The constructors of both can be package private (i.e. have default visibility).
In both cases, the actual usage for clients would be the same, except for the name of the builder class (package.Person.PersonBuilder vs. package.PersonBuilder). The "contents" of the classes would also be the same (except for slightly different visibilities). And in both cases, you can create subclasses of Person, if desired, depending on the builder configuration, and the builder itself can have a fluent interface.
As an alternative to the builder pattern, you could also use a parameter object:
class FooParams {
public int size;
public Color color;
public String name;
}
You can use getters and setters here, instead of public fields, if you prefer.
Then the Foo constructor takes one of these as an argument:
public Foo(FooParams params) {
this.size = params.size;
this.color = params.color;
this.name = params.name;
}
How can I use the set and get methods, and why should I use them? Are they really helpful? And also can you give me examples of set and get methods?
Set and Get methods are a pattern of data encapsulation. Instead of accessing class member variables directly, you define get methods to access these variables, and set methods to modify them. By encapsulating them in this manner, you have control over the public interface, should you need to change the inner workings of the class in the future.
For example, for a member variable:
Integer x;
You might have methods:
Integer getX(){ return x; }
void setX(Integer x){ this.x = x; }
chiccodoro also mentioned an important point. If you only want to allow read access to the field for any foreign classes, you can do that by only providing a public get method and keeping the set private or not providing a set at all.
I want to add to other answers that setters can be used to prevent putting the object in an invalid state.
For instance let's suppose that I've to set a TaxId, modelled as a String. The first version of the setter can be as follows:
private String taxId;
public void setTaxId(String taxId) {
this.taxId = taxId;
}
However we'd better prevent the use to set the object with an invalid taxId, so we can introduce a check:
private String taxId;
public void setTaxId(String taxId) throws IllegalArgumentException {
if (isTaxIdValid(taxId)) {
throw new IllegalArgumentException("Tax Id '" + taxId + "' is invalid");
}
this.taxId = taxId;
}
The next step, to improve the modularity of the program, is to make the TaxId itself as an Object, able to check itself.
private final TaxId taxId = new TaxId()
public void setTaxId(String taxIdString) throws IllegalArgumentException {
taxId.set(taxIdString); //will throw exception if not valid
}
Similarly for the getter, what if we don't have a value yet? Maybe we want to have a different path, we could say:
public String getTaxId() throws IllegalStateException {
return taxId.get(); //will throw exception if not set
}
I think you want something like this:
public class Person {
private int age;
//public method to get the age variable
public int getAge(){
return this.age
}
//public method to set the age variable
public void setAge(int age){
this.age = age;
}
}
You're simply calling such a method on an object instance. Such methods are useful especially if setting something is supposed to have side effects. E.g. if you want to react to certain events like:
public void setAge(int age){
this.age = age;
double averageCigarettesPerYear = this.smokedCigarettes * 1.0 / age;
if(averageCigarettesPerYear >= 7300.0) {
this.eventBus.fire(new PersonSmokesTooMuchEvent(this));
}
}
Of course this can be dangerous if somebody forgets to call setAge(int) where he should and sets age directly using this.age.
Setters and getters are used to replace directly accessing member variables from external classes. if you use a setter and getter in accessing a property, you can include initialization, error checking, complex transformations, etc. Some examples:
private String x;
public void setX(String newX) {
if (newX == null) {
x = "";
} else {
x = newX;
}
}
public String getX() {
if (x == null) {
return "";
} else {
return x;
}
}
Having accessor methods is preferred to accessing fields directly, because it controls how fields are accessed (may impose data checking etc) and fits with interfaces (interfaces can not requires fields to be present, only methods).
Some benefits of using getters and setters (known as encapsulation or data-hiding):
(originally answered here)
1. The fields of a class can be made read-only (by only providing the getter) or write-only (by only providing the setter). This gives the class a total control of who gets to access/modify its fields.
Example:
class EncapsulationExample {
private int readOnly = -1; // this value can only be read, not altered
private int writeOnly = 0; // this value can only be changed, not viewed
public int getReadOnly() {
return readOnly;
}
public int setWriteOnly(int w) {
writeOnly = w;
}
}
2. The users of a class do not need to know how the class actually stores the data. This means data is separated and exists independently from the users thus allowing the code to be more easily modified and maintained. This allows the maintainers to make frequent changes like bug fixes, design and performance enhancements, all while not impacting users.
Furthermore, encapsulated resources are uniformly accessible to each user and have identical behavior independent of the user since this behavior is internally defined in the class.
Example (getting a value):
class EncapsulationExample {
private int value;
public int getValue() {
return value; // return the value
}
}
Now what if I wanted to return twice the value instead? I can just alter my getter and all the code that is using my example doesn't need to change and will get twice the value:
class EncapsulationExample {
private int value;
public int getValue() {
return value*2; // return twice the value
}
}
3. Makes the code cleaner, more readable and easier to comprehend.
Here is an example:
No encapsulation:
class Box {
int widthS; // width of the side
int widthT; // width of the top
// other stuff
}
// ...
Box b = new Box();
int w1 = b.widthS; // Hm... what is widthS again?
int w2 = b.widthT; // Don't mistake the names. I should make sure I use the proper variable here!
With encapsulation:
class Box {
private int widthS; // width of the side
private int widthT; // width of the top
public int getSideWidth() {
return widthS;
}
public int getTopWIdth() {
return widthT;
}
// other stuff
}
// ...
Box b = new Box();
int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side
int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!
Look how much more control you have on which information you are getting and how much clearer this is in the second example. Mind you, this example is trivial and in real-life the classes you would be dealing with a lot of resources being accessed by many different components. Thus, encapsulating the resources makes it clearer which ones we are accessing and in what way (getting or setting).
Here is good SO thread on this topic.
Here is good read on data encapsulation.
The above answers summarize the role of getters and setters better than I could, however I did want to add that your code should ideally be structured to reduce the use of pure getters and setters, i.e. those without complex constructions, validation, and so forth, as they break encapsulation. This doesn't mean you can't ever use them (stivlo's answer shows an example of a good use of getters and setters), just try to minimize how often you use them.
The problem is that getters and setters can act as a workaround for direct access of private data. Private data is called private because it's not meant to be shared with other objects; it's meant as a representation of the object's state. Allowing other objects to access an object's private fields defeats the entire purpose of setting it private in the first place. Moreover, you introduce coupling for every getter or setter you write. Consider this, for example:
private String foo;
public void setFoo(String bar) {
this.foo = bar;
}
What happens if, somewhere down the road, you decide you don't need foo anymore, or you want to make it an integer? Every object that uses the setFoo method now needs to be changed along with foo.
just because the OOP rule: Data Hiding and Encapsulation. It is a very bad practice to declare a object's as public and change it on the fly in most situations. Also there are many other reasons , but the root is Encapsulation in OOP. and "buy a book or go read on Object Oriented Programming ", you will understand everything on this after you read any book on OOP.
The benefits of get() set() methods are as follows ..
You can serialize you object easily.
You can create a persistent object from the containing class.
You can convert the properties to JSON easily.
In the DAO layer (Frameworks like Hibernate) you can directly save the object to DB.
Easy understanding of object oriented concept.
Needs in all design pattern except possibly in single tone pattern.
Security for properties protecting direct access.
Polymorphism, Encapsulation can be easily understood and implemented by this type of class.
Example:
private String personName;
private int personId;
public void setPersonName(String name) throws Exception{
if(!(name.equals("")||name=="")){
this.personName = name;
}
}
public String getPersonName(){
return this.personName;
}
public void setPersonId(int id) throws Exception{
this.personId = id;
}
public int getPersonId(){
return this.personId;
}
Above answers all assume that the object in question is an object with behaviour.
An advanced strategy in OOP is to separate data objects (that do zip, only have fields) and behaviour objects.
With data objects, it is perfectly fine to omit getters and instead have public fields. They usually don't have setters, since they most commonly are immutable - their fields are set via the constructors, and never again.
Have a look at Bob Martin's Clean Code or Pryce and Freeman's Growing OO Software... for details.
public class Person{
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
i think this is you want..
and this also called pojo
this is the code for set method
public void setAge(int age){
this.age = age;
}
It looks like you trying to do something similar to C# if you want setAge create method setAge(int age){
this.age = age;}
I don't see a simple answer to the second question (why) here. So here goes.
Let's say you have a public field that gets used very often in your code. Whenever you decide you need to do something extra before you give or set this field you have a problem. You have to create a special getter and setter for this field and change your complete code from using the field directly to using the getter and setters.
Now imagine you are developing a library widely used by many people. When you need to make a change like the above and set direct access of the field to private the code of all the people using this field will break.
Using getters and setters is about future planning of the code, it makes it more flexible. Of course you can use public fields, especially for simple classes that just hold some data. But it's always a good idea to just make the field privately and code a get and set method for it.
This answer is merged from another question.
Your getAge() method is called instance method in Java.
To invoke an instance method, you should have a object of the Class in which this method is defined.
For Example, If this method in a Class called Person, then
Create a Person object using new operator
Person p = new Person();
To get the age of a Person object, use this method
p.getAge()
Although still a second year undergraduate student I will say my opinion. I believe that Java and private variables within your class are "RULES". Therefore because the variables in your class are private I think you use getters and setters to be able to define these variables outside the class.
I'm re-writing some code, and I've decided the way to recreate the class, as there are a fixed number of sheets, I'm creating them as enums. This is a decision based on the readability of a builder patter vs a telescoping constructor.
The code I'm grabs some some .xls files, adds headers (and reads some from other .xls files) and perhaps some sub-sheets. It then merges a variety of these sheets together in a specific way to make tabs on a main excel workbook. My issue is that some of the workbook tabs take different numbers of sheets are arguments. I'm trying to apply the builder pattern. This is the sort of code I'm trying to write:
public enum workBookSheet {
mySheet1("Name1","mainSheet1.xls",true,1).addSubSheet("pathToSubSheet1.xls"),
mySheet2("Name2","mainSheet2.xls",true,2).addHeaderSheet("pathToHeaders.xls").addSubsheet("pathtoSubSheet2.xls");
private String tabName;
private String mainSheetName;
private Boolean available;
private Integer order;
private String subSheetName;
private String headerSheetName;
private workBookSheet(String tabName, String mainSheetName, Boolean available, Integer order){
this.tabName = tabName;
this.mainSheetName = mainSheetName;
this.available = available;
this.order = order;
}
public workBookSheet addSubSheet(String subSheetName){
this.subSheetName = subSheetName;
return this;
}
public workBookSheet addHeaderSheet(String headerSheetName){
this.headerSheetName = headerSheetName;
return this;
}
}
The error that java is giving me seems to be saying that Java expects my enum declaration (comma delimited list of 'enum constructors' at the top) to only have the constructor in it, and not additional methods. I can move those methods to a 'builder' method below, without complaint.
public void buildSheets(){
mySheet1.addSubSheet("pathToSubSheet1.xls");
mySheet2.addHeaderSheet("pathToHeaders.xls").addSubSheet("pathtoSubSheet2.xls");
}
Is this the only way to implement a builder pattern on an enum? It does require me to run a separate method, which isn't too much hassle. IT does feel like I'm breaking the pattern though (I guess, not such a bad thing if this works.)
N.B I've had a good look around to see if anyone else has asked this question, on SO or elsewhere on the web. The closest I found was a question here on Enums and Factories, but that doesn't quite answer my question. Also I'm aware this isn't quite the builder pattern, as I don't have a separate class that then accepts a build() method that creates a new enum. I guess this is the root of the problem in my initial design, but I am relatively new to Java.
So Is there a better way to use a builder pattern on a Java enum? Or is what I have 'close enough'?
Although it doesn't strictly conform to the builder pattern, the short answer is yes. Sort of.
The missing piece is not being able to call .build() to instantiate the enum constant, because build() can't use new. But you can get quite a few of the benefits of the builder pattern. And let's face it, you can't use static factory methods, and inline subclassing of enum constants is weird.
Here's an example using a Country enumeration.
package app;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.Set;
import static app.Language.*;
import static com.google.common.base.Preconditions.*;
enum Language {
ITALIAN,
ENGLISH,
MALTESE
}
public enum Country {
ITALY(new Builder(1, "Italy").addLanguage(ITALIAN)),
MALTA(new Builder(2, "Malta").addLanguages(MALTESE, ENGLISH, ITALIAN).setPopulation(450_000));
final private int id;
final private String name;
final private Integer population;
final private Set<Language> languages;
private static class Builder {
private int id;
private String name;
private Integer population;
private Set<Language> languages = EnumSet.noneOf(Language.class);
public Builder(int id, String name) {
checkArgument(!StringUtils.isBlank(name));
this.id = id;
this.name = name;
}
public Builder setPopulation(int population) {
checkArgument(population > 0);
this.population = population;
return this;
}
public Builder addLanguage(Language language) {
checkNotNull(language);
this.languages.add(language);
return this;
}
public Builder addLanguages(Language... language) {
checkNotNull(language);
this.languages.addAll(languages);
return this;
}
}
private Country(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.population = builder.population;
this.languages = builder.languages;
checkState(!this.languages.isEmpty());
}
public int getId() {
return id;
}
public String getName() {
return name;
}
#Nullable
public Integer getPopulation() {
return population;
}
public Set<Language> getLanguages() {
return languages;
}
}
You can even put static factory methods in the builder if you have common ways to build a constant.
So it's not quite Bloch's builder, but it's pretty close.
You can use instance blocks (often incorrectly called "double brace initializers") to customise construction with arbitrary code:
public enum workBookSheet {
mySheet1("Name1", "mainSheet1.xls", true, 1) {{
addSubSheet("pathToSubSheet1.xls");
}},
mySheet2("Name2", "mainSheet2.xls", true, 2) {{
// you can use the fluent interface:
addHeaderSheet("pathToHeaders.xls").addSubSheet("pathtoSubSheet2.xls");
// but I would prefer coding separate statements:
addHeaderSheet("pathToHeaders.xls");
addSubSheet("pathtoSubSheet2.xls");
}};
// rest of your class the same...
}
Employing this syntax allows you to work around the limitations imposed by an enum but still have the brevity, convenience and flexibility of a builder/fluent pattern.
mySheet1, mySheet2, etc. are enum constants which follows the JLS syntax defined in section 8.9.1
EnumConstant:
Annotationsopt Identifier Argumentsopt ClassBodyopt
So, you can follow the enum constant by an argument list (the parameters to pass to the constructor) but you can't call a method on the enum constant while declaring it. At most you can add a class body for it.
Beside this, your usage of builder pattern to build enum instances is questionable as in general the builder pattern is used when you have a large number of instances (combinations of field values) in contrast with the concept of enums used for a few instances.
I saw somewhere on SO today a design pattern that was used to illustrate a point about immutable objects in Java. The idea is to allow the user to set the value for whatever properties he wants during construction, and it looks something like this:
MyObject obj = new MyObject().name("Foo")
.height(5)
.width(3)
.color("blue")
.age(7);
Is there a name for this pattern?
In C++ I know you can just return a pointer to this in each function. How is it done the same way in Java?
For immutable objects, do you have to make a new copy of the object for each property you want to set?
If you want to construct an immutable object with approximately this style, you likely want the Builder pattern.
The chaining visible in this is also known as a Fluent interface and is indeed enabled by returning this.
With your code using the fluent interface on the actual object under construction, the object won't be immutable if all the methods setting things are in fact mutators. If these methods all return a new object instead of this it could be immutable.
This is NOT the Builder pattern as mentioned in the comments by others.
It is the http://en.wikipedia.org/wiki/Fluent_interface, which is similar but not the same.
Your last two questions I think are somewhat correlated, as you can implement this pattern both in a mutable and immutable way.
If you implement it mutable, then for each method you alter the state and return this:
public class UsefulThing {
Integer state;
public UsefulThing(Integer state) {
this.state=state;
}
public UsefulThing alter(Integer newState) {
state = newState;
return this;
}
}
For an immutable implementation, you create a new object based on the one supplied and return that.
public class UsefulThing {
Integer state;
public UsefulThing(Integer state) {
this.state=state;
}
public UsefulThing alter(Integer newState) {
return new UsefulThing(newState);
}
}
This looks like a form of the builder pattern (though really, it's not).
Usually (using your example and assuming it's immutable) it follows a pattern similar to this:
public class MyObject {
private final String name;
private final int height;
private final int width;
private final String color;
private final int age;
private MyObject(Builder builder) { // Notice this is private
name = builder.name;
height = builder.height;
width = builder.width;
color = builder.color;
age = builder.age;
}
// Getters
public static class Builder {
// Initialize these to defaults if you have any
private String name;
private int height;
private int width;
private String color;
private int age;
// Getters as usual
// Every setter looks like this:
public Builder setName(String name) {
this.name = name;
return this;
}
// Other setters
public MyObject build() {
return new MyObject(this);
}
}
}
Then to use it:
MyObject obj = new MyObject.Builder()
.setName("Foo")
.setHeight(5)
.setWidth(3)
.setColor("blue")
.setAge(7)
.build();
You can also reuse the builder:
MyObject.Builder builder = new MyObject.Builder();
MyObject obj1 = builder
.setName("Foo")
.setHeight(5)
.setWidth(3)
.setColor("blue")
.setAge(7)
.build();
MyObject obj2 = builder
.setName("Bar")
.build();
Here, obj2 will have the same properties as obj1 for all but name.
This is usually an alternative to long constructors. It can also be used for an object where all the information isn't available immediately and you don't want to declare a bunch of variables yourself everywhere you need to create your object. From the last example, you see it can be used if you have lots of objects you want to initialize with the same properties without having to pass those properties over and over again.
The result is that you have an immutable object, but you don't have to set/pass all of the variables at the same time like you would with a constructor or a static factory method.
Here are some references:
Wikipedia builder pattern page
OODesign.com's builder pattern page (also details how you can use interfaces for the builder pattern)
Joshua Bloch's Effective Java - 2nd Edition is an excellent source of information about some of the patterns (and anti-patterns) in Java.
This is an example of the Builder Pattern.
A more typical usage would be:
MyObject obj = new MyObjectBuilder().name("Foo").blah().build();
Note the use of a distinct builder class.
The builder pattern is popular to create immutable objects, but there is some programming overhead to create a builder. So I wonder why not simply using a config object.
The usage of a builder would look like this:
Product p = Product.Builder.name("Vodka").alcohol(0.38).size(0.7).price(17.99).build();
It is obvious that this is very readable and concise, but you have to implement the builder:
public class Product {
public final String name;
public final float alcohol;
public final float size;
public final float price;
private Product(Builder builder) {
this.name = builder.name;
this.alcohol = builder.alcohol;
this.size = builder.size;
this.price = builder.price;
}
public static class Builder {
private String name;
private float alcohol;
private float size;
private float price;
// mandatory
public static Builder name(String name) {
Builder b = new Builder();
b.name = name;
return b;
}
public Builder alcohol(float alcohol) {
this.alcohol = alcohol;
return.this;
}
public Builder size(float size) {
this.size = size;
return.this;
}
public Builder price(float price) {
this.price = price;
return.this;
}
public Product build() {
return new Product(this);
}
}
}
My idea is, to reduce the code by using a simple config object like this:
class ProductConfig {
public String name;
public float alcohol;
public float size;
public float price;
// name is still mandatory
public ProductConfig(String name) {
this.name = name;
}
}
public class Product {
public final String name;
public final float alcohol;
public final float size;
public final float price;
public Product(ProductConfig config) {
this.name = config.name;
this.alcohol = config.alcohol;
this.size = config.size;
this.price = config.price;
}
}
Usage:
ProductConfig config = new ProductConfig("Vodka");
config.alcohol = 0.38;
config.size = 0.7;
config.price = 17.99;
Product p = new Product(config);
This usage needs a few more lines but is also very readable, but the implementation is much simpler and maybe it is easier to understand for someone who isn't familiar with the builder pattern. By the way: is there a name for this pattern?
Is there a drawback in the config approach that I've overlooked?
The builder pattern improves decoupling - your Product can be an interface and the only class that knows about the implementation (or implementations, in some cases) is the builder. If the builder also implements an interface then you can inject this into your code to increase decoupling further.
This decoupling means your code is more maintainable and easier to test.
You are losing several advantages of the builder pattern, as has already been pointed out (new is ugly and harder to maintain and leaking details compared to a clean builder).
The one I miss the most however is that the builder pattern can be used to provide what are called "fluent interfaces".
Instead of this:
ProductConfig config = new ProductConfig("Vodka");
config.alcohol = 0.38;
config.size = 0.7;
config.price = 17.99;
Product p = new Product(config);
You can do:
ProductFactory.create()
.drink("Vodka")
.whereAlcohoolLevelIs(0.38)
.inABottleSized(0.7)
.pricedAt(17.99)
.build();
Not everyone like fluent interfaces, but they are definitely a very nice use of the builder pattern (all fluent interfaces should use the builder pattern, but not all builder pattern are fluent interfaces).
Some great Java collections, like the Google collections, makes both very liberal and very good use of "fluent interfaces". I'd pick these any day over your "easier-to-type/less characters" approach : )
The configuration pattern and the builder pattern are functionally equivalent. They both solve the same problems -
Eliminate the need for multiple constructor signatures
Allow fields to only be set during construction
Allow consumers to only set values they care about and have logical defaults for the other values
Anything you want to do in one of these patterns you can do in the other, such as only allowing state to be set with methods that do validation and setting state with encapsulated logic. The only real difference is if you like creating objects with the new key term or if you like calling a .build() method.
What problem do you try to solve with your pattern? The builder pattern is used for objects with many (optional) parameters in order to prevent tons of different constructors or very long ones. It also keeps your object in a consistent state (vs. javabean pattern) during construction.
The difference between builder and "config object" (feels like a good name) is, that you still have to create the object with the same params by constructor or getter/setter. This a) doesnt solve the constructor problem or b) keeps the config object in inconsistent state. Inconsistent states of the config object dont really hurt it but you could pass an unfinished config object as a param. [Michids link to phantom types seem to solve this problem, but that again kills readability (new Foo<TRUE,TRUE, TRUE, FALSE, TRUE> kinda sucks).] Thats the big advantage of the builder pattern: you can validate your params before you create an object and you can return any subtype (acts like a factory).
Config objects are valid for sets of params which are all mandatory. Ive seen this pattern many times in .NET or java before.
Have you considered using builder-builder?
I do think the builder (with prefixes like "With") reads more natrually/fluently.
I personally feel that the builder pattern at first sight offers you cleaner code where these objects are in fact used. On the other hand, not having getters/setters will not be very usable by a lot of frameworks that expect camel case getters/setters. This is a serious draw back I feel.
What I also like with getters/setters is that you clearly see what you are doing: get or set. I feel with the builder I am losing a bit of intuitive clarity here.
I know that many people have read a specific book and that now all of a sudden, the builder pattern has enjoyed the hype, as if it were the new iPhone. However, I am not an early adopter. I only use "the new way" when it really really proves a big time saver on whatever territory, being it performance, maintenance, coding...
My hands-on experience is that I usually am better of with getters/setters and constructors. It allows me to reuse these POJO's for any purpose.
Although I see the purpose of your Config Object, I also think it is even more overhead than the builder, and for what? What is wrong with setters?
Maybe we need to invent a WITH clause:
example, let's say you have
public Class FooBar() {
private String foo;
public void setFoo(String bar) {
this.foo = bar;
}
public String getFoo() {
return this.foo;
}
}
public static void main(String []args) {
FooBar fuBar = new FooBar();
String myBar;
with fuBar {
setFoo("bar");
myBar = getFoo();
}
}
Ah I dunno... I think this may yet result in quicker code writing without all the inner class hassle. Does any one have connections with the Oracle Java guru's?
It doesn't look as clean as using an object with a builder, but you save builder-construction time. And you can still use the class as a regular pojo/bean which can be used in frameworks...
Would you guys actually like this clause or you think it would rather suck?
Cheers
IMO, the builder pattern is much more roboust if you have things like validation, etc.
The builder pattern in your case can be changed to do the following:
Product p = new ProductBuilder("pName").alcohol(0.38).size(0.7).price(17.99).build();
The build() method can do all the validation stuff that is needed for your builder.
The builder pattern also has several design advangates (all of which may not be applicable in your case). For deatils check this question
The main drawback is that it is not in Joshua's book, so drones can't wrap their heads around it.
You are using a simple value object to hold multiple arguments a function(/method/constructor) needs, there is nothing wrong with that, it has been done for ages. As long as we don't have named optional parameters we'll have to devise workarounds like this - it's a shame, not some god damn brilliant inventions from the gods in the Sun.
The real difference is that you expose fields directly. Joshua would never have a public mutable field - but he writes APIs that will be used by millions of people most of which are morons, and the APIs must be safe to evolve for decades to come, and they can allocate many man months just to design a simple class
Who are we to emmulate that?
You should not use the public field, but protected or private. For accesing then you should use the getters and setter to keep the encapsulation..