I have a case when I want to avoid defensive copies, for data which might nevertheless be modified, but is usually simply read, and not written to. So, I'd like to use immutable objects, with functional mutator methods, which is kind of usual (java lombok is able to do it more or less automatically). The way I proceed is the following:
public class Person {
private String name, surname;
public Person(String name, String surname) {....}
// getters...
// and instead of setters
public Person withName(String name) {
Person p= copy(); // create a copy of this...
p.name= name;
return p;
}
public Person copy() {....}
}
So, to get a copy of the person with a different name, I would call
p= new Person("Bar", "Alfred");
...
p= p.withName("Foo");
In practice, the objects are rather large (and I ended up using serialization to avoid the burden of writing the copy code).
Now, while browsing the web, I see a potential concurrency problem with this implementation, as my fields are not final, and thus, concurrent access might see the returned copy, for instance, without the new name change (as there is no warrantee on the order of operation in this context).
Of course, I can't make my fields final, with the current implementation, as I first do a copy, and then change the data in the copy.
So, I'm looking for a good solution for this problem.
I might use volatile, but I feel it's not a good solution.
Another solution would be to use the builder pattern:
class PersonBuilder {
String name, surname; ....
}
public class Person {
private final String name, surname;
public Person(PersonBuilder builder) {...}
private PersonBuilder getBuilder() {
return new PersonBuilder(name, surname);
}
public Person withName(String name) {
PersonBuilder b= getBuilder();
b.setName(name);
return new Person(b);
}
}
Is there any problem here, and above all, is there a more elegant way of doing the same thing ?
I recommend you take a look at Guava's immutable collections, such as immutable list and how they create lists from builders etc.
The idiom is the following:
List<String> list1 = ImmutableList.of("a","b","c"); // factory method
List<String> list2 = ImmutableList.builder() // builder pattern
.add("a")
.add("b")
.add("c")
.build();
List<String> list3 = ... // created by other means
List<String> immutableList3 = ImmutableList.copyOf(list3); // immutable copy, lazy if already immutable
I really like the idiom above. For an entity builder I would take the following approach:
Person johnWayne = Person.builder()
.firstName("John")
.lastName("Wayne")
.dob("05-26-1907")
.build();
Person johnWayneClone = johnWayne.copy() // returns a builder!
.dob("06-25-2014")
.build();
The builder here can be obtained from an existing instance via the copy() method or via a static method on the Person class (a private constructor is recommended) that return a person builder.
Note that the above mimics a little Scala's case classes in that you can create a copy from an existing instance.
Finally, don't forget to follow the guidelines for immutable classes:
make the class final or make all getters final (if the class can be extended);
make all fields final and private;
initialize all fields in the constructor (which can be private if you provide a builder and/or factory methods);
make defensive copies from getters if returning mutable objects (mutable collections, dates, third party classes, etc.).
One possibility is to separate your interfaces surrounding such objects into an immutable variant (providing getters) and a mutable variant (providing getters and setters).
public interface Person {
String getName();
}
public interface MutablePerson extends Person {
void setName(String name);
}
It doesn't solve the mutability of the object per se but it does offer some guarantees that when you pass around the object using the immutable interface reference, you know that the code you're passing this to won't change your object. Obviously you need to control the references to the underlying object and determine the subset of functionality that has control of a reference via the mutable interface.
It doesn't solve the underlying problem and I would favour immutable objects until I definitely need a mutable version. The builder approach works nicely, and you can integrate it within the object to give a modifier thus:
Person newPerson = existingPerson.withAge(30);
Why not make your fields final and your modifier methods directly create new objects?
public class Person {
private final String name, surname;
public Person(String name, String surname) {....}
// getters...
// and instead of setters
public Person withName(String newName) {
return new Person(newName, surname);
}
}
Your problem boils down to this: You want a method that safely publishes an effectively immutable, almost-but-not-quite-faithful copy of an effectively immutable object.
I'd go with the builder solution: It's verbose as all get out, but Eclipse helps with that, and it allows all of the published objects to be actually immutable. Actual immutability makes safe publication a no-brainer.
If I wrote it, it'd look like this:
class Person {
public static final FooType DEFAULT_FOO = ...;
public static final BarType DEFAULT_BAR = ...;
public static final BazType DEFAULT_BAZ = ...;
...
private final FooType foo;
private final BarType bar;
private final BazType baz;
...
private Person(Builder builder) {
this.foo = builder.foo;
this.bar = builder.bar;
this.baz = builder.baz;
...
}
public FooType getFoo() { return foo; }
public BarType getBar() { return bar; }
public BazType getBaz() { return baz; }
...
public Person cloneWith(FooType foo) {
return new Builder(this).setFoo(foo).build();
}
public Person cloneWith(BarType bar) {
return new Builder(this).setBar(bar).build();
}
public Person cloneWith(FooType foo, BarType bar) {
return new Builder(this).setFoo(foo).setBar(bar).build();
}
...
public class Builder{
private FooType foo;
private BarType bar;
private BazType baz;
...
public Builder() {
foo = DEFAULT_FOO;
bar = DEFAULT_BAR;
baz = DEFAULT_BAZ;
...
}
public Builder(Person person) {
foo = person.foo;
bar = person.bar;
baz = person.baz;
...
}
public Builder setFoo(FooType foo) {
this.foo = foo;
return this;
}
public Builder setBar(BarType bar) {
this.bar = bar;
return this;
}
public Builder setBaz(BazType baz) {
this.baz = baz;
return this;
}
...
public Person build() {
return new Person(this);
}
}
}
Depends on how many fields you intend to change. You could make special Changed objects like:
interface Person {
public String getForeName();
public String getSurName();
}
class RealPerson implements Person {
private final String foreName;
private final String surName;
public RealPerson (String foreName, String surName) {
this.foreName = foreName;
this.surName = surName;
}
#Override
public String getForeName() {
return foreName;
}
#Override
public String getSurName() {
return surName;
}
public Person setSurName (String surName) {
return new PersonWithSurnameChanged(this, surName);
}
}
class PersonWithSurnameChanged implements Person {
final Person original;
final String surName;
public PersonWithSurnameChanged (Person original, String surName) {
this.original = original;
this.surName = surName;
}
#Override
public String getForeName() {
return original.getForeName();
}
#Override
public String getSurName() {
return surName;
}
}
This may also mitigate the problem you have with cloning heavy objects.
Related
Just a question RE: Constructor Chaining in subclasses that I can't find a good answer on and I'm confusing myself a bit with.
I'm making a basic little Text Based RPG for some practice and I'm going through my constructors for an abstract class and have the constructors from 0-4 params chained together like below
abstract class Creature {
// Fields
private String name;
private int lifeForce;
private int strength;
private int agility;
// Constructors + Chaining
public Creature() {
this("Unknown")
}
public Creature(String name) {
this(name, 100);
}
public Creature(String name, int lifeForce) {
this(name, lifeForce, 10);
}
public Creature(String name, int lifeForce, int strength) {
this(name, lifeForce, strength, 10);
}
public Creature(String name, int lifeForce, int strength, int agility) {
this.name = name;
this.lifeForce = lifeForce;
this.strength = strength;
this.agility = agility;
}
My confusion is how best to format the constructors of a subclass of creature, for example this simple Person class introduces two new fields. There's definitely too much repetition if I write the constructors like this
// Constructors + Chaining
public Person() {
super("Unknown");
this.skillClass=new Mage();
this.dialogue="...";
}
public Person(String name) {
super(name);
this.skillClass=new Mage();
this.dialogue="...";
} etc etc etc
I suppose I could restrict the constructors to limit the repetition but I'm mostly just wondering if there's good best practice that I'm missing here.
Any and all suggestions welcome and if anyone has any good resources to recommend that go deeper than the usual
Class B extends Class A
examples I'd massively appreciate.
In situations like this one when you need to use multiple constructors with different parameters, it is recommended to use the builder pattern like this :
abstract class Creature {
// Fields
private String name;
private int lifeForce;
private int strength;
private int agility;
private Creature(Builder<?> builder) {
this.name = builder.name;
this.lifeForce = builder.lifeForce;
// Add the other attributes here.
}
public static abstract Builder extends Builder<T extends Builder<T>> {
private String name;
private int lifeForce;
private int strength;
private int agility;
public Builder(//here you put the attributes that you need to have in all instances) {
// here you do the affectations.
}
// now you need to make the functions that set each property :
public Builder lifeForce(int lifeForce) {
this.lifeForce = lifeForce;
return this;
}
// you do the same thing for all the other attributes.
...
public Creature build() {
return new Creature(this);
}
}
}
So for the explanation : This pattern will allow you to create instances of your class by setting only the needed attributes.
As here you have subclasses the builder pattern will be little bit more harder to understand but it is the perfect solution in such situation.
We need to apply the builder pattern also for every subclasse so let's do it for the person class :
public class Person extends Creature {
private int anotherField;
public Person(Builder builder) {
super(builder);
this.anotherField = anotherField;
}
public static Builder extends Creature.Builder<Builder> {
public Builder(//add the fieldHere if it is needed in all class instances) {
// if the field is not mandatory you can omit this constructor but you need to put the function below.
}
public Builder anotherField(int anotherField) {
this.anotherField = anotherField;
}
public Person build() {
return new Person(this);
}
}
Now let me show you how tricky is this solution :
1/ declare person with 2 fields :
Person p1 = Person.Builder().name("name").anotherField(0).build();
2/ declare another one with just one field
Person p2 = Person.Builder().agility(1000).build();
Remark : In these two examples, i supposed that your builders' constructors don't have parameters. If for example the name is mandatory field :
Person p3 = Person.Builder("name").anotherField(0).build();
I wish that you had the idea about using builder pattern.
How should I retain Encapsulation Principle of OOP, when using builder pattern? I mean fact that builder should provide abstraction layer between object and the code that uses it, so that it can be constructed part-by-part, requires either making setter for every parameter of an object that we would normally pass in the constructor. That again may be undesirable in some cases, as I don't want client to be able to modify value that I have to via builder. Example to picture what I mean is below:
public class Cat
{
private string _race;
private string _name;
public Cat()
{
_race = "common";
_name = string.Empty;
}
public void setRace(string race) { _race = race; }
public void setName(string name) { _name = name; }
}
public class CatBuilder
{
private Cat _objectUnderConstruction;
public CatBuilder() { _objectUnderConstruction = new Cat(); }
public CatBuilder WithName(string name)
{
_objectUnderConstruction.setName(name);
return this;
}
public CatBuilder OfRace(string race)
{
_objectUnderConstruction.setRace(race);
return this;
}
}
This is not production code, I wrote it now with presentation in mind, so do not get mad on how it is constructed.
In the example above there is need to set cat's race, as we need that information for the purpose of object filling, so we need to pass info into it. At the same time I don't want anyone to ever change race of my cat during its lifetime (e.g. it would change from egyptian to british in the middle of processing) Normally I would get rid of accessor method, but I need for the builder. This way, encapsulation of data is hurt (because straight get and set aren't encapsulating anything), and I want to avoid it.
This example is simple and I could pass parameter in constructor, but imagine bigger class, where there is a lot of such fields, what in this case? Should I pass some configuration object inside (which is almost like builder, but simpler, hence builder is pointless) or pass the builder itself to the constructor (which is weird, but what do I know)?
How I should do that?
If your builder is tightly-coupled with your class you can make Builder subclass of the object being constructed:
public class Cat
{
private string _race;
private string _name;
public Cat()
{
_race = "common";
_name = string.Empty;
}
private void setRace(string race) { _race = race; }
private void setName(string name) { _name = name; }
public class Builder
{
private Cat _objectUnderConstruction;
public CatBuilder() { _objectUnderConstruction = new Cat(); }
public CatBuilder WithName(string name)
{
_objectUnderConstruction.setName(name);
return this;
}
public CatBuilder OfRace(string race)
{
_objectUnderConstruction.setRace(race);
return this;
}
}
}
This way, you'll be able in Builder to access private fields and methods of Cat and use it like new Cat.Builder().OfRace("").OfName("").Build().
Recently I came into a situation where the builder pattern was very strong, but I had the need to subclass. I looked up some solutions and some suggested generics while others suggested normal subclassing. However, none of the examples I looked at had required fields in order to even begin building an object. I wrote a tiny example to illustrate where I'm getting stuck. At every turn I kept running into a wall of problems where things would return the wrong class, can't override static methods, returning super() returns the wrong data type, etc. I have a feeling there is no way out except excessive use of generics.
What is the correct way to go in this situation?
Tester
import person.Person;
import person.Student;
public class Tester
{
public static void main(String[] args)
{
Person p = Person.builder("Jake", 18).interest("Soccer").build();
// Student s = Student.builder(name, age) <-- It's weird that we still have access to pointless static method
// Student s = Student.builder("Johnny", 24, "Harvard", 3).address("199 Harvard Lane") <-- returns Person builder, not student
Student s = ((Student.Builder)Student.builder("Jack", 19, "NYU", 1).address("Dormitory")).build(); // really bad
}
}
Person Class
package person;
import java.util.ArrayList;
import java.util.List;
public class Person
{
// Required
protected String name;
protected int age;
// Optional
protected List<String> interests = new ArrayList<>();
protected String address = "";
protected Person(String name, int age)
{
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
public List<String> getInterests() { return interests; }
public String getAddress() { return address; }
// person.person does not allow builder construction
// unless all required fields are provided
/* Problem: I have to repeat the constructor fields here, very annoying */
public static Builder builder(String name, int age)
{
Person p = new Person(name, age);
return new Builder(p);
}
public static class Builder
{
Person reference;
protected Builder(Person reference)
{
this.reference = reference;
}
public Builder address(String address)
{
reference.address = address;
return this;
}
public Builder interest(String interest)
{
reference.interests.add(interest);
return this;
}
public Person build()
{
return reference;
}
}
}
Student Class
package person;
import java.util.ArrayList;
import java.util.List;
public class Student extends Person
{
// Required
protected String school;
protected int year;
// Optional
protected List<String> subjects = new ArrayList<>();
// This looks good
public Student(final String name, final int age, final String school, final int year)
{
super(name, age);
this.school = school;
this.year = year;
}
public String getSchool() { return school; }
public int getYear() { return year; }
public List<String> getSubjects() { return subjects; }
/* Here's where my issues are:
* Override doesn't compile on static methods but how else can I describe that I want to
* override this functionality from the Person class?
*
* Extending 'Person' does not enforce that I need to provide 'name', 'age', etc like it would
* if this was a normal design pattern using the 'new' keyword. I have to manually drag fields
* from 'person' and place them here. This would get VERY messy with an additional class
*
* User can STILL call the Person builder on a Student object, which makes no sense. */
/*#Override*/ public static Builder builder(String name, int age, String school, int year)
{
Student s = new Student(name, age, school, year);
return new Builder(s);
}
public static class Builder extends Person.Builder
{
// Student reference; <--- this should not be needed since we already
// have a variable for this purpose from 'Person.Builder'
public Builder(final Student reference)
{
super(reference);
}
/* Things begins to get very messy here */
public Builder subject(String subject)
{
((Student)reference).subjects.add(subject);
// I guess I could replace the reference with a student one, but
// I feel like that infringes on calling super() builder since we do the work twice.
return this;
}
#Override public Student build()
{
// I can either cast here or
// rewrite 'return reference' every time.
// Seems to infringe a bit on subclassing.
return (Student)super.build();
}
}
}
What you write here :
Student s = ((Student.Builder)Student.builder("Jack", 19, "NYU", 1).address("Dormitory")).build(); // really bad
is indeed not very natural and you should not need to cast.
We expect rather something like :
Student s = Student.builder("Jack", 19, "NYU", 1).address("Dormitory")).build();
Besides all casts you did in the implementation of Student.Builder are also noise and statements that may fail at runtime :
/* Things begins to get very messy here */
public Builder subject(String subject) {
((Student)reference).subjects.add(subject);
return this;
}
#Override public Student build() {
return (Student)super.build();
}
Your main issue is the coupling between the Builder classes and the building methods.
A important thing to consider is that at compile time, the method binding (method selected by the compiler) is performed according to the declared type of the target of the invocation and the declared type of its arguments.
The instantiated type is considered only at runtime as the dynamic binding is applied: invoking the method bounded at compile time on the runtime object.
So this overriding defined in Student.Builder is not enough :
#Override public Student build() {
return (Student)super.build();
}
As you invoke :
Student.builder("Jack", 19, "NYU", 1).address("Dormitory").build();
At compile time, address("Dormitory") returns a variable typed as Person.Builder as the method is defined in Person.Builder :
public Builder address(String address){
reference.address = address;
return this;
}
and it not overriden in Student.Builder.
And at compile time, invoking build() on a variable declared as Person.Builder returns a object with as declared type a Person as the method is declared in Person.Builder as :
public Person build(){
return reference;
}
Of course at runtime, the returned object will be a Student as
Student.builder("Jack", 19, "NYU", 1) creates under the hood a Student and not a Person.
To avoid cast to Student.builder both from the implementation and the client side, favor composition over inheritancy :
public static class Builder {
Person.Builder personBuilder;
private Student reference;
public Builder(final Student reference) {
this.reference = reference;
personBuilder = new Person.Builder(reference);
}
public Builder subject(String subject) {
reference.subjects.add(subject);
return this;
}
// delegation to Person.Builder but return Student.Builder
public Builder interest(String interest) {
personBuilder.interest(interest);
return this;
}
// delegation to Person.Builder but return Student.Builder
public Builder address(String address) {
personBuilder.address(address);
return this;
}
public Student build() {
return (Student) personBuilder.build();
}
}
You can now write :
Student s = Student.builder("Jack", 19, "NYU", 1)
.address("Dormitory")
.build();
or even that :
Student s2 = Student.builder("Jack", 19, "NYU", 1)
.interest("Dance")
.address("Dormitory")
.build();
Composition introduces generally more code as inheritancy but it makes the code
both more robust and adaptable.
As a side note, your actual issue is enough close to another question I answered 1 month ago.
The question and its answers may interest you.
A few thoughts as background
Static methods are not so great,
they make unit testing more difficult.
It is fine to put the builder as a static, nested class, but if you are using a builder to construct a class you should make the constructor not-public.
I prefer to have the builder be a separate class in the same package and to make the constructor (of the class that is created by the builder) package access.
Limit the builder constructor parameters.
I'm not a fan of using a class hierarchy for builders.
The Person and Student classes each have a builder.
Some Code
public class PersonBuilder
{
private String address;
private int age;
private final List<String> interestList;
private String name;
public PersonBuilder()
{
interestList = new LinkedList<>();
}
public void addInterest(
final String newValue)
{
// StringUtils is an apache utility.
if (StringUtils.isNotBlank(newValue))
{
interestList.add(newValue);
}
return this;
}
public Person build()
{
// perform validation here.
// check for required values: age and name.
// send all parameters in the constructor. it's not public, so that is fine.
return new Person(address, age, interestList, name);
}
public PersonBuilder setAddress(
final String newValue)
{
address = newValue;
return this;
}
public PersonBuilder setAge(
final int newValue)
{
age = newValue;
return this;
}
public PersonBuilder setInterestList(
final List<String> newValue)
{
interestList.clear();
if (CollectionUtils.isNotEmpty(newValue))
{
interestList.addAll(newValue);
}
return this;
}
public PersonBuilder setName(
final String newValue)
{
name = newValue;
return this;
}
}
public class Person
{
private Person()
{
}
Person(
final String addressValue,
final int ageValue,
final List<String> interestListValue,
final String name)
{
// set stuff.
// handle null for optional parameters.
}
// create gets or the fields, but do not create sets. Only the builder can set values in the class.
}
I'm not sure if a class object to transfer data will be more efficient than an object array.
My goal is to know which option is the most efficient and which option is the best practice.
Consider this is a web application served to thousands of users.
Here the two sample cases:
A)
Model.java
public class Model {
public Contact getContact(long id)
{
// some logic
return new Contact(...);
}
}
Contact.java
public class Contact
{
private long id;
private String name;
private String surname;
private String email;
private int session;
private byte[] avatar;
// Constructor
public Contact(long id, String name, ...)
// Getters and Setters
}
B)
Model.java
public class Model {
public Object[] getContact(long id)
{
// some logic
Object[] myReturningContact = new Object[n];
myReturningContact[0] = rs.getLong("id");
// ...
myReturningContact[n] = rs.getBytes("avatar");
return myReturningContact;
}
}
SomeController.java
public class SomeController
{
public void someAction()
{
// Option A
this.setSomeTextTo(contact.getName());
// Option B
this.setSomeTextTo(String.valueOf(returningObject[n]));
}
}
Option A is best practice, unless you have a speed requirement that it can't meet, and Option B can.
Note that Option A will probably be a little faster if you make your fields public and final and don't use getters.
Also note that if you have many primitive fields, the cost of boxing and unboxing will slow down Option B, as may String.valueOf on Strings
I have an enum type (say for arguments sake CarModel), used throughout an application (numerous classes).
public enum CarModel {
DIABLO,
P911,
DB7;
}
I have various methods that use this CarModel enum type in different ways, and each has a switch statement to set some String variable depending on the enum type, before going on to do other stuff. (e.g. set the Manufacturer of some model, or set the country of origin etc. These results are static at runtime)
The issue is, if I want to add a new model to the enum, I'd need to go to each method, and extend/modify the switch statement to handle its existence. This could easily lead to human error, and/or code duplication (if various methods use the same switch statements).
Rather than using switch statements all-over, I would like to have static methods, that could be edited in a single location, and would allow for behaviour similar to the following:
String country = CarModel.DIABLO.getCountry() // returns Italy
String manufacturer = CarModel.P911.getManufacturer() // returns Porsche
Is this possible with an enum, (and is an enum even the 'correct' way to do this?
You can do something like this.
public enum CarModel {
DIABLO("Lamborghini", "Italy"),
P911("Porsche", "Germany");
private String manufacturer;
private String country;
private CarModel(String manufacturer, String country) {
this.manufacturer = manufacturer;
this.country = country;
}
public String getManufacturer() {
return manufacturer;
}
public String getCountry() {
return country;
}
}
Yes, absolutely. Enums can have their own methods, and those methods can be value-specific. It looks like this:
enum CarModel {
P911 {
public String getManufacturer() { return "Porsche"; }
},
DB7 {
public String getManufacturer() { return "Aston Martin"; }
},
...
public abstract String getManufacturer();
}
You can add more methods, of course.
If you're going to use enums, I would suggest an abstract method declared in the enum, and then a provided implementation for each enum instance.
That way you don't have switch statements everywhere (from which you can easily omit cases) and you have a more reliable and OO-styled polymorphic approach.
abstract public int getEngineSize();
DIABLO {
public int getEngineSize() {
return 6.3; // whatever it really is...
}
}
See here for more examples/discussions etc.
I would suggest adding this information directly into your enum.
Like this:
public enum CarModel {
DIABLO("Lambo"),
P911 ("Porsche");
private String manufacturer;
private CarModel(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getManufacturer() {
return manufacturer;
}
}
and in the class you'd only have to use the getManufacturer method
Moreover enums can implement an interface. You can add some get() methods like getMaxSpeed() or getWeight().
Interface can look like
interface car{
public int getMaxSpeed();
public int getWeight();
}
Yes, this is quite easy to do:
public enum CarModel {
DIABLO("rod"),
P911("jane"),
DB7("freddy");
private String name;
CarModel(String name){
this.name = name;
}
public String getName() {
return name;
}
}
Haha, I recommend you to use "Factory" Design Pattern.
you can make a CarFactory(), to produce new model car.
http://en.wikipedia.org/wiki/Factory_method_pattern