CodeGym/Blog Java/rawak/Bagaimana pemfaktoran semula berfungsi di Jawa
John Squirrels
Tahap
San Francisco

Bagaimana pemfaktoran semula berfungsi di Jawa

Diterbitkan dalam kumpulan
Semasa anda belajar cara pengaturcaraan, anda menghabiskan banyak masa menulis kod. Kebanyakan pembangun permulaan percaya bahawa ini adalah perkara yang akan mereka lakukan pada masa hadapan. Ini sebahagiannya benar, tetapi tugas pengaturcara juga termasuk mengekalkan dan memfaktorkan semula kod. Hari ini kita akan bercakap tentang pemfaktoran semula. Bagaimana pemfaktoran semula berfungsi dalam Java - 1

Pemfaktoran semula pada CodeGym

Pemfaktoran semula diliputi dua kali dalam kursus CodeGym: Tugas besar memberi peluang untuk membiasakan diri dengan pemfaktoran semula sebenar melalui latihan, dan pelajaran tentang pemfaktoran semula dalam IDEA membantu anda menyelami alatan automatik yang akan menjadikan hidup anda lebih mudah.

Apakah pemfaktoran semula?

Ia mengubah struktur kod tanpa mengubah fungsinya. Sebagai contoh, katakan kita mempunyai kaedah yang membandingkan 2 nombor dan mengembalikan benar jika yang pertama lebih besar dan palsu sebaliknya:
public boolean max(int a, int b) {
    if(a > b) {
        return true;
    } else if (a == b) {
        return false;
    } else {
        return false;
    }
}
Ini adalah kod yang agak sukar digunakan. Walaupun pemula jarang menulis sesuatu seperti ini, tetapi ada peluang. Mengapa menggunakan if-elseblok jika anda boleh menulis kaedah 6 baris dengan lebih ringkas?
public boolean max(int a, int b) {
     return a > b;
}
Kini kami mempunyai kaedah mudah dan elegan yang melakukan operasi yang sama seperti contoh di atas. Beginilah cara pemfaktoran semula berfungsi: anda menukar struktur kod tanpa menjejaskan intipatinya. Terdapat banyak kaedah dan teknik pemfaktoran semula yang akan kita lihat dengan lebih dekat.

Mengapa anda memerlukan pemfaktoran semula?

Terdapat beberapa sebab. Sebagai contoh, untuk mencapai kesederhanaan dan kepekatan dalam kod. Penyokong teori ini percaya bahawa kod harus ringkas yang mungkin, walaupun beberapa dozen baris komen diperlukan untuk memahaminya. Pembangun lain yakin bahawa kod harus difaktorkan semula untuk menjadikannya mudah difahami dengan bilangan komen minimum. Setiap pasukan menggunakan kedudukannya sendiri, tetapi ingat bahawa pemfaktoran semula tidak bermakna pengurangan . Tujuan utamanya adalah untuk memperbaiki struktur kod. Beberapa tugas boleh dimasukkan dalam tujuan keseluruhan ini:
  1. Pemfaktoran semula meningkatkan pemahaman kod yang ditulis oleh pembangun lain.
  2. Ia membantu mencari dan membetulkan pepijat.
  3. Ia boleh mempercepatkan kelajuan pembangunan perisian.
  4. Secara keseluruhan, ia menambah baik reka bentuk perisian.
Jika pemfaktoran semula tidak dilakukan untuk masa yang lama, pembangunan mungkin menghadapi kesukaran, termasuk menghentikan sepenuhnya kerja.

"Kod berbau"

Apabila kod memerlukan pemfaktoran semula, ia dikatakan mempunyai "bau". Sudah tentu, tidak secara literal, tetapi kod sedemikian benar-benar tidak kelihatan sangat menarik. Di bawah ini kita akan meneroka teknik pemfaktoran semula asas untuk peringkat awal.

Kelas dan kaedah yang tidak munasabah

Kelas dan kaedah boleh menyusahkan, mustahil untuk digunakan dengan berkesan dengan tepat kerana saiznya yang besar.

