第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用靜態(tài)工廠方法來獲取更新了一個字段的新實例是否正確?

使用靜態(tài)工廠方法來獲取更新了一個字段的新實例是否正確?

慕哥6287543 2022-01-12 14:31:20
我認為標題是自我描述的,但我會舉一個例子來詳細說明我的問題。我有一個DTO字段很少的CarDataTransferObj類(在我的例子中是一個類)。在另一個類(我們稱之為類A)中,我需要多次創(chuàng)建該對象的新實例,但只更新一個字段(length我的示例中的字段)。GivenDTO在類中必須是不可變的A。由于類中有“許多”字段CarDataTransferObj,我考慮了以下方法(以避免在類中重復代碼A):@Builderpublic 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();    }}對我來說,這聽起來像是對靜態(tài)工廠方法的一點反模式使用。我不確定它是否可以接受,因此這個問題。以所呈現(xiàn)的方式使用靜態(tài)工廠方法是一種反模式,應該避免嗎?
查看完整描述

3 回答

?
犯罪嫌疑人X

TA貢獻2080條經(jīng)驗 獲得超4個贊

在我的搜索中,我沒有遇到任何人將此1稱為反模式。

但是,很明顯,如果您嘗試使用未專門實施以支持此操作模式的經(jīng)典構(gòu)建器來執(zhí)行此操作....它將無法正常工作。例如,Wikipedia 文章中關于 Builder 設計模式的示例 CarBuilderImpl將狀態(tài)放入急切創(chuàng)建的Car實例中。該build()方法只是返回該對象。如果您嘗試以您建議的方式重用該構(gòu)建器,您最終會修改一個Car已經(jīng)構(gòu)建的。

您還需要擔心另一個問題。在我們修改 WikipediaCarBuilder示例以將實際車輪(而不是多個車輪)添加到Car正在建造的汽車中時,我們必須擔心創(chuàng)建共享相同車輪的汽車。

您可以在構(gòu)建器實現(xiàn)中解決這些問題,但尚不清楚收益是否超過成本。


如果你將這種想法轉(zhuǎn)移到使用工廠方法來做這件事,你會得出一個稍微不同的結(jié)論。

  • 如果您將其作為“一次性”進行,那可能沒問題。你有一個特定的需求,代碼很笨拙......但問題也是如此。

  • 如果您需要對許多不同的參數(shù)或參數(shù)組合執(zhí)行此操作,則無法擴展。

  • 如果創(chuàng)建的對象是可變的,那么這種方法在多線程環(huán)境中可能會出現(xiàn)問題,具體取決于您如何控制對用作模板的對象的訪問。


1 - 對于某事物是否為反模式,沒有明確的可衡量標準。這是一個見仁見智的問題。誠然,對于許多反模式來說,這種觀點會有廣泛的共識。


查看完整回答
反對 回復 2022-01-12
?
搖曳的薔薇

TA貢獻1793條經(jīng)驗 獲得超6個贊

每次你想通過一個小的修改來制作一個新的副本時,通過一個構(gòu)建器來構(gòu)建一個全新的實例似乎有點低效。更重要的是,聽起來您需要類不可變的地方與 A 類之類的地方隔離。為什么不嘗試這樣的事情:


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;

    }

}

現(xiàn)在,當您希望 A 類擁有任何人都無法修改的副本時,只需使用復制構(gòu)造函數(shù)并僅公開該副本的只讀版本。


public class A {

    ICarDataTransferObject _dto;

    ReadOnlyCarDataTransferObject _readOnlyDTO;


    public ICarDataTransferObject GetDTO() { return _readOnlyDTO; }


    public A(ICarDataTransferObject dto) {

        _dto = new CarDataTransferObject(dto);

        _readOnlyDTO = new ReadOnlyCarDataTransferObject(_dto);

    }

}

您通常在 .NET 應用程序中看到這種方法。


查看完整回答
反對 回復 2022-01-12
?
溫溫醬

TA貢獻1752條經(jīng)驗 獲得超4個贊

盡管您的靜態(tài)方法是否是反模式尚有爭議,但它肯定不會針對不同屬性的組合進行擴展。盡管如此,即使它不是反模式,我認為有更好的方法來完成你所需要的。


有一個傳統(tǒng)構(gòu)建器模式的變體,它不是創(chuàng)建一個新的空構(gòu)建器,而是接受一個已經(jīng)構(gòu)建的對象并創(chuàng)建一個已經(jīng)初始化的構(gòu)建器。以這種方式創(chuàng)建構(gòu)建器后,您只需更改builder 中的length屬性。最后,構(gòu)建對象。用純代碼(沒有龍目島,對不起)它可能是這樣的:


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

        }

    }

}

現(xiàn)在有了所有這些基礎設施,您可以輕松地做您想做的事情:


CarDataTransferObj originalCar = ... // get the original car from somewhere


CarDataTransferObj newCar = CarDataTransferObj.builder(originalCar)

    .withLength(newLength)

    .build();

這種方法的優(yōu)點是它可以很好地擴展(它可以用來改變參數(shù)的任何組合)。也許所有這些構(gòu)建器的代碼看起來都是樣板,但我使用 IntelliJ 插件通過兩次擊鍵創(chuàng)建構(gòu)建器(包括接受構(gòu)建實例以創(chuàng)建初始化構(gòu)建器的變體工廠方法)。


查看完整回答
反對 回復 2022-01-12
  • 3 回答
  • 0 關注
  • 180 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號