Is it correct to have static factory method to get a new instance with one field updated?
up vote
1
down vote
favorite
I think the title is self-descriptive but I will give an example to elaborate on my question. I have a DTO
class with few fields (a CarDataTransferObj
class in my example). In another class (let's call it class A
) I need to create a new instance of that object few times, but with only one field updated (length
field in my example). Given DTO
must be immutable in class A
. As there is "many" fields in the class CarDataTransferObj
, I thought about following approach (to avoid repeating code in class A
):
@Builder
public class CarDataTransferObj
private Integer id;
private String color;
private String manufacturer;
private String model;
private String uniqueIdNr;
private Integer nrOfDoors;
private EngineType engineType;
private Integer length;
private Integer safetyLevel;
public static CarDataTransferObj newInstanceWithUpdatedLength(final CarDataTransferObj car, final Integer newLength)
return CarDataTransferObj.builder()
.id(car.getId())
.color(car.getColor())
.manufacturer(car.getManufacturer())
.model(car.getModel())
.uniqueIdNr(car.getUniqueIdNr())
.nrOfDoors(car.getNrOfDoors())
.engineType(car.getEngineType())
.length(newLength)
.safetyLevel(car.getSafetyLevel())
.build();
For me it smells like a little anti-pattern usage of static factory methods. I am not sure whether it's acceptable or not, hence the question.
Is using static factory method in the presented way an anti-pattern, and should be avoided ?
java spring design-patterns
add a comment |
up vote
1
down vote
favorite
I think the title is self-descriptive but I will give an example to elaborate on my question. I have a DTO
class with few fields (a CarDataTransferObj
class in my example). In another class (let's call it class A
) I need to create a new instance of that object few times, but with only one field updated (length
field in my example). Given DTO
must be immutable in class A
. As there is "many" fields in the class CarDataTransferObj
, I thought about following approach (to avoid repeating code in class A
):
@Builder
public class CarDataTransferObj
private Integer id;
private String color;
private String manufacturer;
private String model;
private String uniqueIdNr;
private Integer nrOfDoors;
private EngineType engineType;
private Integer length;
private Integer safetyLevel;
public static CarDataTransferObj newInstanceWithUpdatedLength(final CarDataTransferObj car, final Integer newLength)
return CarDataTransferObj.builder()
.id(car.getId())
.color(car.getColor())
.manufacturer(car.getManufacturer())
.model(car.getModel())
.uniqueIdNr(car.getUniqueIdNr())
.nrOfDoors(car.getNrOfDoors())
.engineType(car.getEngineType())
.length(newLength)
.safetyLevel(car.getSafetyLevel())
.build();
For me it smells like a little anti-pattern usage of static factory methods. I am not sure whether it's acceptable or not, hence the question.
Is using static factory method in the presented way an anti-pattern, and should be avoided ?
java spring design-patterns
It looks like you're using Lombok. They actually have an experimental feature exactly for such purpose projectlombok.org/features/experimental/Wither.
– yegodm
Nov 11 at 1:25
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I think the title is self-descriptive but I will give an example to elaborate on my question. I have a DTO
class with few fields (a CarDataTransferObj
class in my example). In another class (let's call it class A
) I need to create a new instance of that object few times, but with only one field updated (length
field in my example). Given DTO
must be immutable in class A
. As there is "many" fields in the class CarDataTransferObj
, I thought about following approach (to avoid repeating code in class A
):
@Builder
public class CarDataTransferObj
private Integer id;
private String color;
private String manufacturer;
private String model;
private String uniqueIdNr;
private Integer nrOfDoors;
private EngineType engineType;
private Integer length;
private Integer safetyLevel;
public static CarDataTransferObj newInstanceWithUpdatedLength(final CarDataTransferObj car, final Integer newLength)
return CarDataTransferObj.builder()
.id(car.getId())
.color(car.getColor())
.manufacturer(car.getManufacturer())
.model(car.getModel())
.uniqueIdNr(car.getUniqueIdNr())
.nrOfDoors(car.getNrOfDoors())
.engineType(car.getEngineType())
.length(newLength)
.safetyLevel(car.getSafetyLevel())
.build();
For me it smells like a little anti-pattern usage of static factory methods. I am not sure whether it's acceptable or not, hence the question.
Is using static factory method in the presented way an anti-pattern, and should be avoided ?
java spring design-patterns
I think the title is self-descriptive but I will give an example to elaborate on my question. I have a DTO
class with few fields (a CarDataTransferObj
class in my example). In another class (let's call it class A
) I need to create a new instance of that object few times, but with only one field updated (length
field in my example). Given DTO
must be immutable in class A
. As there is "many" fields in the class CarDataTransferObj
, I thought about following approach (to avoid repeating code in class A
):
@Builder
public class CarDataTransferObj
private Integer id;
private String color;
private String manufacturer;
private String model;
private String uniqueIdNr;
private Integer nrOfDoors;
private EngineType engineType;
private Integer length;
private Integer safetyLevel;
public static CarDataTransferObj newInstanceWithUpdatedLength(final CarDataTransferObj car, final Integer newLength)
return CarDataTransferObj.builder()
.id(car.getId())
.color(car.getColor())
.manufacturer(car.getManufacturer())
.model(car.getModel())
.uniqueIdNr(car.getUniqueIdNr())
.nrOfDoors(car.getNrOfDoors())
.engineType(car.getEngineType())
.length(newLength)
.safetyLevel(car.getSafetyLevel())
.build();
For me it smells like a little anti-pattern usage of static factory methods. I am not sure whether it's acceptable or not, hence the question.
Is using static factory method in the presented way an anti-pattern, and should be avoided ?
java spring design-patterns
java spring design-patterns
asked Nov 11 at 0:29
user3529850
398316
398316
It looks like you're using Lombok. They actually have an experimental feature exactly for such purpose projectlombok.org/features/experimental/Wither.
– yegodm
Nov 11 at 1:25
add a comment |
It looks like you're using Lombok. They actually have an experimental feature exactly for such purpose projectlombok.org/features/experimental/Wither.
– yegodm
Nov 11 at 1:25
It looks like you're using Lombok. They actually have an experimental feature exactly for such purpose projectlombok.org/features/experimental/Wither.
– yegodm
Nov 11 at 1:25
It looks like you're using Lombok. They actually have an experimental feature exactly for such purpose projectlombok.org/features/experimental/Wither.
– yegodm
Nov 11 at 1:25
add a comment |
4 Answers
4
active
oldest
votes
up vote
2
down vote
accepted
In my searching, I didn't come across anyone calling this1 an anti-pattern.
However, it is clear that if you try to do this using a classic builder that is not specifically implemented to support this mode of operation .... it won't work. For instance, the example CarBuilderImpl
in the Wikipedia article on the Builder design pattern puts the state into an eagerly created Car
instance. The build()
method simply returns that object. If you tried to reuse that builder in the way that you propose, you would end up modifying a Car
that has already been built.
There is another problem you would need to worry about. In we modified the Wikipedia CarBuilder
example to add actual wheels (rather than a number of wheels) to the Car
being built, we have to worry about creating cars that share the same wheels.
You could address these things in a builder implementation, but it is unclear whether the benefits out-weigh the costs.
If you then transfer this thinking to doing this using a factory method, you come to a slightly different conclusion.
If you are doing this as a "one-off", that's probably OK. You have a specific need, the code is clunky ... but so is the problem.
If you needed to do this for lots of different parameters, or combinations of parameters, this is not going to scale.
If the objects that are created are mutable, then this approach is could be problematic in a multi-threaded environment depending on how you control access to the objects you are using as templates.
1 - There are no clear measurable criteria for whether something is an anti-pattern or not. It is a matter of opinion. Admittedly, for many anti-patterns, there will be wide-scale agreement on that opinion.
Related: What is an anti-pattern?
– jaco0646
Nov 13 at 20:21
add a comment |
up vote
2
down vote
It seems a little inefficient to construct an entirely new instance via a builder every time you want to make a new copy with a small modification. More significantly, it sounds like the places where you need the class to be immutable are isolated to places like class A. Why not try something like this:
public interface ICarDataTransferObject
public Integer GetId();
public String GetColor();
public String GetManufacturer();
public String GetModel();
public String GetUUID();
public Integer GetDoorCount();
public EngineType GetEngineType();
public Integer GetLength();
public Integer GetSafteyLevel();
public class CarDataTransferObject Implements ICarDataTransferObject
private Integer _id;
private String _color;
private String _manufacturer;
private String _model;
private String _uniqueIdNr;
private Integer _nrOfDoors;
private EngineType _engineType;
private Integer _length;
private Integer _safetyLevel;
public Integer GetId() return _id;
public void SetId(Integer id) _id = id;
public String GetColor() return _color;
public void SetColor(String color) _color = color;
public String GetManufacturer() return _manufacturer;
public void SetManufacturer(String manufacturer) _manufacturer = manufacturer;
public String GetModel() return _model;
public void SetModel(String model) _model = model;
public String GetUUID() return _uniqueIdNr;
public void SetUUID(String uuid) _uniqueIdNr = uuid;
public Integer GetDoorCount() return _nrOfDoors;
public void SetDoorCount(Integer count) _nrOfDoors = count;
public EngineType GetEngineType() return _engineType;
public void SetEngineType(EngineType et) _engineType = et;
public Integer GetLength() return _length;
public void SetLength(Integer length) _length = length;
public Integer GetSafteyLevel() return _safetyLevel;
public void SetSafteyLevel(Integer level) _safteyLevel = level;
public CarDataTransferObject()
public CarDataTransferObject(ICarDataTransferObject other) ...
public ReadOnlyCarDataTransferObject AsReadOnly()
return ReadOnlyCarDataTransferObject (this);
}
public class ReadOnlyCarDataTransferObject Implements ICarDataTransferObject
private ICarDataTransferObject _dto = null;
public Integer GetId() return _dto.GetId();
public String GetColor() return _dto.GetColor();
public String GetManufacturer() return _dto.GetManufacturer();
public String GetModel() return _dto.GetModel();
public String GetUUID() return _dto.GetUUID();
public Integer GetDoorCount() return _dto.GetDoorCount();
public EngineType GetEngineType() return _dto.GetEngineType();
public Integer GetLength() return _dto.GetLength();
public Integer GetSafteyLevel() return _dto.GetSafteyLevel;
public ReadOnlyCarDataTransferObject (ICarDataTransferObject other)
_dto = other;
Now when you want class A to have a copy no one can modify, just use the copy constructor and only expose a ReadOnly version of that copy.
public class A
ICarDataTransferObject _dto;
ReadOnlyCarDataTransferObject _readOnlyDTO;
public ICarDataTransferObject GetDTO() return _readOnlyDTO;
public A(ICarDataTransferObject dto)
_dto = new CarDataTransferObject(dto);
_readOnlyDTO = new ReadOnlyCarDataTransferObject(_dto);
You commonly see this approach in .NET applications.
Why the down vote?
– Ryan Pierce Williams
Nov 11 at 1:26
1
It wasn't by me, if it matters. I will up-vote. Thank you.
– user3529850
Nov 11 at 1:29
haha, thanks :)
– Ryan Pierce Williams
Nov 11 at 1:29
add a comment |
up vote
1
down vote
While it is debatable whether your static method is an anti-pattern or not, it surely won't scale for combinations of different attributes. Nonetheless, even if it's not an anti-pattern, I think there is a better way to accomplish what you need.
There's a variant of the traditional builder pattern that, instead of creating a new empty builder, accepts an already built object and creates an already initialized builder. Once you create the builder this way, you simply change the length
attribute in the builder. Finally, build the object. In plain code (no Lombok, sorry) it could be like this:
public class CarDataTransferObj
private Integer id;
private String color;
// other attributes omitted for brevity
private Integer length;
// Private constructor for builder
private CarDataTransferObj(Builder builder)
this.id = builder.id;
this.color = builder.color;
this.length = builder.length;
// Traditional factory method to create and return builder
public static Builder builder()
return new Builder();
// Factory method to create and return builder initialized from an instance
public static Builder builder(CarDataTransferObj car)
Builder builder = builder();
builder.id = car.id;
builder.color = car.color;
builder.length = car.length;
return builder;
// getters
public static class Builder
private Integer id;
private String color;
private Integer length;
private Builder()
public Builder withId(Integer id) this.id = id; return this;
public Builder withColor(String color) this.color = color; return this;
public Builder withLength(Integer length) this.length = length; return this;
public CarDataTransferObj build()
return new CarDataTransferObj(this);
Now with all this infrastructure in place, you can do what you want as easy as:
CarDataTransferObj originalCar = ... // get the original car from somewhere
CarDataTransferObj newCar = CarDataTransferObj.builder(originalCar)
.withLength(newLength)
.build();
This approach has the advantage that it scales well (it can be used to change any combination of parameters). Maybe all this builder's code seems boilerplate, but I use an IntelliJ plugin to create the builder with two keystrokes (including the variant factory method that accepts a built instance to create an initialized builder).
add a comment |
up vote
0
down vote
I'm still new to java but..
I guess making a copy method which takes the CarDataTransferObj object variables and sets their values to another CarDataTransferObj object variables and changing the the length using it's setter method would be better idea
Example:
public class CarDataTransferObj
private Integer id;
private String color;
private String manufacturer;
private String model;
private String uniqueIdNr;
private Integer nrOfDoors;
private EngineType engineType;
private Integer length;
private Integer safetyLevel;
public void Copy(CarDataTransferObj copy) //Could add another parameter here to be the new length
copy.setId(id);
copy.set(color);
copy.setManufacturer(manufacturer);
copy.setModel(model);
copy.setUniqueIdNr(uniqueIdNr));
copy.setNrOfDoors(nrOfDoors));
copy.setEngineType(engineType));
copy.setLength(length);
copy.setSafetyLevel(safetyLevel));
public class SomeOtherClass
CarDataTransferObj car1 = new CarDataTransferObj(); //Using this way made you able to use the constructor for a more useful thing
//You set the variables you want for car1 here
CarDataTransferObj car2 = new CarDataTransferObj();
car1.Copy(car2)
car2.setLength(newLength) //Set the new length here
Couple things here: 1. You are using a bunch of setter methods you didn't define (but we know what you mean). 2. How do you ensure that in class A no one can modify the DTO? I defined a ReadOnlyCarTransferObject in my answer to solve this.
– Ryan Pierce Williams
Nov 11 at 1:35
I actually missed that part...but i think that would be declaring the setters private. And good idea to make a ReadOnly instance btw
– Omar Abdul'Azeez
Nov 11 at 2:11
If the setters were private then SomeOtherClass wouldn't be able to modify the length ;)
– Ryan Pierce Williams
Nov 11 at 2:30
@Ryan I guess 8 hours of debugging messed with my head....i thought you would never say this because it can through car1.varName but now i realized they have to be private
– Omar Abdul'Azeez
Nov 11 at 2:43
haha, no worries :)
– Ryan Pierce Williams
Nov 11 at 2:45
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
In my searching, I didn't come across anyone calling this1 an anti-pattern.
However, it is clear that if you try to do this using a classic builder that is not specifically implemented to support this mode of operation .... it won't work. For instance, the example CarBuilderImpl
in the Wikipedia article on the Builder design pattern puts the state into an eagerly created Car
instance. The build()
method simply returns that object. If you tried to reuse that builder in the way that you propose, you would end up modifying a Car
that has already been built.
There is another problem you would need to worry about. In we modified the Wikipedia CarBuilder
example to add actual wheels (rather than a number of wheels) to the Car
being built, we have to worry about creating cars that share the same wheels.
You could address these things in a builder implementation, but it is unclear whether the benefits out-weigh the costs.
If you then transfer this thinking to doing this using a factory method, you come to a slightly different conclusion.
If you are doing this as a "one-off", that's probably OK. You have a specific need, the code is clunky ... but so is the problem.
If you needed to do this for lots of different parameters, or combinations of parameters, this is not going to scale.
If the objects that are created are mutable, then this approach is could be problematic in a multi-threaded environment depending on how you control access to the objects you are using as templates.
1 - There are no clear measurable criteria for whether something is an anti-pattern or not. It is a matter of opinion. Admittedly, for many anti-patterns, there will be wide-scale agreement on that opinion.
Related: What is an anti-pattern?
– jaco0646
Nov 13 at 20:21
add a comment |
up vote
2
down vote
accepted
In my searching, I didn't come across anyone calling this1 an anti-pattern.
However, it is clear that if you try to do this using a classic builder that is not specifically implemented to support this mode of operation .... it won't work. For instance, the example CarBuilderImpl
in the Wikipedia article on the Builder design pattern puts the state into an eagerly created Car
instance. The build()
method simply returns that object. If you tried to reuse that builder in the way that you propose, you would end up modifying a Car
that has already been built.
There is another problem you would need to worry about. In we modified the Wikipedia CarBuilder
example to add actual wheels (rather than a number of wheels) to the Car
being built, we have to worry about creating cars that share the same wheels.
You could address these things in a builder implementation, but it is unclear whether the benefits out-weigh the costs.
If you then transfer this thinking to doing this using a factory method, you come to a slightly different conclusion.
If you are doing this as a "one-off", that's probably OK. You have a specific need, the code is clunky ... but so is the problem.
If you needed to do this for lots of different parameters, or combinations of parameters, this is not going to scale.
If the objects that are created are mutable, then this approach is could be problematic in a multi-threaded environment depending on how you control access to the objects you are using as templates.
1 - There are no clear measurable criteria for whether something is an anti-pattern or not. It is a matter of opinion. Admittedly, for many anti-patterns, there will be wide-scale agreement on that opinion.
Related: What is an anti-pattern?
– jaco0646
Nov 13 at 20:21
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
In my searching, I didn't come across anyone calling this1 an anti-pattern.
However, it is clear that if you try to do this using a classic builder that is not specifically implemented to support this mode of operation .... it won't work. For instance, the example CarBuilderImpl
in the Wikipedia article on the Builder design pattern puts the state into an eagerly created Car
instance. The build()
method simply returns that object. If you tried to reuse that builder in the way that you propose, you would end up modifying a Car
that has already been built.
There is another problem you would need to worry about. In we modified the Wikipedia CarBuilder
example to add actual wheels (rather than a number of wheels) to the Car
being built, we have to worry about creating cars that share the same wheels.
You could address these things in a builder implementation, but it is unclear whether the benefits out-weigh the costs.
If you then transfer this thinking to doing this using a factory method, you come to a slightly different conclusion.
If you are doing this as a "one-off", that's probably OK. You have a specific need, the code is clunky ... but so is the problem.
If you needed to do this for lots of different parameters, or combinations of parameters, this is not going to scale.
If the objects that are created are mutable, then this approach is could be problematic in a multi-threaded environment depending on how you control access to the objects you are using as templates.
1 - There are no clear measurable criteria for whether something is an anti-pattern or not. It is a matter of opinion. Admittedly, for many anti-patterns, there will be wide-scale agreement on that opinion.
In my searching, I didn't come across anyone calling this1 an anti-pattern.
However, it is clear that if you try to do this using a classic builder that is not specifically implemented to support this mode of operation .... it won't work. For instance, the example CarBuilderImpl
in the Wikipedia article on the Builder design pattern puts the state into an eagerly created Car
instance. The build()
method simply returns that object. If you tried to reuse that builder in the way that you propose, you would end up modifying a Car
that has already been built.
There is another problem you would need to worry about. In we modified the Wikipedia CarBuilder
example to add actual wheels (rather than a number of wheels) to the Car
being built, we have to worry about creating cars that share the same wheels.
You could address these things in a builder implementation, but it is unclear whether the benefits out-weigh the costs.
If you then transfer this thinking to doing this using a factory method, you come to a slightly different conclusion.
If you are doing this as a "one-off", that's probably OK. You have a specific need, the code is clunky ... but so is the problem.
If you needed to do this for lots of different parameters, or combinations of parameters, this is not going to scale.
If the objects that are created are mutable, then this approach is could be problematic in a multi-threaded environment depending on how you control access to the objects you are using as templates.
1 - There are no clear measurable criteria for whether something is an anti-pattern or not. It is a matter of opinion. Admittedly, for many anti-patterns, there will be wide-scale agreement on that opinion.
edited Nov 11 at 1:30
answered Nov 11 at 1:05
Stephen C
508k69554906
508k69554906
Related: What is an anti-pattern?
– jaco0646
Nov 13 at 20:21
add a comment |
Related: What is an anti-pattern?
– jaco0646
Nov 13 at 20:21
Related: What is an anti-pattern?
– jaco0646
Nov 13 at 20:21
Related: What is an anti-pattern?
– jaco0646
Nov 13 at 20:21
add a comment |
up vote
2
down vote
It seems a little inefficient to construct an entirely new instance via a builder every time you want to make a new copy with a small modification. More significantly, it sounds like the places where you need the class to be immutable are isolated to places like class A. Why not try something like this:
public interface ICarDataTransferObject
public Integer GetId();
public String GetColor();
public String GetManufacturer();
public String GetModel();
public String GetUUID();
public Integer GetDoorCount();
public EngineType GetEngineType();
public Integer GetLength();
public Integer GetSafteyLevel();
public class CarDataTransferObject Implements ICarDataTransferObject
private Integer _id;
private String _color;
private String _manufacturer;
private String _model;
private String _uniqueIdNr;
private Integer _nrOfDoors;
private EngineType _engineType;
private Integer _length;
private Integer _safetyLevel;
public Integer GetId() return _id;
public void SetId(Integer id) _id = id;
public String GetColor() return _color;
public void SetColor(String color) _color = color;
public String GetManufacturer() return _manufacturer;
public void SetManufacturer(String manufacturer) _manufacturer = manufacturer;
public String GetModel() return _model;
public void SetModel(String model) _model = model;
public String GetUUID() return _uniqueIdNr;
public void SetUUID(String uuid) _uniqueIdNr = uuid;
public Integer GetDoorCount() return _nrOfDoors;
public void SetDoorCount(Integer count) _nrOfDoors = count;
public EngineType GetEngineType() return _engineType;
public void SetEngineType(EngineType et) _engineType = et;
public Integer GetLength() return _length;
public void SetLength(Integer length) _length = length;
public Integer GetSafteyLevel() return _safetyLevel;
public void SetSafteyLevel(Integer level) _safteyLevel = level;
public CarDataTransferObject()
public CarDataTransferObject(ICarDataTransferObject other) ...
public ReadOnlyCarDataTransferObject AsReadOnly()
return ReadOnlyCarDataTransferObject (this);
}
public class ReadOnlyCarDataTransferObject Implements ICarDataTransferObject
private ICarDataTransferObject _dto = null;
public Integer GetId() return _dto.GetId();
public String GetColor() return _dto.GetColor();
public String GetManufacturer() return _dto.GetManufacturer();
public String GetModel() return _dto.GetModel();
public String GetUUID() return _dto.GetUUID();
public Integer GetDoorCount() return _dto.GetDoorCount();
public EngineType GetEngineType() return _dto.GetEngineType();
public Integer GetLength() return _dto.GetLength();
public Integer GetSafteyLevel() return _dto.GetSafteyLevel;
public ReadOnlyCarDataTransferObject (ICarDataTransferObject other)
_dto = other;
Now when you want class A to have a copy no one can modify, just use the copy constructor and only expose a ReadOnly version of that copy.
public class A
ICarDataTransferObject _dto;
ReadOnlyCarDataTransferObject _readOnlyDTO;
public ICarDataTransferObject GetDTO() return _readOnlyDTO;
public A(ICarDataTransferObject dto)
_dto = new CarDataTransferObject(dto);
_readOnlyDTO = new ReadOnlyCarDataTransferObject(_dto);
You commonly see this approach in .NET applications.
Why the down vote?
– Ryan Pierce Williams
Nov 11 at 1:26
1
It wasn't by me, if it matters. I will up-vote. Thank you.
– user3529850
Nov 11 at 1:29
haha, thanks :)
– Ryan Pierce Williams
Nov 11 at 1:29
add a comment |
up vote
2
down vote
It seems a little inefficient to construct an entirely new instance via a builder every time you want to make a new copy with a small modification. More significantly, it sounds like the places where you need the class to be immutable are isolated to places like class A. Why not try something like this:
public interface ICarDataTransferObject
public Integer GetId();
public String GetColor();
public String GetManufacturer();
public String GetModel();
public String GetUUID();
public Integer GetDoorCount();
public EngineType GetEngineType();
public Integer GetLength();
public Integer GetSafteyLevel();
public class CarDataTransferObject Implements ICarDataTransferObject
private Integer _id;
private String _color;
private String _manufacturer;
private String _model;
private String _uniqueIdNr;
private Integer _nrOfDoors;
private EngineType _engineType;
private Integer _length;
private Integer _safetyLevel;
public Integer GetId() return _id;
public void SetId(Integer id) _id = id;
public String GetColor() return _color;
public void SetColor(String color) _color = color;
public String GetManufacturer() return _manufacturer;
public void SetManufacturer(String manufacturer) _manufacturer = manufacturer;
public String GetModel() return _model;
public void SetModel(String model) _model = model;
public String GetUUID() return _uniqueIdNr;
public void SetUUID(String uuid) _uniqueIdNr = uuid;
public Integer GetDoorCount() return _nrOfDoors;
public void SetDoorCount(Integer count) _nrOfDoors = count;
public EngineType GetEngineType() return _engineType;
public void SetEngineType(EngineType et) _engineType = et;
public Integer GetLength() return _length;
public void SetLength(Integer length) _length = length;
public Integer GetSafteyLevel() return _safetyLevel;
public void SetSafteyLevel(Integer level) _safteyLevel = level;
public CarDataTransferObject()
public CarDataTransferObject(ICarDataTransferObject other) ...
public ReadOnlyCarDataTransferObject AsReadOnly()
return ReadOnlyCarDataTransferObject (this);
}
public class ReadOnlyCarDataTransferObject Implements ICarDataTransferObject
private ICarDataTransferObject _dto = null;
public Integer GetId() return _dto.GetId();
public String GetColor() return _dto.GetColor();
public String GetManufacturer() return _dto.GetManufacturer();
public String GetModel() return _dto.GetModel();
public String GetUUID() return _dto.GetUUID();
public Integer GetDoorCount() return _dto.GetDoorCount();
public EngineType GetEngineType() return _dto.GetEngineType();
public Integer GetLength() return _dto.GetLength();
public Integer GetSafteyLevel() return _dto.GetSafteyLevel;
public ReadOnlyCarDataTransferObject (ICarDataTransferObject other)
_dto = other;
Now when you want class A to have a copy no one can modify, just use the copy constructor and only expose a ReadOnly version of that copy.
public class A
ICarDataTransferObject _dto;
ReadOnlyCarDataTransferObject _readOnlyDTO;
public ICarDataTransferObject GetDTO() return _readOnlyDTO;
public A(ICarDataTransferObject dto)
_dto = new CarDataTransferObject(dto);
_readOnlyDTO = new ReadOnlyCarDataTransferObject(_dto);
You commonly see this approach in .NET applications.
Why the down vote?
– Ryan Pierce Williams
Nov 11 at 1:26
1
It wasn't by me, if it matters. I will up-vote. Thank you.
– user3529850
Nov 11 at 1:29
haha, thanks :)
– Ryan Pierce Williams
Nov 11 at 1:29
add a comment |
up vote
2
down vote
up vote
2
down vote
It seems a little inefficient to construct an entirely new instance via a builder every time you want to make a new copy with a small modification. More significantly, it sounds like the places where you need the class to be immutable are isolated to places like class A. Why not try something like this:
public interface ICarDataTransferObject
public Integer GetId();
public String GetColor();
public String GetManufacturer();
public String GetModel();
public String GetUUID();
public Integer GetDoorCount();
public EngineType GetEngineType();
public Integer GetLength();
public Integer GetSafteyLevel();
public class CarDataTransferObject Implements ICarDataTransferObject
private Integer _id;
private String _color;
private String _manufacturer;
private String _model;
private String _uniqueIdNr;
private Integer _nrOfDoors;
private EngineType _engineType;
private Integer _length;
private Integer _safetyLevel;
public Integer GetId() return _id;
public void SetId(Integer id) _id = id;
public String GetColor() return _color;
public void SetColor(String color) _color = color;
public String GetManufacturer() return _manufacturer;
public void SetManufacturer(String manufacturer) _manufacturer = manufacturer;
public String GetModel() return _model;
public void SetModel(String model) _model = model;
public String GetUUID() return _uniqueIdNr;
public void SetUUID(String uuid) _uniqueIdNr = uuid;
public Integer GetDoorCount() return _nrOfDoors;
public void SetDoorCount(Integer count) _nrOfDoors = count;
public EngineType GetEngineType() return _engineType;
public void SetEngineType(EngineType et) _engineType = et;
public Integer GetLength() return _length;
public void SetLength(Integer length) _length = length;
public Integer GetSafteyLevel() return _safetyLevel;
public void SetSafteyLevel(Integer level) _safteyLevel = level;
public CarDataTransferObject()
public CarDataTransferObject(ICarDataTransferObject other) ...
public ReadOnlyCarDataTransferObject AsReadOnly()
return ReadOnlyCarDataTransferObject (this);
}
public class ReadOnlyCarDataTransferObject Implements ICarDataTransferObject
private ICarDataTransferObject _dto = null;
public Integer GetId() return _dto.GetId();
public String GetColor() return _dto.GetColor();
public String GetManufacturer() return _dto.GetManufacturer();
public String GetModel() return _dto.GetModel();
public String GetUUID() return _dto.GetUUID();
public Integer GetDoorCount() return _dto.GetDoorCount();
public EngineType GetEngineType() return _dto.GetEngineType();
public Integer GetLength() return _dto.GetLength();
public Integer GetSafteyLevel() return _dto.GetSafteyLevel;
public ReadOnlyCarDataTransferObject (ICarDataTransferObject other)
_dto = other;
Now when you want class A to have a copy no one can modify, just use the copy constructor and only expose a ReadOnly version of that copy.
public class A
ICarDataTransferObject _dto;
ReadOnlyCarDataTransferObject _readOnlyDTO;
public ICarDataTransferObject GetDTO() return _readOnlyDTO;
public A(ICarDataTransferObject dto)
_dto = new CarDataTransferObject(dto);
_readOnlyDTO = new ReadOnlyCarDataTransferObject(_dto);
You commonly see this approach in .NET applications.
It seems a little inefficient to construct an entirely new instance via a builder every time you want to make a new copy with a small modification. More significantly, it sounds like the places where you need the class to be immutable are isolated to places like class A. Why not try something like this:
public interface ICarDataTransferObject
public Integer GetId();
public String GetColor();
public String GetManufacturer();
public String GetModel();
public String GetUUID();
public Integer GetDoorCount();
public EngineType GetEngineType();
public Integer GetLength();
public Integer GetSafteyLevel();
public class CarDataTransferObject Implements ICarDataTransferObject
private Integer _id;
private String _color;
private String _manufacturer;
private String _model;
private String _uniqueIdNr;
private Integer _nrOfDoors;
private EngineType _engineType;
private Integer _length;
private Integer _safetyLevel;
public Integer GetId() return _id;
public void SetId(Integer id) _id = id;
public String GetColor() return _color;
public void SetColor(String color) _color = color;
public String GetManufacturer() return _manufacturer;
public void SetManufacturer(String manufacturer) _manufacturer = manufacturer;
public String GetModel() return _model;
public void SetModel(String model) _model = model;
public String GetUUID() return _uniqueIdNr;
public void SetUUID(String uuid) _uniqueIdNr = uuid;
public Integer GetDoorCount() return _nrOfDoors;
public void SetDoorCount(Integer count) _nrOfDoors = count;
public EngineType GetEngineType() return _engineType;
public void SetEngineType(EngineType et) _engineType = et;
public Integer GetLength() return _length;
public void SetLength(Integer length) _length = length;
public Integer GetSafteyLevel() return _safetyLevel;
public void SetSafteyLevel(Integer level) _safteyLevel = level;
public CarDataTransferObject()
public CarDataTransferObject(ICarDataTransferObject other) ...
public ReadOnlyCarDataTransferObject AsReadOnly()
return ReadOnlyCarDataTransferObject (this);
}
public class ReadOnlyCarDataTransferObject Implements ICarDataTransferObject
private ICarDataTransferObject _dto = null;
public Integer GetId() return _dto.GetId();
public String GetColor() return _dto.GetColor();
public String GetManufacturer() return _dto.GetManufacturer();
public String GetModel() return _dto.GetModel();
public String GetUUID() return _dto.GetUUID();
public Integer GetDoorCount() return _dto.GetDoorCount();
public EngineType GetEngineType() return _dto.GetEngineType();
public Integer GetLength() return _dto.GetLength();
public Integer GetSafteyLevel() return _dto.GetSafteyLevel;
public ReadOnlyCarDataTransferObject (ICarDataTransferObject other)
_dto = other;
Now when you want class A to have a copy no one can modify, just use the copy constructor and only expose a ReadOnly version of that copy.
public class A
ICarDataTransferObject _dto;
ReadOnlyCarDataTransferObject _readOnlyDTO;
public ICarDataTransferObject GetDTO() return _readOnlyDTO;
public A(ICarDataTransferObject dto)
_dto = new CarDataTransferObject(dto);
_readOnlyDTO = new ReadOnlyCarDataTransferObject(_dto);
You commonly see this approach in .NET applications.
edited Nov 11 at 1:44
answered Nov 11 at 1:08
Ryan Pierce Williams
43719
43719
Why the down vote?
– Ryan Pierce Williams
Nov 11 at 1:26
1
It wasn't by me, if it matters. I will up-vote. Thank you.
– user3529850
Nov 11 at 1:29
haha, thanks :)
– Ryan Pierce Williams
Nov 11 at 1:29
add a comment |
Why the down vote?
– Ryan Pierce Williams
Nov 11 at 1:26
1
It wasn't by me, if it matters. I will up-vote. Thank you.
– user3529850
Nov 11 at 1:29
haha, thanks :)
– Ryan Pierce Williams
Nov 11 at 1:29
Why the down vote?
– Ryan Pierce Williams
Nov 11 at 1:26
Why the down vote?
– Ryan Pierce Williams
Nov 11 at 1:26
1
1
It wasn't by me, if it matters. I will up-vote. Thank you.
– user3529850
Nov 11 at 1:29
It wasn't by me, if it matters. I will up-vote. Thank you.
– user3529850
Nov 11 at 1:29
haha, thanks :)
– Ryan Pierce Williams
Nov 11 at 1:29
haha, thanks :)
– Ryan Pierce Williams
Nov 11 at 1:29
add a comment |
up vote
1
down vote
While it is debatable whether your static method is an anti-pattern or not, it surely won't scale for combinations of different attributes. Nonetheless, even if it's not an anti-pattern, I think there is a better way to accomplish what you need.
There's a variant of the traditional builder pattern that, instead of creating a new empty builder, accepts an already built object and creates an already initialized builder. Once you create the builder this way, you simply change the length
attribute in the builder. Finally, build the object. In plain code (no Lombok, sorry) it could be like this:
public class CarDataTransferObj
private Integer id;
private String color;
// other attributes omitted for brevity
private Integer length;
// Private constructor for builder
private CarDataTransferObj(Builder builder)
this.id = builder.id;
this.color = builder.color;
this.length = builder.length;
// Traditional factory method to create and return builder
public static Builder builder()
return new Builder();
// Factory method to create and return builder initialized from an instance
public static Builder builder(CarDataTransferObj car)
Builder builder = builder();
builder.id = car.id;
builder.color = car.color;
builder.length = car.length;
return builder;
// getters
public static class Builder
private Integer id;
private String color;
private Integer length;
private Builder()
public Builder withId(Integer id) this.id = id; return this;
public Builder withColor(String color) this.color = color; return this;
public Builder withLength(Integer length) this.length = length; return this;
public CarDataTransferObj build()
return new CarDataTransferObj(this);
Now with all this infrastructure in place, you can do what you want as easy as:
CarDataTransferObj originalCar = ... // get the original car from somewhere
CarDataTransferObj newCar = CarDataTransferObj.builder(originalCar)
.withLength(newLength)
.build();
This approach has the advantage that it scales well (it can be used to change any combination of parameters). Maybe all this builder's code seems boilerplate, but I use an IntelliJ plugin to create the builder with two keystrokes (including the variant factory method that accepts a built instance to create an initialized builder).
add a comment |
up vote
1
down vote
While it is debatable whether your static method is an anti-pattern or not, it surely won't scale for combinations of different attributes. Nonetheless, even if it's not an anti-pattern, I think there is a better way to accomplish what you need.
There's a variant of the traditional builder pattern that, instead of creating a new empty builder, accepts an already built object and creates an already initialized builder. Once you create the builder this way, you simply change the length
attribute in the builder. Finally, build the object. In plain code (no Lombok, sorry) it could be like this:
public class CarDataTransferObj
private Integer id;
private String color;
// other attributes omitted for brevity
private Integer length;
// Private constructor for builder
private CarDataTransferObj(Builder builder)
this.id = builder.id;
this.color = builder.color;
this.length = builder.length;
// Traditional factory method to create and return builder
public static Builder builder()
return new Builder();
// Factory method to create and return builder initialized from an instance
public static Builder builder(CarDataTransferObj car)
Builder builder = builder();
builder.id = car.id;
builder.color = car.color;
builder.length = car.length;
return builder;
// getters
public static class Builder
private Integer id;
private String color;
private Integer length;
private Builder()
public Builder withId(Integer id) this.id = id; return this;
public Builder withColor(String color) this.color = color; return this;
public Builder withLength(Integer length) this.length = length; return this;
public CarDataTransferObj build()
return new CarDataTransferObj(this);
Now with all this infrastructure in place, you can do what you want as easy as:
CarDataTransferObj originalCar = ... // get the original car from somewhere
CarDataTransferObj newCar = CarDataTransferObj.builder(originalCar)
.withLength(newLength)
.build();
This approach has the advantage that it scales well (it can be used to change any combination of parameters). Maybe all this builder's code seems boilerplate, but I use an IntelliJ plugin to create the builder with two keystrokes (including the variant factory method that accepts a built instance to create an initialized builder).
add a comment |
up vote
1
down vote
up vote
1
down vote
While it is debatable whether your static method is an anti-pattern or not, it surely won't scale for combinations of different attributes. Nonetheless, even if it's not an anti-pattern, I think there is a better way to accomplish what you need.
There's a variant of the traditional builder pattern that, instead of creating a new empty builder, accepts an already built object and creates an already initialized builder. Once you create the builder this way, you simply change the length
attribute in the builder. Finally, build the object. In plain code (no Lombok, sorry) it could be like this:
public class CarDataTransferObj
private Integer id;
private String color;
// other attributes omitted for brevity
private Integer length;
// Private constructor for builder
private CarDataTransferObj(Builder builder)
this.id = builder.id;
this.color = builder.color;
this.length = builder.length;
// Traditional factory method to create and return builder
public static Builder builder()
return new Builder();
// Factory method to create and return builder initialized from an instance
public static Builder builder(CarDataTransferObj car)
Builder builder = builder();
builder.id = car.id;
builder.color = car.color;
builder.length = car.length;
return builder;
// getters
public static class Builder
private Integer id;
private String color;
private Integer length;
private Builder()
public Builder withId(Integer id) this.id = id; return this;
public Builder withColor(String color) this.color = color; return this;
public Builder withLength(Integer length) this.length = length; return this;
public CarDataTransferObj build()
return new CarDataTransferObj(this);
Now with all this infrastructure in place, you can do what you want as easy as:
CarDataTransferObj originalCar = ... // get the original car from somewhere
CarDataTransferObj newCar = CarDataTransferObj.builder(originalCar)
.withLength(newLength)
.build();
This approach has the advantage that it scales well (it can be used to change any combination of parameters). Maybe all this builder's code seems boilerplate, but I use an IntelliJ plugin to create the builder with two keystrokes (including the variant factory method that accepts a built instance to create an initialized builder).
While it is debatable whether your static method is an anti-pattern or not, it surely won't scale for combinations of different attributes. Nonetheless, even if it's not an anti-pattern, I think there is a better way to accomplish what you need.
There's a variant of the traditional builder pattern that, instead of creating a new empty builder, accepts an already built object and creates an already initialized builder. Once you create the builder this way, you simply change the length
attribute in the builder. Finally, build the object. In plain code (no Lombok, sorry) it could be like this:
public class CarDataTransferObj
private Integer id;
private String color;
// other attributes omitted for brevity
private Integer length;
// Private constructor for builder
private CarDataTransferObj(Builder builder)
this.id = builder.id;
this.color = builder.color;
this.length = builder.length;
// Traditional factory method to create and return builder
public static Builder builder()
return new Builder();
// Factory method to create and return builder initialized from an instance
public static Builder builder(CarDataTransferObj car)
Builder builder = builder();
builder.id = car.id;
builder.color = car.color;
builder.length = car.length;
return builder;
// getters
public static class Builder
private Integer id;
private String color;
private Integer length;
private Builder()
public Builder withId(Integer id) this.id = id; return this;
public Builder withColor(String color) this.color = color; return this;
public Builder withLength(Integer length) this.length = length; return this;
public CarDataTransferObj build()
return new CarDataTransferObj(this);
Now with all this infrastructure in place, you can do what you want as easy as:
CarDataTransferObj originalCar = ... // get the original car from somewhere
CarDataTransferObj newCar = CarDataTransferObj.builder(originalCar)
.withLength(newLength)
.build();
This approach has the advantage that it scales well (it can be used to change any combination of parameters). Maybe all this builder's code seems boilerplate, but I use an IntelliJ plugin to create the builder with two keystrokes (including the variant factory method that accepts a built instance to create an initialized builder).
answered Nov 11 at 2:37
Federico Peralta Schaffner
21.4k33269
21.4k33269
add a comment |
add a comment |
up vote
0
down vote
I'm still new to java but..
I guess making a copy method which takes the CarDataTransferObj object variables and sets their values to another CarDataTransferObj object variables and changing the the length using it's setter method would be better idea
Example:
public class CarDataTransferObj
private Integer id;
private String color;
private String manufacturer;
private String model;
private String uniqueIdNr;
private Integer nrOfDoors;
private EngineType engineType;
private Integer length;
private Integer safetyLevel;
public void Copy(CarDataTransferObj copy) //Could add another parameter here to be the new length
copy.setId(id);
copy.set(color);
copy.setManufacturer(manufacturer);
copy.setModel(model);
copy.setUniqueIdNr(uniqueIdNr));
copy.setNrOfDoors(nrOfDoors));
copy.setEngineType(engineType));
copy.setLength(length);
copy.setSafetyLevel(safetyLevel));
public class SomeOtherClass
CarDataTransferObj car1 = new CarDataTransferObj(); //Using this way made you able to use the constructor for a more useful thing
//You set the variables you want for car1 here
CarDataTransferObj car2 = new CarDataTransferObj();
car1.Copy(car2)
car2.setLength(newLength) //Set the new length here
Couple things here: 1. You are using a bunch of setter methods you didn't define (but we know what you mean). 2. How do you ensure that in class A no one can modify the DTO? I defined a ReadOnlyCarTransferObject in my answer to solve this.
– Ryan Pierce Williams
Nov 11 at 1:35
I actually missed that part...but i think that would be declaring the setters private. And good idea to make a ReadOnly instance btw
– Omar Abdul'Azeez
Nov 11 at 2:11
If the setters were private then SomeOtherClass wouldn't be able to modify the length ;)
– Ryan Pierce Williams
Nov 11 at 2:30
@Ryan I guess 8 hours of debugging messed with my head....i thought you would never say this because it can through car1.varName but now i realized they have to be private
– Omar Abdul'Azeez
Nov 11 at 2:43
haha, no worries :)
– Ryan Pierce Williams
Nov 11 at 2:45
add a comment |
up vote
0
down vote
I'm still new to java but..
I guess making a copy method which takes the CarDataTransferObj object variables and sets their values to another CarDataTransferObj object variables and changing the the length using it's setter method would be better idea
Example:
public class CarDataTransferObj
private Integer id;
private String color;
private String manufacturer;
private String model;
private String uniqueIdNr;
private Integer nrOfDoors;
private EngineType engineType;
private Integer length;
private Integer safetyLevel;
public void Copy(CarDataTransferObj copy) //Could add another parameter here to be the new length
copy.setId(id);
copy.set(color);
copy.setManufacturer(manufacturer);
copy.setModel(model);
copy.setUniqueIdNr(uniqueIdNr));
copy.setNrOfDoors(nrOfDoors));
copy.setEngineType(engineType));
copy.setLength(length);
copy.setSafetyLevel(safetyLevel));
public class SomeOtherClass
CarDataTransferObj car1 = new CarDataTransferObj(); //Using this way made you able to use the constructor for a more useful thing
//You set the variables you want for car1 here
CarDataTransferObj car2 = new CarDataTransferObj();
car1.Copy(car2)
car2.setLength(newLength) //Set the new length here
Couple things here: 1. You are using a bunch of setter methods you didn't define (but we know what you mean). 2. How do you ensure that in class A no one can modify the DTO? I defined a ReadOnlyCarTransferObject in my answer to solve this.
– Ryan Pierce Williams
Nov 11 at 1:35
I actually missed that part...but i think that would be declaring the setters private. And good idea to make a ReadOnly instance btw
– Omar Abdul'Azeez
Nov 11 at 2:11
If the setters were private then SomeOtherClass wouldn't be able to modify the length ;)
– Ryan Pierce Williams
Nov 11 at 2:30
@Ryan I guess 8 hours of debugging messed with my head....i thought you would never say this because it can through car1.varName but now i realized they have to be private
– Omar Abdul'Azeez
Nov 11 at 2:43
haha, no worries :)
– Ryan Pierce Williams
Nov 11 at 2:45
add a comment |
up vote
0
down vote
up vote
0
down vote
I'm still new to java but..
I guess making a copy method which takes the CarDataTransferObj object variables and sets their values to another CarDataTransferObj object variables and changing the the length using it's setter method would be better idea
Example:
public class CarDataTransferObj
private Integer id;
private String color;
private String manufacturer;
private String model;
private String uniqueIdNr;
private Integer nrOfDoors;
private EngineType engineType;
private Integer length;
private Integer safetyLevel;
public void Copy(CarDataTransferObj copy) //Could add another parameter here to be the new length
copy.setId(id);
copy.set(color);
copy.setManufacturer(manufacturer);
copy.setModel(model);
copy.setUniqueIdNr(uniqueIdNr));
copy.setNrOfDoors(nrOfDoors));
copy.setEngineType(engineType));
copy.setLength(length);
copy.setSafetyLevel(safetyLevel));
public class SomeOtherClass
CarDataTransferObj car1 = new CarDataTransferObj(); //Using this way made you able to use the constructor for a more useful thing
//You set the variables you want for car1 here
CarDataTransferObj car2 = new CarDataTransferObj();
car1.Copy(car2)
car2.setLength(newLength) //Set the new length here
I'm still new to java but..
I guess making a copy method which takes the CarDataTransferObj object variables and sets their values to another CarDataTransferObj object variables and changing the the length using it's setter method would be better idea
Example:
public class CarDataTransferObj
private Integer id;
private String color;
private String manufacturer;
private String model;
private String uniqueIdNr;
private Integer nrOfDoors;
private EngineType engineType;
private Integer length;
private Integer safetyLevel;
public void Copy(CarDataTransferObj copy) //Could add another parameter here to be the new length
copy.setId(id);
copy.set(color);
copy.setManufacturer(manufacturer);
copy.setModel(model);
copy.setUniqueIdNr(uniqueIdNr));
copy.setNrOfDoors(nrOfDoors));
copy.setEngineType(engineType));
copy.setLength(length);
copy.setSafetyLevel(safetyLevel));
public class SomeOtherClass
CarDataTransferObj car1 = new CarDataTransferObj(); //Using this way made you able to use the constructor for a more useful thing
//You set the variables you want for car1 here
CarDataTransferObj car2 = new CarDataTransferObj();
car1.Copy(car2)
car2.setLength(newLength) //Set the new length here
answered Nov 11 at 1:29
Omar Abdul'Azeez
185
185
Couple things here: 1. You are using a bunch of setter methods you didn't define (but we know what you mean). 2. How do you ensure that in class A no one can modify the DTO? I defined a ReadOnlyCarTransferObject in my answer to solve this.
– Ryan Pierce Williams
Nov 11 at 1:35
I actually missed that part...but i think that would be declaring the setters private. And good idea to make a ReadOnly instance btw
– Omar Abdul'Azeez
Nov 11 at 2:11
If the setters were private then SomeOtherClass wouldn't be able to modify the length ;)
– Ryan Pierce Williams
Nov 11 at 2:30
@Ryan I guess 8 hours of debugging messed with my head....i thought you would never say this because it can through car1.varName but now i realized they have to be private
– Omar Abdul'Azeez
Nov 11 at 2:43
haha, no worries :)
– Ryan Pierce Williams
Nov 11 at 2:45
add a comment |
Couple things here: 1. You are using a bunch of setter methods you didn't define (but we know what you mean). 2. How do you ensure that in class A no one can modify the DTO? I defined a ReadOnlyCarTransferObject in my answer to solve this.
– Ryan Pierce Williams
Nov 11 at 1:35
I actually missed that part...but i think that would be declaring the setters private. And good idea to make a ReadOnly instance btw
– Omar Abdul'Azeez
Nov 11 at 2:11
If the setters were private then SomeOtherClass wouldn't be able to modify the length ;)
– Ryan Pierce Williams
Nov 11 at 2:30
@Ryan I guess 8 hours of debugging messed with my head....i thought you would never say this because it can through car1.varName but now i realized they have to be private
– Omar Abdul'Azeez
Nov 11 at 2:43
haha, no worries :)
– Ryan Pierce Williams
Nov 11 at 2:45
Couple things here: 1. You are using a bunch of setter methods you didn't define (but we know what you mean). 2. How do you ensure that in class A no one can modify the DTO? I defined a ReadOnlyCarTransferObject in my answer to solve this.
– Ryan Pierce Williams
Nov 11 at 1:35
Couple things here: 1. You are using a bunch of setter methods you didn't define (but we know what you mean). 2. How do you ensure that in class A no one can modify the DTO? I defined a ReadOnlyCarTransferObject in my answer to solve this.
– Ryan Pierce Williams
Nov 11 at 1:35
I actually missed that part...but i think that would be declaring the setters private. And good idea to make a ReadOnly instance btw
– Omar Abdul'Azeez
Nov 11 at 2:11
I actually missed that part...but i think that would be declaring the setters private. And good idea to make a ReadOnly instance btw
– Omar Abdul'Azeez
Nov 11 at 2:11
If the setters were private then SomeOtherClass wouldn't be able to modify the length ;)
– Ryan Pierce Williams
Nov 11 at 2:30
If the setters were private then SomeOtherClass wouldn't be able to modify the length ;)
– Ryan Pierce Williams
Nov 11 at 2:30
@Ryan I guess 8 hours of debugging messed with my head....i thought you would never say this because it can through car1.varName but now i realized they have to be private
– Omar Abdul'Azeez
Nov 11 at 2:43
@Ryan I guess 8 hours of debugging messed with my head....i thought you would never say this because it can through car1.varName but now i realized they have to be private
– Omar Abdul'Azeez
Nov 11 at 2:43
haha, no worries :)
– Ryan Pierce Williams
Nov 11 at 2:45
haha, no worries :)
– Ryan Pierce Williams
Nov 11 at 2:45
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244753%2fis-it-correct-to-have-static-factory-method-to-get-a-new-instance-with-one-field%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
It looks like you're using Lombok. They actually have an experimental feature exactly for such purpose projectlombok.org/features/experimental/Wither.
– yegodm
Nov 11 at 1:25