Kelas besar

Kelas sedemikian mempunyai sejumlah besar baris kod dan banyak kaedah yang berbeza. Biasanya lebih mudah bagi pembangun untuk menambah ciri pada kelas sedia ada daripada mencipta yang baharu, itulah sebabnya kelas itu berkembang. Sebagai peraturan, terlalu banyak fungsi dijejalkan ke dalam kelas sedemikian. Dalam kes ini, ia membantu untuk memindahkan sebahagian daripada fungsi ke dalam kelas yang berasingan. Kami akan membincangkan perkara ini dengan lebih terperinci dalam bahagian mengenai teknik pemfaktoran semula.

Kaedah panjang

"Bau" ini timbul apabila pembangun menambah fungsi baharu pada kaedah: "Mengapa saya perlu meletakkan semakan parameter ke dalam kaedah berasingan jika saya boleh menulis kod di sini?", "Mengapa saya memerlukan kaedah carian berasingan untuk mencari maksimum elemen dalam tatasusunan? Mari kita simpan di sini. Kod akan menjadi lebih jelas dengan cara ini", dan salah tanggapan yang lain.

Terdapat dua peraturan untuk memfaktorkan semula kaedah yang panjang:

  1. Jika anda rasa ingin menambah ulasan semasa menulis kaedah, anda harus meletakkan fungsi dalam kaedah yang berasingan.
  2. Jika kaedah mengambil lebih daripada 10-15 baris kod, anda harus mengenal pasti tugas dan subtugas yang dilakukannya dan cuba meletakkan subtugasan ke dalam kaedah yang berasingan.

Terdapat beberapa cara untuk menghapuskan kaedah yang panjang:

  • Pindahkan sebahagian daripada kefungsian kaedah ke kaedah yang berasingan
  • Jika pembolehubah setempat menghalang anda daripada mengalihkan sebahagian daripada fungsi, anda boleh mengalihkan keseluruhan objek ke kaedah lain.

Menggunakan banyak jenis data primitif

Masalah ini biasanya berlaku apabila bilangan medan dalam kelas bertambah dari semasa ke semasa. Contohnya, jika anda menyimpan segala-galanya (mata wang, tarikh, nombor telefon, dll.) dalam jenis atau pemalar primitif dan bukannya objek kecil. Dalam kes ini, amalan yang baik ialah memindahkan kumpulan logik medan ke dalam kelas berasingan (kelas ekstrak). Anda juga boleh menambah kaedah pada kelas untuk memproses data.

Terlalu banyak parameter

Ini adalah kesilapan yang agak biasa, terutamanya dalam kombinasi dengan kaedah yang panjang. Biasanya, ia berlaku jika kaedah mempunyai terlalu banyak fungsi, atau jika kaedah melaksanakan berbilang algoritma. Senarai panjang parameter adalah sangat sukar untuk difahami, dan menggunakan kaedah dengan senarai sedemikian adalah menyusahkan. Akibatnya, lebih baik untuk melepasi keseluruhan objek. Jika objek tidak mempunyai data yang mencukupi, anda harus menggunakan objek yang lebih umum atau membahagikan fungsi kaedah supaya setiap kaedah memproses data yang berkaitan secara logik.

Kumpulan data

Kumpulan data yang berkaitan secara logik sering muncul dalam kod. Contohnya, parameter sambungan pangkalan data (URL, nama pengguna, kata laluan, nama skema, dll.). Jika tiada satu medan boleh dialih keluar daripada senarai medan, maka medan ini harus dialihkan ke kelas berasingan (kelas ekstrak).

Penyelesaian yang melanggar prinsip OOP

"Bau" ini berlaku apabila pembangun melanggar reka bentuk OOP yang betul. Ini berlaku apabila dia tidak memahami sepenuhnya keupayaan OOP dan gagal menggunakannya sepenuhnya atau betul.

Kegagalan menggunakan warisan

