CodeGym /Blog Jawa /Acak /SOLID: Lima prinsip dhasar desain kelas ing Jawa
John Squirrels
tingkat
San Francisco

SOLID: Lima prinsip dhasar desain kelas ing Jawa

Diterbitake ing grup
Kelas minangka blok bangunan aplikasi. Kaya bata ing bangunan. Kelas sing ditulis kanthi apik bisa nyebabake masalah. SOLID: Lima prinsip dhasar desain kelas ing Jawa - 1Kanggo mangerteni apa kelas ditulis kanthi bener, sampeyan bisa mriksa cara ngukur nganti "standar kualitas". Ing Jawa, iki sing diarani prinsip SOLID, lan kita bakal ngomong babagan iki.

Prinsip SOLID ing Jawa

SOLID minangka akronim sing dibentuk saka huruf kapital saka limang prinsip pisanan OOP lan desain kelas. Prinsip kasebut diandharake dening Robert Martin ing awal taun 2000-an, lan banjur singkatan kasebut ditepungi dening Michael Feathers. Mangkene prinsip SOLID:
  1. Prinsip Tanggung Jawab Tunggal
  2. Bukak Prinsip Tertutup
  3. Prinsip Substitusi Liskov
  4. Prinsip Segregasi Antarmuka
  5. Prinsip Inversi Dependensi

Prinsip Tanggung Jawab Tunggal (SRP)

Prinsip iki nyatakake yen ora ana luwih saka siji alasan kanggo ngganti kelas. Saben obyek duwe tanggung jawab siji, sing wis encapsulated ing kelas. Kabeh layanan kelas ditujokake kanggo ndhukung tanggung jawab iki. Kelas kasebut mesthi gampang diowahi yen perlu, amarga jelas kelas kasebut lan ora tanggung jawab. Kanthi tembung liyane, kita bakal bisa nggawe owah-owahan lan ora wedi karo akibate, yaiku impact ing obyek liyane. Kajaba iku, kode kasebut luwih gampang dites, amarga tes sampeyan nyakup siji fungsi sing ora ana gandhengane karo kabeh liyane. Mbayangno modul sing proses pesenan. Yen pesenan digawe kanthi bener, modul iki disimpen ing database lan ngirim email kanggo konfirmasi pesenan:

public class OrderProcessor {

    public void process(Order order){
        if (order.isValid() && save(order)) {
            sendConfirmationEmail(order);
        }
    }

    private boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // Save the order in the database

        return true;
    }

    private void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Send an email to the customer
    }
}
Modul iki bisa diganti amarga telung alasan. Kaping pisanan, logika kanggo ngolah pesenan bisa uga diganti. Kapindho, cara pesenan disimpen (jinis database) bisa diganti. Katelu, cara konfirmasi dikirim bisa diganti (contone, kita kudu ngirim pesen teks tinimbang email). Prinsip tanggung jawab tunggal nuduhake yen telung aspek saka masalah iki sejatine telung tanggung jawab sing beda. Tegese kudu ana ing kelas utawa modul sing beda. Nggabungake sawetara entitas sing bisa diganti ing wektu sing beda-beda lan kanthi alasan sing beda-beda dianggep minangka keputusan desain sing ora apik. Luwih becik pamisah modul dadi telung modul sing kapisah, sing saben-saben nindakake fungsi siji:

public class MySQLOrderRepository {
    public boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // Save the order in the database

        return true;
    }
}

public class ConfirmationEmailSender {
    public void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Send an email to the customer
    }
}

public class OrderProcessor {
    public void process(Order order){

        MySQLOrderRepository repository = new MySQLOrderRepository();
        ConfirmationEmailSender mailSender = new ConfirmationEmailSender();

        if (order.isValid() && repository.save(order)) {
            mailSender.sendConfirmationEmail(order);
        }
    }

}

Prinsip Tertutup (OCP)

Prinsip iki diterangake kaya ing ngisor iki: entitas piranti lunak (kelas, modul, fungsi, lan liya-liyane) kudu mbukak kanggo ekstensi, nanging ditutup kanggo modifikasi . Iki tegese iku kudu bisa kanggo ngganti prilaku external kelas kang tanpa owah-owahan kanggo kode ana kelas. Miturut prinsip iki, kelas dirancang supaya tweaking kelas pas kondisi tartamtu mung mbutuhake ndawakake lan overriding sawetara fungsi. Iki tegese sistem kudu fleksibel, bisa digunakake ing kahanan ganti tanpa ngganti kode sumber. Terusake conto sing nglibatake pangolahan pesenan, umpamane kita kudu nindakake sawetara tumindak sadurunge pesenan diproses uga sawise email konfirmasi dikirim. Tinimbang nggantiOrderProcessorkelas dhewe, kita bakal ngluwihi kanggo ngrampungake tujuan kita tanpa nglanggar Prinsip Terbuka Tertutup:

