Bagaimana menyusun objek kompleks dengan bidang terkait yang perlu diinisialisasi secara bersamaan

Saya menerapkan API dan saya terus mengalami masalah ini. Saya pikir ada sesuatu yang salah dengan desain inti saya tapi saya tidak yakin apa dan saya merasa kewalahan dengan prinsip-prinsip desain.

Pada dasarnya saya akan memiliki objek dengan banyak bidang terkait. Mengisi bidang dengan info yang tepat bukanlah hal yang sepele dan bergantung pada satu atau lebih panggilan API eksternal menggunakan klien yang saya teruskan ke konstruktor, panggilan API ini juga memberikan informasi terkait dengan lebih dari satu bidang, oleh karena itu diinginkan untuk mengisi banyak bidang secara bersamaan. Saya ingin menjaga konstruktor tetap sederhana/cepat dan menjaga objek saya dapat diuji sehingga saya tidak memasukkan logika apa pun di sana, hanya tugas. Namun, yang akhirnya saya lakukan adalah membuat metode tunggal untuk mengisi semua bidang dan memanggil ini di semua pengambil saya setelah pemeriksaan nol, yaitu dengan malas mengisi bidang objek.

Menurut saya ini buruk karena melanggar prinsip "cepat-gagal", terutama karena saya menggunakan klien untuk memanggil layanan eksternal, yang mungkin gagal jika, katakanlah, kredensial klien tidak valid. Namun, saya mengalami masalah saat merestrukturisasi kode saya.

Saya telah berpikir untuk mengekstraksi logika klien ke dalam layanan/konektor, ClothingConnector misalnya, namun saya tidak yakin ini akan menyelesaikan masalah saya karena saya masih tidak ingin menyebutnya di konstruktor, dan itu akan tetap bermanfaat untuk mengisi banyak bidang sekaligus.

class Person {
    ClientToGetClothing clothingClient;

    Pants pants;
    Shirt shirt;
    Fabric shirtFabric;
    Fabric pantsFabric;

    public Person(ClientToGetClothing clothingClient) {
         this.clothingClient = clothingClient;
    }

    private void populateClothing() {
         PantsResponse pantsInfo = clothingClient.retrievePantsInfo();
         this.pants = pantsInfo.getPants();

         ShirtResponse shirtInfo = clothingClient.retrieveShirtInfo();
         this.shirt = pantsInfo.getShirt();

         // do some more things with my pants + shirt and assign results to more fields, calculate the fabric in this example

    }

    public Shirt getShirt() {
        if (shirt == null) {
            populateClothing;
        }
        return this.shirt;
    }
    // ...
}

person Tristan Sparks    schedule 11.07.2019    source sumber
comment
Mengapa tidak mengambil komponen yang diperlukan dari API eksternal terlebih dahulu dan meneruskannya ke konstruktor (Pemisahan masalah &Pembalikan kontrol)? Jika digabungkan dengan Builder pola, hal ini dapat menghasilkan kode yang cukup mudah dibaca. Selain itu, pertanyaan ini tampaknya lebih cocok untuk Tinjauan Kode.   -  person Turing85    schedule 12.07.2019


Jawaban (1)


Pertama, saya akan memisahkan ClothingClient dari objek Person. Mintalah pabrik mengerjakan atribut populasi dan kemudian mengembalikan kelas orang. https://en.wikipedia.org/wiki/Factory_method_pattern#Java

person Arpan Kanthal    schedule 11.07.2019
comment
Saya berpendapat bahwa operasi ini terlalu rumit untuk sebuah pabrik dan oleh karena itu menggunakan pembangun sebagai gantinya - person Turing85; 12.07.2019