Jika subkelas hanya menggunakan subset kecil fungsi kelas induk, maka ia berbau hierarki yang salah. Apabila ini berlaku, biasanya kaedah yang berlebihan tidak ditindih atau mereka membuang pengecualian. Satu kelas mewarisi kelas lain membayangkan bahawa kelas anak menggunakan hampir semua fungsi kelas induk. Contoh hierarki yang betul: Bagaimana pemfaktoran semula berfungsi dalam Java - 2Contoh hierarki yang salah: Bagaimana pemfaktoran semula berfungsi dalam Java - 3

Tukar kenyataan

Apa yang boleh salah dengan switchkenyataan? Ia buruk apabila ia menjadi sangat kompleks. Masalah yang berkaitan ialah sejumlah besar ifpernyataan bersarang.

Kelas alternatif dengan antara muka yang berbeza

Berbilang kelas melakukan perkara yang sama, tetapi kaedah mereka mempunyai nama yang berbeza.

Medan sementara

Jika kelas mempunyai medan sementara yang diperlukan objek hanya sekali-sekala apabila nilainya ditetapkan, dan ia kosong atau, Allah melarang, nullsepanjang masa, maka kod itu berbau. Ini adalah keputusan reka bentuk yang boleh dipersoalkan.

Bau yang menyukarkan pengubahsuaian

Bau ini lebih serius. Bau lain terutamanya menjadikannya lebih sukar untuk memahami kod, tetapi ini menghalang anda daripada mengubah suainya. Apabila anda cuba memperkenalkan sebarang ciri baharu, separuh daripada pembangun berhenti, dan separuh menjadi gila.

Hierarki warisan selari

Masalah ini muncul dengan sendirinya apabila subkelas kelas memerlukan anda mencipta subkelas lain untuk kelas lain.

Kebergantungan yang diedarkan secara seragam

Sebarang pengubahsuaian memerlukan anda mencari semua kegunaan kelas (bergantungan) dan membuat banyak perubahan kecil. Satu perubahan — suntingan dalam banyak kelas.

Pokok pengubahsuaian yang kompleks

Bau ini adalah bertentangan dengan yang sebelumnya: perubahan mempengaruhi sejumlah besar kaedah dalam satu kelas. Sebagai peraturan, kod tersebut mempunyai pergantungan bertingkat: menukar satu kaedah memerlukan anda membetulkan sesuatu dalam yang lain, dan kemudian pada yang ketiga dan seterusnya. Satu kelas — banyak perubahan.

"Bau sampah"

Kategori bau yang agak tidak menyenangkan yang menyebabkan sakit kepala. Tidak berguna, tidak perlu, kod lama. Nasib baik, IDE dan linter moden telah belajar untuk memberi amaran tentang bau sedemikian.

Sebilangan besar ulasan dalam kaedah

Kaedah mempunyai banyak ulasan penjelasan pada hampir setiap baris. Ini biasanya disebabkan oleh algoritma yang kompleks, jadi adalah lebih baik untuk membahagikan kod kepada beberapa kaedah yang lebih kecil dan memberi mereka nama penjelasan.

Kod pendua

Kelas atau kaedah yang berbeza menggunakan blok kod yang sama.

Kelas malas

Kelas menggunakan fungsi yang sangat sedikit, walaupun ia dirancang untuk menjadi besar.

Kod yang tidak digunakan

Kelas, kaedah atau pembolehubah tidak digunakan dalam kod dan adalah berat mati.

Sambungan yang berlebihan

Kategori bau ini dicirikan oleh sejumlah besar perhubungan yang tidak wajar dalam kod.

Kaedah luaran

Kaedah menggunakan data daripada objek lain lebih kerap daripada datanya sendiri.

Keintiman yang tidak wajar

Kelas bergantung pada butiran pelaksanaan kelas lain.

Panggilan kelas panjang

Satu kelas memanggil yang lain, yang meminta data daripada yang ketiga, yang mendapat data dari yang keempat, dan seterusnya. Rangkaian panggilan yang begitu panjang bermakna pergantungan yang tinggi pada struktur kelas semasa.

