Apa gunanya membuat konstruktor pribadi di kelas?

134

Mengapa kita harus menjadikan konstruktor pribadi di kelas? Karena kita selalu membutuhkan konstruktor untuk menjadi publik.

giri
sumber

Jawaban:

129

Beberapa alasan di mana Anda mungkin memerlukan konstruktor pribadi:

  1. Konstruktor hanya dapat diakses dari metode pabrik statis di dalam kelas itu sendiri. Singleton juga termasuk dalam kategori ini.
  2. Kelas utilitas , yang hanya berisi metode statis.
nanda
sumber
9
Saya bahkan tidak mau repot-repot membuat konstruktor pribadi untuk kelas utilitas.
Petesh
16
@Patesh: Itu keputusan Anda. Lainnya (s) dan saya lebih suka mencegah instantiasi kelas utilitas daripada meninggalkan satu baris konstruktor pribadi.
nanda
1
dalam beberapa bahasa pemrograman (terutama Java) juga mencegah pewarisan
dfa
9
@ dfa: untuk mencegah warisan, Anda harus memakai finallevel kelas. Menempatkan konstruktor pribadi tidak berguna karena alasan ini.
nanda
3
@ Akan: Tidak jika Anda menggunakan refleksi. Mendeklarasikan konstruktor pribadi dimaksudkan untuk mencegah instantiasi (pembatasan refleksi), tetapi mencegah subklasifikasi adalah efek samping, bukan maksudnya. Alat yang tepat untuk ini adalah mendeklarasikan kelas final. Inilah yang Sun lakukan untuk kelas String, dan potongan yang wajar dari API yang seharusnya tidak diperpanjang.
BobMcGee
96

Dengan menyediakan konstruktor pribadi Anda mencegah instance kelas dari diciptakan di tempat lain selain kelas ini. Ada beberapa kasus penggunaan untuk menyediakan konstruktor tersebut.

A. Instance kelas Anda dibuat dalam suatu staticmetode. The staticMetode ini kemudian dinyatakan sebagai public.

class MyClass()
{
private:
  MyClass() { }

public:
  static MyClass * CreateInstance() { return new MyClass(); }
};

B. Kelas Anda adalah singleton . Ini berarti, tidak lebih dari satu instance kelas Anda ada di program.

class MyClass()
{
private:
  MyClass() { }

public:
  MyClass & Instance()
  {
    static MyClass * aGlobalInst = new MyClass();
    return *aGlobalInst;
  }
};

C. (Hanya berlaku untuk standar C ++ 0x yang akan datang) Anda memiliki beberapa konstruktor. Beberapa dari mereka dinyatakan public, yang lain private. Untuk mengurangi ukuran kode, konstruktor publik 'memanggil' konstruktor pribadi yang pada gilirannya melakukan semua pekerjaan. publicKonstruktor Anda disebut konstruktor pendelegasian :

class MyClass
{
public:
  MyClass() : MyClass(2010, 1, 1) { }

private:
  MyClass(int theYear, int theMonth, int theDay) { /* do real work */ }
};

D. Anda ingin membatasi penyalinan objek (misalnya, karena menggunakan sumber daya bersama):

class MyClass
{
  SharedResource * myResource;

private:
  MyClass(const MyClass & theOriginal) { }
};

E. Kelas Anda adalah kelas utilitas . Itu artinya, hanya berisi staticanggota. Dalam hal ini, tidak ada instance objek yang harus dibuat dalam program.

Kerido
sumber
3
Dalam kebanyakan kasus, Anda ingin mencegah penyalinan objek. Jadi, Anda tidak akan memberikan implementasi untuk pembuat salinan pribadi.
tanggal
dari google c ++ style guide (contoh lain tidak ada dalam daftar tetapi umum) -> jika Anda perlu melakukan pekerjaan di konstruktor "pertimbangkan fungsi pabrik [dan buat konstruktor pribadi]" (teks dalam kurung kurawal ditulis oleh saya )
Trevor Boyd Smith
12

Untuk meninggalkan "pintu belakang" yang memungkinkan kelas teman lain / fungsi untuk membangun objek dengan cara yang dilarang untuk pengguna. Contoh yang terlintas dalam pikiran adalah wadah yang membangun iterator (C ++):