public class OrderProcessorWithPreAndPostProcessing extends OrderProcessor {

    @Override
    public void process(Order order) {
        beforeProcessing();
        super.process(order);
        afterProcessing();
    }
    
    private void beforeProcessing() {
        // Take some action before processing the order
    }
    
    private void afterProcessing() {
        // Take some action after processing the order
    }
}

Prinsip Substitusi Liskov (LSP)

Iki minangka variasi saka prinsip tertutup sing wis kasebut sadurunge. Bisa ditetepake kaya ing ngisor iki: obyek bisa diganti karo obyek subkelas tanpa ngganti properti program. Iki tegese kelas sing digawe kanthi nggedhekake kelas dhasar kudu ngatasi metode kasebut supaya fungsi kasebut ora dikompromi saka sudut pandang klien. Yaiku, yen pangembang ngluwihi kelas sampeyan lan digunakake ing aplikasi, dheweke ora kudu ngganti prilaku sing dikarepake saka metode sing ditindhes. Subkelas kudu ngatasi metode kelas dasar supaya fungsine ora rusak saka sudut pandang klien. Kita bisa njelajah iki kanthi rinci ing conto ing ngisor iki. Upaminipun kita duwe kelas sing tanggung jawab kanggo validasi pesenan lan mriksa apa kabeh barang ing urutan ing Simpenan.isValid()cara sing ngasilake bener utawa salah :

public class OrderStockValidator {

    public boolean isValid(Order order) {
        for (Item item : order.getItems()) {
            if (!item.isInStock()) {
                return false;
            }
        }

        return true;
    }
}
Upaminipun uga sawetara pesenan kudu divalidasi beda saka liyane, contone, kanggo sawetara pesenan kita kudu mriksa apa kabeh barang ing urutan ing Simpenan lan apa kabeh barang wis dikempalken. Kanggo nindakake iki, kita ngluwihi OrderStockValidatorkelas kanthi nggawe OrderStockAndPackValidatorkelas:

public class OrderStockAndPackValidator extends OrderStockValidator {

    @Override
    public boolean isValid(Order order) {
        for (Item item : order.getItems()) {
            if ( !item.isInStock() || !item.isPacked() ){
                throw new IllegalStateException(
                     String.format("Order %d is not valid!", order.getId())
                );
            }
        }

        return true;
    }
}
Nanging ing kene kita wis nglanggar prinsip substitusi Liskov, amarga tinimbang bali palsu yen pesenan gagal validasi, cara kita mbuwang IllegalStateException. Klien sing nggunakake kode iki ora ngarep-arep iki: padha ngarepake nilai bali sing bener utawa salah . Iki bisa nyebabake kesalahan runtime.

Prinsip Segregasi Antarmuka (ISP)

Prinsip iki ditondoi dening pernyataan ing ngisor iki: klien ora kudu dipeksa ngetrapake metode sing ora bakal digunakake . Prinsip pamisahan antarmuka tegese antarmuka sing banget "kandel" kudu dipérang dadi luwih cilik, luwih spesifik, supaya klien sing nggunakake antarmuka cilik mung ngerti babagan cara sing dibutuhake kanggo karya. Akibaté, nalika cara antarmuka diganti, klien apa wae sing ora nggunakake metode kasebut ora kudu diganti. Coba conto iki: Alex, pangembang, wis nggawe antarmuka "laporan" lan nambah rong cara: generateExcel()langeneratedPdf(). Saiki klien pengin nggunakake antarmuka iki, nanging mung arep nggunakake laporan ing format PDF, ora ing Excel. Apa fungsi iki bakal gawe marem klien iki? Ora. Klien kudu ngleksanakake rong cara, salah sijine ora dibutuhake lan mung ana thanks kanggo Alex, sing ngrancang piranti lunak kasebut. Klien bakal nggunakake antarmuka sing beda utawa ora nindakake apa-apa karo metode laporan Excel. Dadi apa solusine? Iku kanggo pamisah antarmuka sing wis ana dadi loro cilik. Siji kanggo laporan PDF, liyane kanggo laporan Excel. Iki ngidini klien nggunakake mung fungsi sing dibutuhake.