Kelas pengedar tugas

Kelas diperlukan hanya untuk menghantar tugasan ke kelas lain. Mungkin ia perlu dikeluarkan?

Teknik pemfaktoran semula

Di bawah ini kita akan membincangkan teknik pemfaktoran semula asas yang boleh membantu menghilangkan bau kod yang diterangkan.

Ekstrak kelas

Kelas menjalankan terlalu banyak fungsi. Sebahagian daripada mereka mesti dipindahkan ke kelas lain. Sebagai contoh, katakan kita mempunyai Humankelas yang turut menyimpan alamat rumah dan mempunyai kaedah yang mengembalikan alamat penuh:
class Human {
    private String name;
    private String age;
    private String country;
    private String city;
    private String street;
    private String house;
    private String quarter;

    public String getFullAddress() {
        StringBuilder result = new StringBuilder();
        return result
                        .append(country)
                        .append(", ")
                        .append(city)
                        .append(", ")
                        .append(street)
                        .append(", ")
                        .append(house)
                        .append(" ")
                        .append(quarter).toString();
    }
 }
Amalan yang baik untuk meletakkan maklumat alamat dan kaedah yang berkaitan (tingkah laku pemprosesan data) ke dalam kelas yang berasingan:
class Human {
   private String name;
   private String age;
   private Address address;

   private String getFullAddress() {
       return address.getFullAddress();
   }
}
class Address {
   private String country;
   private String city;
   private String street;
   private String house;
   private String quarter;

   public String getFullAddress() {
       StringBuilder result = new StringBuilder();
       return result
                       .append(country)
                       .append(", ")
                       .append(city)
                       .append(", ")
                       .append(street)
                       .append(", ")
                       .append(house)
                       .append(" ")
                       .append(quarter).toString();
   }
}

Ekstrak kaedah

Jika kaedah mempunyai beberapa fungsi yang boleh diasingkan, anda harus meletakkannya dalam kaedah yang berasingan. Sebagai contoh, kaedah yang mengira punca-punca persamaan kuadratik:
public void calcQuadraticEq(double a, double b, double c) {
    double D = b * b - 4 * a * c;
    if (D > 0) {
        double x1, x2;
        x1 = (-b - Math.sqrt(D)) / (2 * a);
        x2 = (-b + Math.sqrt(D)) / (2 * a);
        System.out.println("x1 = " + x1 + ", x2 = " + x2);
    }
    else if (D == 0) {
        double x;
        x = -b / (2 * a);
        System.out.println("x = " + x);
    }
    else {
        System.out.println("Equation has no roots");
    }
}
Kami mengira setiap tiga pilihan yang mungkin dalam kaedah berasingan:
public void calcQuadraticEq(double a, double b, double c) {
    double D = b * b - 4 * a * c;
    if (D > 0) {
        dGreaterThanZero(a, b, D);
    }
    else if (D == 0) {
        dEqualsZero(a, b);
    }
    else {
        dLessThanZero();
    }
}

public void dGreaterThanZero(double a, double b, double D) {
    double x1, x2;
    x1 = (-b - Math.sqrt(D)) / (2 * a);
    x2 = (-b + Math.sqrt(D)) / (2 * a);
    System.out.println("x1 = " + x1 + ", x2 = " + x2);
}

public void dEqualsZero(double a, double b) {
    double x;
    x = -b / (2 * a);
    System.out.println("x = " + x);
}

public void dLessThanZero() {
    System.out.println("Equation has no roots");
}
Setiap kod kaedah telah menjadi lebih pendek dan lebih mudah difahami.

Melepasi keseluruhan objek

Apabila kaedah dipanggil dengan parameter, kadangkala anda mungkin melihat kod seperti ini:
public void employeeMethod(Employee employee) {
    // Some actions
    double yearlySalary = employee.getYearlySalary();
    double awards = employee.getAwards();
    double monthlySalary = getMonthlySalary(yearlySalary, awards);
    // Continue processing
}