Iterator Container::begin() { return Iterator(this->beginPtr_); }
// Iterator(pointer_type p) constructor is private,
//     and Container is a friend of Iterator.
Emile Cormier
sumber
Apakah ini cukup berbeda, Terry? ;)
Emile Cormier
Jawaban yang bagus. Mengapa tidak menyebutkan refleksi, karena ini adalah salah satu jalan untuk mencapai sesuatu yang tidak bisa dilakukan pengguna?
BobMcGee
@ Bob: Anda harus memberi tahu saya tentang hal itu, karena saya terutama seorang pria C ++ dan refleksi sebenarnya tidak ada dalam kosa kata C ++. ;)
Emile Cormier
3
Tidak ada yang akan membaca ini, tetapi begini: Saya sudah beberapa kali downvoted untuk yang ini. Bukan kesal atau apa pun, tapi (demi belajar) saya ingin tahu mengapa ini buruk? Bagaimana lagi iterator dapat dibangun dengan data yang dibutuhkan untuk mengakses data kontener?
Emile Cormier
2
@EmileCormier, saya pikir Anda mendapat suara tidak adil karena orang yang belajar C ++ diberitahu berulang kali: "Hindari deklarasi teman". Saran ini tampaknya ditujukan untuk programmer C ++ yang tidak berpengalaman yang mungkin menggunakan di friendmana itu tidak dijamin - dan ada banyak kasus di mana itu adalah ide yang buruk. Sayangnya, pesan tersebut telah diterima dengan baik, dan banyak pengembang tidak pernah mempelajari bahasa dengan cukup baik untuk memahami bahwa penggunaan sesekali friendtidak hanya dapat diterima, tetapi lebih disukai . Contoh Anda adalah kasus seperti itu. Kopling kuat yang disengaja bukanlah kejahatan, ini adalah keputusan desain.
evadeflow
10

Semua orang terjebak pada masalah Singleton, wow.

Hal-hal lain:

  • Hentikan orang dari membuat kelas Anda di stack; membuat konstruktor pribadi dan hanya mengembalikan pointer melalui metode pabrik.
  • Mencegah pembuatan salinan kelas (konstruktor copy pribadi)
Terry Mahaffey
sumber
8

Ini bisa sangat berguna untuk konstruktor yang berisi kode umum; konstruktor pribadi dapat dipanggil oleh konstruktor lain, menggunakan 'this (...);' notasi. Dengan membuat kode inisialisasi umum dalam konstruktor pribadi (atau yang dilindungi), Anda juga membuat jelas secara eksplisit bahwa kode itu hanya dipanggil selama konstruksi, yang tidak demikian jika hanya berupa metode:

public class Point {
   public Point() {
     this(0,0); // call common constructor
   }
   private Point(int x,int y) {
     m_x = x; m_y = y;
   }
};
Akan
sumber
3

Ada beberapa contoh di mana Anda mungkin tidak ingin menggunakan konstruktor publik; misalnya jika Anda ingin kelas singleton.

Jika Anda menulis sebuah majelis yang digunakan oleh pihak ke-3 mungkin ada sejumlah kelas internal yang Anda hanya ingin dibuat oleh majelis Anda dan tidak akan dipakai oleh pengguna majelis Anda.

Kane
sumber
3

Ini memastikan bahwa Anda (kelas dengan konstruktor pribadi) mengontrol bagaimana konstruktor dipanggil.

Contoh: Metode pabrik statis di kelas dapat mengembalikan objek ketika metode pabrik memilih untuk mengalokasikannya (seperti pabrik tunggal misalnya).

Praha Sangha
sumber
@ Skilldrick: salah satu contoh adalah bahwa Anda dapat memaksa kelas hanya dialokasikan tumpukan.
Dirk
@ bandar Saya telah menghapus komentar saya karena tidak lagi relevan.
Skilldrick
3

Kita juga dapat memiliki konstruktor pribadi, untuk memulai pembuatan objek hanya dengan kelas tertentu (Untuk alasan keamanan).

Salah satu cara untuk melakukannya adalah melalui kelas teman.

Contoh C ++:

class ClientClass;
class SecureClass 
{
  private:
    SecureClass();   // Constructor is private.
    friend class ClientClass;  // All methods in 
                               //ClientClass have access to private
                               // &   protected methods of SecureClass.
};

class ClientClass
{
public:
    ClientClass();
    SecureClass* CreateSecureClass()
     { 
           return (new SecureClass());  // we can access 
                                        // constructor of 
                                        // SecureClass as 
                                        // ClientClass is friend 
                                        // of SecureClass.
     }
};

Catatan: Catatan: Hanya ClientClass (karena itu adalah teman SecureClass) yang dapat memanggil Constructor SecureClass.