Prinsip Pembalikan Ketergantungan (DIP)

Ing Jawa, prinsip SOLID iki diterangake ing ngisor iki: dependensi ing sistem dibangun adhedhasar abstraksi. Modul tingkat sing luwih dhuwur ora gumantung marang modul tingkat ngisor. Abstraksi ngirim ora gumantung ing rincian. Rincian kudu gumantung ing abstraksi. Piranti lunak kudu dirancang supaya macem-macem modul bisa mandhiri lan disambungake menyang siji liyane liwat abstraksi. Aplikasi klasik saka prinsip iki yaiku Spring Framework. Ing Spring Framework, kabeh modul dileksanakake minangka komponen kapisah sing bisa bebarengan. Padha otonomi banget supaya bisa digunakake kanthi gampang ing modul program kajaba Spring Framework. Iki digayuh amarga gumantung saka prinsip sing ditutup lan mbukak. Kabeh modul menehi akses mung kanggo abstraksi, kang bisa digunakake ing modul liyane. Ayo dadi nyoba kanggo ilustrasi iki nggunakake conto. Ngomong babagan prinsip tanggung jawab tunggal, kita nganggepOrderProcessorkelas. Ayo deleng maneh kode kelas iki:

public class OrderProcessor {
    public void process(Order order){

        MySQLOrderRepository repository = new MySQLOrderRepository();
        ConfirmationEmailSender mailSender = new ConfirmationEmailSender();

        if (order.isValid() && repository.save(order)) {
            mailSender.sendConfirmationEmail(order);
        }
    }

}
Ing conto iki, OrderProcessorkelas kita gumantung ing rong kelas tartamtu: MySQLOrderRepositorylan ConfirmationEmailSender. Kita uga bakal nampilake kode kelas kasebut:

public class MySQLOrderRepository {
    public boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // Save the order in the database

        return true;
    }
}

public class ConfirmationEmailSender {
    public void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Send an email to the customer
    }
}
Kelas-kelas iki adoh saka apa sing diarani abstraksi. Lan saka sudut pandang prinsip inversi dependensi, luwih becik diwiwiti kanthi nggawe sawetara abstraksi sing bisa ditindakake ing mangsa ngarep, tinimbang implementasine tartamtu. Ayo nggawe rong antarmuka: MailSenderlan OrderRepository). Iki bakal dadi abstraksi kita:

public interface MailSender {
    void sendConfirmationEmail(Order order);
}

public interface OrderRepository {
    boolean save(Order order);
}
Saiki kita ngetrapake antarmuka kasebut ing kelas sing wis disiapake kanggo iki:

public class ConfirmationEmailSender implements MailSender {

    @Override
    public void sendConfirmationEmail(Order order) {
        String name = order.getCustomerName();
        String email = order.getCustomerEmail();

        // Send an email to the customer
    }

}

public class MySQLOrderRepository implements OrderRepository {

    @Override
    public boolean save(Order order) {
        MySqlConnection connection = new MySqlConnection("database.url");
        // Save the order in the database

        return true;
    }
}
Kita nindakake karya preparatory supaya OrderProcessorkelas kita gumantung, ora ing rincian konkrit, nanging ing abstraksi. Kita bakal ngganti kanthi nambahake dependensi menyang konstruktor kelas:

public class OrderProcessor {

    private MailSender mailSender;
    private OrderRepository repository;

    public OrderProcessor(MailSender mailSender, OrderRepository repository) {
        this.mailSender = mailSender;
        this.repository = repository;
    }

    public void process(Order order){
        if (order.isValid() && repository.save(order)) {
            mailSender.sendConfirmationEmail(order);
        }
    }
}
Saiki kelas kita gumantung ing abstraksi, dudu implementasi spesifik. Kita bisa gampang ngganti prilaku kanthi nambahake ketergantungan sing dikarepake nalika obyek OrderProcessordigawe. Kita wis nliti prinsip desain SOLID ing Jawa. Sampeyan bakal sinau luwih lengkap babagan OOP ing umum lan dhasar pemrograman Java — ora ana sing mboseni lan latihan atusan jam — ing kursus CodeGym. Wektu kanggo ngrampungake sawetara tugas :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION