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 ?










share|improve this question





















  • 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














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 ?










share|improve this question





















  • 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












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 ?










share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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
















  • 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












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.






share|improve this answer






















  • Related: What is an anti-pattern?
    – jaco0646
    Nov 13 at 20:21

















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.






share|improve this answer






















  • 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

















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).






share|improve this answer



























    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






    share|improve this answer




















    • 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










    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    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

























    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.






    share|improve this answer






















    • Related: What is an anti-pattern?
      – jaco0646
      Nov 13 at 20:21














    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.






    share|improve this answer






















    • Related: What is an anti-pattern?
      – jaco0646
      Nov 13 at 20:21












    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.






    share|improve this answer














    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.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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
















    • 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












    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.






    share|improve this answer






















    • 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














    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.






    share|improve this answer






















    • 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












    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.






    share|improve this answer














    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.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    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
















    • 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










    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).






    share|improve this answer
























      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).






      share|improve this answer






















        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).






        share|improve this answer












        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).







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 11 at 2:37









        Federico Peralta Schaffner

        21.4k33269




        21.4k33269




















            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






            share|improve this answer




















            • 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














            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






            share|improve this answer




















            • 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












            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






            share|improve this answer












            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







            share|improve this answer












            share|improve this answer



            share|improve this answer










            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
















            • 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

















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            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





















































            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







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3

            Museum of Modern and Contemporary Art of Trento and Rovereto