vijayNidumolu
sumber
2

ketika Anda tidak ingin pengguna membuat instance kelas ini atau membuat kelas yang mewarisi kelas ini, seperti java.lang.math, semua fungsi dalam paket ini static, semua fungsi dapat dipanggil tanpa membuat turunan math, sehingga konstruktor diumumkan sebagai statis .

Shinxg
sumber
1

Jika bersifat pribadi, maka Anda tidak dapat menyebutnya ==> Anda tidak dapat membuat instance kelas. Berguna dalam beberapa kasus, seperti singleton.

Ada diskusi dan beberapa contoh lagi di sini .

Seth
sumber
1

Saya melihat pertanyaan dari Anda menangani masalah yang sama.

Sederhananya jika Anda tidak ingin orang lain membuat instance, maka pertahankan konstuktor dalam ruang lingkup terbatas. Aplikasi praktis (Contoh) adalah pola tunggal.

Chathuranga Chandrasekara
sumber
1

Anda seharusnya tidak menjadikan konstruktor sebagai pribadi. Titik. Buat itu terlindungi, sehingga Anda dapat memperpanjang kelas jika perlu.

Sunting: Saya mendukung itu, tidak peduli berapa banyak downvotes yang Anda lemparkan pada ini. Anda memotong potensi untuk pengembangan kode di masa mendatang. Jika pengguna atau pemrogram lain benar-benar bertekad untuk memperluas kelas, maka mereka hanya akan mengubah konstruktor menjadi dilindungi dalam sumber atau bytecode. Anda tidak akan mencapai apa pun selain untuk membuat hidup mereka sedikit lebih sulit. Sertakan peringatan dalam komentar konstruktor Anda, dan biarkan di situ.

Jika ini adalah kelas utilitas, solusi yang lebih sederhana, lebih benar, dan lebih elegan adalah menandai seluruh kelas "final statis" untuk mencegah ekstensi. Tidak ada gunanya hanya menandai konstruktor pribadi; pengguna yang benar-benar bertekad selalu dapat menggunakan refleksi untuk mendapatkan konstruktor.

Penggunaan yang valid:

  • Salah satu penggunaan protected konstruktor yang baik adalah dengan memaksa penggunaan metode pabrik statis, yang memungkinkan Anda untuk membatasi instantiasi atau mengumpulkan & menggunakan kembali sumber daya yang mahal (koneksi DB, sumber daya asli).
  • Lajang (biasanya bukan latihan yang baik, tetapi kadang-kadang diperlukan)
BobMcGee
sumber
2
Dalam pengalaman saya tidak ada kebenaran absolut, bahkan goto dapat digunakan jika situasi menuntutnya. Ada cara-cara Jahat dan Jahat, tetapi seperti yang dikatakan Marshall Cline, kadang-kadang Anda harus memilih di antara yang tidak jahat. parashift.com/c++-faq-lite/big-picture.html#faq-6.15 Adapun konstruktor pribadi, mereka diperlukan dan bahkan tidak buruk untuk Anda. Ini berarti bahwa tidak ada seorang pun, termasuk subclass Anda yang harus menggunakannya.
daramarak
Gotos memiliki tempat mereka, benar, tetapi menandai sebuah konstruktor tidak akan memberi Anda apa-apa selain masalah di ujung jalan. Saya telah mengedit posting saya untuk menjelaskan mengapa lebih lengkap.
BobMcGee
Tidak masuk akal untuk menyalin konstruk atau membangun default beberapa kelas. Dalam C ++ Anda menunjukkan ini dengan mendeklarasikan ctor pribadi tanpa mendefinisikannya (yang juga umum untuk operator =).
Mengoptimalkan kompiler seperti Java JIT dan GWT sebenarnya menggunakan konstruktor pribadi: untuk membatasi cakupan instantiasi dan melakukan pekerjaan yang lebih baik dengan mengurutkan / memangkas kode Anda.
Ajax
1

Konstruktor bersifat pribadi untuk beberapa tujuan seperti ketika Anda perlu mengimplementasikan singleton atau membatasi jumlah objek kelas. Misalnya dalam implementasi singleton kita harus menjadikan konstruktor sebagai pribadi

#include<iostream>
using namespace std;
class singletonClass
{


    static int i;
    static singletonClass* instance;
public:


    static singletonClass* createInstance()
    {


        if(i==0)
        {

            instance =new singletonClass;
            i=1;

        }

        return instance;

    }
    void test()
    {

        cout<<"successfully created instance";
    }
};

int singletonClass::i=0;
singletonClass* singletonClass::instance=NULL;
int main()
{


    singletonClass *temp=singletonClass::createInstance();//////return instance!!!
    temp->test();
}

Sekali lagi jika Anda ingin membatasi pembuatan objek hingga 10 maka gunakan yang berikut ini

#include<iostream>
using namespace std;
class singletonClass
{


    static int i;
    static singletonClass* instance;
public:


    static singletonClass* createInstance()
    {


        if(i<10)
        {

            instance =new singletonClass;
            i++;
            cout<<"created";

        }

        return instance;

    }
};

int singletonClass::i=0;
singletonClass* singletonClass::instance=NULL;
int main()
{


    singletonClass *temp=singletonClass::createInstance();//return an instance
    singletonClass *temp1=singletonClass::createInstance();///return another instance

}

Terima kasih

Tunvir Rahman Tusher
sumber
1

Anda dapat memiliki lebih dari satu konstruktor. C ++ menyediakan konstruktor default dan konstruktor salin default jika Anda tidak menyediakan secara eksplisit. Misalkan Anda memiliki kelas yang hanya dapat dibangun menggunakan beberapa konstruktor berparameter. Mungkin itu menginisialisasi variabel. Jika pengguna kemudian menggunakan kelas ini tanpa konstruktor itu, mereka dapat menyebabkan masalah tanpa akhir. Aturan umum yang baik: Jika implementasi default tidak valid, jadikan konstruktor default dan salin menjadi pribadi dan jangan berikan implementasi:

class C
{
public:
    C(int x);

private:
    C();
    C(const C &);
};

Gunakan kompiler untuk mencegah pengguna menggunakan objek dengan konstruktor default yang tidak valid.

Charles
sumber
2
Ketika Anda memberikan konstruktor non default tanpa menentukan konstruktor default, konstruktor default tidak ada. Tidak perlu membuatnya dan menjadikannya pribadi.
TT_
0

Mengutip dari Java Efektif , Anda dapat memiliki kelas dengan konstruktor pribadi untuk memiliki kelas utilitas yang mendefinisikan konstanta (sebagai bidang final statis).

( EDIT: Sesuai komentar, ini adalah sesuatu yang mungkin hanya dapat diterapkan dengan Java, saya tidak mengetahui apakah konstruk ini berlaku / diperlukan dalam bahasa OO lainnya (katakanlah C ++))

Contohnya seperti di bawah ini:

public class Constants {
    private Contants():

    public static final int ADDRESS_UNIT = 32;
    ...
}

EDIT_1 : Sekali lagi, penjelasan di bawah ini berlaku di Jawa: (dan merujuk dari buku, Java Efektif )

Instansiasi kelas utilitas seperti yang di bawah ini, meskipun tidak berbahaya, tidak melayani tujuan apa pun karena mereka tidak dirancang untuk dipakai.

Misalnya, katakanlah tidak ada Konstruktor pribadi untuk Konstanta kelas. Potongan kode seperti di bawah ini valid tetapi tidak lebih baik menyampaikan maksud pengguna kelas Konstanta

unit = (this.length)/new Constants().ADDRESS_UNIT;

berbeda dengan kode like

unit = (this.length)/Constants.ADDRESS_UNIT;

Juga saya pikir konstruktor pribadi menyampaikan maksud perancang kelas Constants (katakanlah) lebih baik.

Java menyediakan konstruktor publik tanpa parameter default jika tidak ada konstruktor yang disediakan, dan jika niat Anda adalah mencegah instantiasi maka konstruktor pribadi diperlukan.

Seseorang tidak dapat menandai kelas statis tingkat atas dan bahkan kelas akhir dapat dipakai.

sateesh
sumber
2
Tetapi dalam C ++ Anda tidak perlu kelas untuk ini. Jika sesuatu tidak bergantung pada data di dalam objek, tulis itu sebagai fungsi bebas, dan variabel bebas. Ingin enkapsulasi? Gunakan namespace.
daramarak
@ Daramarak: terima kasih, saya tidak punya pengalaman dengan C ++. Saya memperbarui jawaban untuk mencerminkan bahwa ini hanya berlaku di Java
sateesh
2
Jika objek Anda hanya merangkum variabel statis, mengapa membatasi Instansiasi? Mengapa menentukan sesuatu tentang konstruktor? Tidak akan ada ruginya jika itu dipakai. Sepertinya Anda bisa mendapatkan hasil yang sama dengan mendeklarasikan kelas statis dan final.
BobMcGee
@ BobMcGee, terima kasih atas komentar Anda. Ini membuat saya berpikir (dan merujuk) lebih banyak tentang apa yang telah saya posting. Saya telah mengedit jawaban saya untuk menambahkan beberapa alasan tentang kegunaan konstruktor pribadi.
sateesh
0

Kelas utilitas dapat memiliki konstruktor pribadi. Pengguna kelas tidak boleh membuat instance kelas-kelas ini:

public final class UtilityClass {
    private UtilityClass() {}

    public static utilityMethod1() {
        ...
    }
}
gpampara
sumber
1
Mengapa penting jika kelas utilitas dipakai? Yang dilakukannya hanyalah membuat objek tanpa bidang dan memakan beberapa byte memori.
BobMcGee
Mampu instantiate itu menciptakan API ambigu. Jika Anda mendesain kelas sebagai kelas utilitas tanpa status dan ingin tetap seperti itu. Anda bisa subkelas kelas dengan konstruktor publik. Subkelas dari beberapa metode utilitas bodoh.
gpampara
@ BobMcGee: jelas merancang kelas yang berfungsi dan merancang kelas yang akan digunakan oleh orang lain adalah hal yang berbeda. Mereka yang bekerja dalam pengembangan API (seperti Sun people atau Google collections guy) akan membunuh siapa pun yang mencoba mengatakan bahwa konstruktor pribadi di kelas utilitas tidak berguna.
nanda
@ gpampara: Mendeklarasikan final kelas Anda mencegah orang melakukan subklasifikasi. Inilah yang Sun lakukan untuk kelas String. @Anda: Kelas utilitas tidak memerlukan konstruktor yang ditentukan. Jika Anda tidak ingin diperpanjang, maka nyatakan tidak dengan menggunakan "final."
BobMcGee
1
@ BobMcGee: Sepertinya Anda suka melihat contoh dari Sun. Kemudian periksa kelas utilitas ini Collections from Sun: docjar.com/html/api/java/util/Collections.java.html . Memang menggunakan konstruktor pribadi.
nanda
0

Anda mungkin ingin mencegah kelas untuk dipakai secara bebas. Lihat pola desain singleton sebagai contoh. Untuk menjamin keunikan, Anda tidak dapat membiarkan siapa pun membuat instance dari itu :-)

Seb
sumber
0

Salah satu penggunaan penting adalah di kelas SingleTon

class Person
{
   private Person()
   {
      //Its private, Hense cannot be Instantiated
   }

   public static Person GetInstance()
   {
       //return new instance of Person
       // In here I will be able to access private constructor
   }
};

Ini juga cocok, Jika kelas Anda hanya memiliki metode statis. yaitu tidak ada yang perlu instantiate kelas Anda

SysAdmin
sumber
Perlu dicatat bahwa singleton dianggap oleh banyak orang sebagai "anti-pola" dan keputusan untuk menerapkannya tidak boleh dianggap enteng. Alternatif umum adalah injeksi ketergantungan.
Michael Aaron Safyan
SingleTon bukan anti-pola. Namun, penggunaan pola yang berlebihan (karena kurangnya pengetahuan tentang penggunaannya) tidak baik. Perlu dicatat bahwa ini adalah salah satu pola GOF.
SysAdmin
0

Ini benar-benar satu alasan yang jelas: Anda ingin membangun objek, tetapi tidak praktis untuk melakukannya (dalam hal antarmuka) dalam konstruktor.

The Factorycontoh adalah cukup jelas, biarkan aku menunjukkan Named Constructoridiom.

Katakanlah saya memiliki kelas Complexyang dapat mewakili bilangan kompleks.

class Complex { public: Complex(double,double); .... };

Pertanyaannya adalah: apakah konstruktor mengharapkan bagian yang nyata dan imajiner, atau apakah ia mengharapkan norma dan sudut (koordinat kutub)?

Saya dapat mengubah antarmuka untuk membuatnya lebih mudah:

class Complex
{
public:
  static Complex Regular(double, double = 0.0f);
  static Complex Polar(double, double = 0.0f);
private:
  Complex(double, double);
}; // class Complex

Ini disebut Named Constructoridiom: kelas hanya dapat dibangun dari awal dengan secara eksplisit menyatakan konstruktor mana yang ingin kita gunakan.