public double getMonthlySalary(double yearlySalary, double awards) {
     return (yearlySalary + awards)/12;
}
Ia employeeMethodmempunyai 2 baris keseluruhan yang dikhaskan untuk menerima nilai dan menyimpannya dalam pembolehubah primitif. Kadangkala binaan sedemikian boleh mengambil masa sehingga 10 baris. Lebih mudah untuk melepasi objek itu sendiri dan menggunakannya untuk mengekstrak data yang diperlukan:
public void employeeMethod(Employee employee) {
    // Some actions
    double monthlySalary = getMonthlySalary(employee);
    // Continue processing
}

public double getMonthlySalary(Employee employee) {
    return (employee.getYearlySalary() + employee.getAwards())/12;
}

Ringkas, ringkas dan padat.

Secara logik mengumpulkan medan dan mengalihkannya ke dalam classDespitefakta yang berasingan bahawa contoh di atas adalah sangat mudah, dan apabila anda melihatnya, ramai di antara anda mungkin bertanya, "Siapa yang melakukan ini?", ramai pembangun melakukan kesilapan struktur sedemikian kerana kecuaian, keengganan untuk memfaktorkan semula kod, atau sekadar sikap "itu sudah cukup baik".

Mengapa pemfaktoran semula berkesan

Hasil daripada pemfaktoran semula yang baik, program mempunyai kod yang mudah dibaca, prospek untuk mengubah logiknya tidak menakutkan, dan memperkenalkan ciri baharu tidak menjadi analisis kod neraka, tetapi sebaliknya merupakan pengalaman yang menyenangkan selama beberapa hari . Anda tidak seharusnya memfaktorkan semula jika lebih mudah untuk menulis program dari awal. Sebagai contoh, katakan pasukan anda menganggarkan bahawa tenaga kerja yang diperlukan untuk memahami, menganalisis dan kod refactor akan lebih besar daripada melaksanakan fungsi yang sama dari awal. Atau jika kod yang akan difaktorkan semula mempunyai banyak masalah yang sukar untuk dinyahpepijat. Mengetahui cara menambah baik struktur kod adalah penting dalam kerja pengaturcara. Dan pembelajaran untuk memprogram dalam Java dilakukan dengan terbaik di CodeGym, kursus dalam talian yang menekankan amalan. 1200+ tugas dengan pengesahan segera, kira-kira 20 projek mini, tugasan permainan — semua ini akan membantu anda berasa yakin dalam pengekodan. Masa terbaik untuk bermula ialah sekarang :)

Sumber untuk lebih melibatkan diri dalam pemfaktoran semula

Buku yang paling terkenal mengenai pemfaktoran semula ialah "Pemfaktoran Semula. Memperbaik Reka Bentuk Kod Sedia Ada" oleh Martin Fowler. Terdapat juga penerbitan yang menarik tentang pemfaktoran semula, berdasarkan buku sebelumnya: "Memfaktorkan Semula Menggunakan Corak" oleh Joshua Kerievsky. Bercakap tentang corak... Apabila memfaktorkan semula, ia sentiasa sangat berguna untuk mengetahui corak reka bentuk asas. Buku-buku yang sangat baik ini akan membantu dalam perkara ini: Bercakap tentang corak... Apabila memfaktorkan semula, adalah sangat berguna untuk mengetahui corak reka bentuk asas. Buku-buku yang sangat baik ini akan membantu dengan ini:
  1. "Corak Reka Bentuk" oleh Eric Freeman, Elizabeth Robson, Kathy Sierra, dan Bert Bates, daripada siri Head First
  2. "The Art of Readable Code" oleh Dustin Boswell dan Trevor Foucher
  3. "Code Complete" oleh Steve McConnell, yang menetapkan prinsip untuk kod yang cantik dan elegan.
Komen
  • Popular
  • Baru
  • Tua
Anda mesti log masuk untuk meninggalkan ulasan
Halaman ini tidak mempunyai sebarang ulasan lagi