Ini adalah kasus khusus dari banyak metode konstruksi. Pola Desain memberikan baik jumlah cara untuk membangun objek: Builder, Factory, Abstract Factory, ... dan konstruktor pribadi akan memastikan bahwa pengguna benar dibatasi.

Matthieu M.
sumber
0

Selain kegunaan yang lebih dikenal ...

Untuk menerapkan pola Object Method , yang saya ringkas sebagai:

"Konstruktor pribadi, metode statis publik"
"Objek untuk implementasi, fungsi untuk antarmuka"

Jika Anda ingin menerapkan fungsi menggunakan objek, dan objek tidak berguna di luar melakukan perhitungan satu kali (dengan pemanggilan metode), maka Anda memiliki Objek Throwaway . Anda dapat merangkum pembuatan objek dan pemanggilan metode dalam metode statis, mencegah anti-pola umum ini:

z = new A(x,y).call();

... menggantinya dengan panggilan fungsi (namespaced):

z = A.f(x,y);

Penelepon tidak perlu tahu atau peduli bahwa Anda menggunakan objek secara internal, menghasilkan antarmuka yang lebih bersih, dan mencegah sampah dari objek berkeliaran atau penggunaan objek yang salah.

Misalnya, jika Anda ingin memecah perhitungan di seluruh metode foo,, bardan zork, misalnya untuk berbagi keadaan tanpa harus melewati banyak nilai masuk dan keluar dari fungsi, Anda bisa menerapkannya sebagai berikut:

class A {
  public static Z f(x, y) {
    A a = new A(x, y);
    a.foo();
    a.bar();
    return a.zork();
  }

  private A(X x, Y y) { /* ... */ };
}

Metode ini Pola objek diberikan dalam Smalltalk Best Practice Patterns , Kent Beck, halaman 34-37, di mana ini adalah langkah terakhir dari pola refactoring, yang berakhir:

  1. Ganti metode asli dengan yang membuat instance kelas baru, dibangun dengan parameter dan penerima metode asli, dan memanggil "compute".

Ini berbeda secara signifikan dari contoh-contoh lain di sini: kelasnya instantiable (tidak seperti kelas utilitas), tetapi instansnya pribadi (tidak seperti metode pabrik, termasuk lajang dll.), Dan dapat hidup di stack, karena mereka tidak pernah keluar.

Pola ini sangat berguna dalam OOP dasar, di mana objek digunakan untuk menyederhanakan implementasi tingkat rendah, tetapi tidak perlu diekspos secara eksternal, dan kontras dengan OOP top-down yang sering disajikan dan dimulai dengan antarmuka tingkat tinggi.

Nils von Barth
sumber
0

Terkadang berguna jika Anda ingin mengontrol bagaimana dan kapan (dan berapa banyak) instance dari objek dibuat.

Antara lain, digunakan dalam pola:

Singleton pattern
Builder pattern
ssedano
sumber
Bagaimana konstruktor pribadi berguna dalam objek yang tidak berubah? Kekekalan adalah tentang mencegah perubahan pada suatu objek setelah penciptaan , sedangkan konstruktor pribadi adalah tentang mencegah penciptaan .
Nils von Barth
0

Penggunaan konstruktor pribadi juga bisa untuk meningkatkan keterbacaan / pemeliharaan dalam menghadapi desain berbasis domain. Dari "Microsoft .NET - Aplikasi Architecing untuk Perusahaan, Edisi ke-2":

var request = new OrderRequest(1234);

Mengutip, "Ada dua masalah di sini. Pertama, ketika melihat kode, orang hampir tidak bisa menebak apa yang terjadi. Contoh dari OrderRequest sedang dibuat, tetapi mengapa dan menggunakan data yang mana? Apa 1234? Ini mengarah ke masalah kedua: Anda melanggar bahasa di mana-mana dari konteks yang dibatasi. Bahasa ini mungkin mengatakan sesuatu seperti ini: pelanggan dapat mengeluarkan permintaan pesanan dan diizinkan untuk menentukan ID pembelian. Jika demikian, inilah cara yang lebih baik untuk mendapatkan contoh OrderRequest baru : "

var request = OrderRequest.CreateForCustomer(1234);

dimana

private OrderRequest() { ... }

public OrderRequest CreateForCustomer (int customerId)
{
    var request = new OrderRequest();
    ...
    return request;
}

Saya tidak menganjurkan ini untuk setiap kelas tunggal, tetapi untuk skenario DDD di atas saya pikir itu masuk akal untuk mencegah penciptaan langsung objek baru.

Morten Nørgaard
sumber