Apa arti dari 'kohesi tinggi'?

28

Saya seorang siswa yang baru-baru ini bergabung dengan perusahaan pengembangan perangkat lunak sebagai magang. Kembali di universitas, salah satu profesor saya dulu mengatakan bahwa kita harus berusaha untuk mencapai "kopling rendah dan kohesi tinggi".

Saya mengerti arti kopling rendah. Ini berarti menyimpan kode komponen yang terpisah secara terpisah, sehingga perubahan di satu tempat tidak merusak kode di tempat lain.

Namun apa yang dimaksud dengan kohesi tinggi. Jika itu berarti mengintegrasikan berbagai potongan komponen yang sama dengan baik satu sama lain, saya tidak mengerti bagaimana itu menjadi menguntungkan.

Apa yang dimaksud dengan kohesi tinggi? Bisakah contoh dijelaskan untuk memahami manfaatnya?

Maks
sumber
kemungkinan rangkap dari Apakah Ada Metrik Untuk Kohesi Dan Kopling?
nyamuk
1
Apakah artikel wikipedia tidak menjawab pertanyaan Anda dengan cukup? en.wikipedia.org/wiki/Cohesion_(computer_science)
Eoin Carroll
Ada artikel bagus tentang ini di: msdn.microsoft.com/en-us/magazine/cc947917.aspx
NoChance
1
@EoinCarroll: Sayangnya artikel wikipedia pada saat ini tidak memberikan contoh konkret yang bagus yang dapat digunakan oleh programmer baru. Teori itu bagus dan semuanya, tetapi tidak benar-benar bertahan sampai Anda telah melakukan kesalahan seputar kohesi rendah. Kohesi tinggi adalah salah satu topik yang telah membuat saya beberapa tahun pemrograman untuk sepenuhnya memahami mengapa itu penting dan bagaimana mencapainya.
Spoike
Saya tidak pernah benar-benar mengerti Kohesi sampai saya membaca Kode Bersih. Kamu juga harus.
Sebastian Redl

Jawaban:

25

Salah satu cara melihat kohesi dalam hal OO adalah jika metode di kelas menggunakan salah satu atribut pribadi. Dengan menggunakan metrik seperti LCOM4 (Kurangnya Metode Kohesif), seperti yang ditunjukkan oleh nyamuk dalam jawaban ini di sini , Anda dapat mengidentifikasi kelas-kelas yang dapat di refactored. Alasan Anda ingin memperbaiki metode atau kelas agar lebih kohesif adalah karena ia membuat desain kode lebih mudah bagi orang lain untuk menggunakannya . Percayalah kepadaku; sebagian besar pemimpin teknologi dan programmer perawatan akan menyukai Anda ketika Anda memperbaiki masalah ini.

Anda bisa menggunakan alat dalam proses pembuatan Anda seperti Sonar untuk mengidentifikasi kohesi rendah di basis kode. Ada beberapa kasus yang sangat umum yang bisa saya pikirkan di mana metode rendah dalam "kekompakan" :

Kasus 1: Metode sama sekali tidak terkait dengan kelas

Perhatikan contoh berikut:

public class Food {
   private int _foodValue = 10;

   public void Eat() {
     _foodValue -= 1;
   }

   public void Replenish() {
     _foodValue += 1;
   }

   public void Discharge() {
     Console.WriteLine("Nnngghhh!");
   }
}

Salah satu metode,, Discharge()tidak memiliki kohesi karena tidak menyentuh anggota pribadi kelas. Dalam hal ini hanya ada satu anggota pribadi: _foodValue. Jika tidak melakukan apa-apa dengan internal kelas, maka apakah itu benar-benar milik di sana Metode ini dapat dipindahkan ke kelas lain yang bisa bernama mis FoodDischarger.

// Non-cohesive function extracted to another class, which can
// be potentially reused in other contexts
public FoodDischarger {
  public void Discharge() {
    Console.WriteLine("Nnngghhh!");
  }
}

Saat Anda melakukannya dalam Javascript, karena fungsi adalah objek kelas satu, debit dapat berupa fungsi bebas:

function Food() {
    this._foodValue = 10;
}
Food.prototype.eat = function() {
    this._foodValue -= 1;
};
Food.prototype.replenish = function() {
    this._foodValue += 1;
};

// This
Food.prototype.discharge = function() {
    console.log('Nnngghhh!');
};
// can easily be refactored to:
var discharge = function() {
    console.log('Nnngghhh!');
};
// making it easily reusable without creating a class

Kasus 2: Kelas Utilitas

Ini sebenarnya adalah kasus umum yang merusak kohesi. Semua orang menyukai kelas utilitas, tetapi ini biasanya menunjukkan cacat desain dan sebagian besar waktu membuat basis kode lebih sulit untuk dipertahankan (karena ketergantungan yang tinggi terkait dengan kelas utilitas). Pertimbangkan kelas-kelas berikut:

public class Food {
    public int FoodValue { get; set; }
}

public static class FoodHelper {

    public static void EatFood(Food food) {
        food.FoodValue -= 1;
    }

    public static void ReplenishFood(Food food) {
        food.FoodValue += 1;
    }

}

Di sini kita dapat melihat bahwa kelas utilitas perlu mengakses properti di kelas Food. Metode dalam kelas utilitas tidak memiliki kohesi sama sekali dalam hal ini karena membutuhkan sumber daya luar untuk melakukan pekerjaannya. Dalam hal ini, bukankah akan lebih baik untuk memiliki metode di kelas yang mereka kerjakan sendiri (seperti dalam kasus pertama)?

Kasus 2b: Objek tersembunyi di Kelas Utilitas

Ada kasus lain dari kelas utilitas di mana ada objek domain yang belum direalisasi. Reaksi spontan pertama yang dimiliki programmer ketika memanipulasi string string adalah menulis kelas utilitas untuknya. Seperti yang ada di sini yang memvalidasi beberapa representasi string yang umum:

public static class StringUtils {

  public static bool ValidateZipCode(string zipcode) {
    // validation logic
  }

  public static bool ValidatePhoneNumber(string phoneNumber) {
    // validation logic
  }

}

Yang paling tidak disadari di sini adalah bahwa kode pos, nomor telepon, atau repesentasi string lainnya dapat menjadi objek itu sendiri:

public class ZipCode {
    private string _zipCode;
    public bool Validates() {
      // validation logic for _zipCode
    }
}

public class PhoneNumber {
    private string _phoneNumber;
    public bool Validates() {
      // validation logic for _phoneNumber
    }
}

Gagasan bahwa Anda tidak harus "menangani string" secara langsung dirinci dalam blogpost ini oleh @codemonkeyism , tetapi terkait erat dengan kohesi karena cara programmer menggunakan string dengan meletakkan logika di kelas utilitas.

Spoike
sumber
Sekarang seandainya kita bisa membuat ORM kita menangani dengan benar kelas ZipCode dan PhoneNumber kustom kita: |
Pete
+1 contoh yang bagus. Untuk poin terakhir, lihat juga sourcemaking.com/refactoring/primitive-obsession
AlexFoxGill
@Paruh ORM Anda akan menanganinya jika Anda memberikan operator konversi dari string ke tipe yang Anda tentukan (Kode Pos, Nomor Telepon): msdn.microsoft.com/en-us/library/85w54y0a.aspx
Marcus
9

Kohesi tinggi berarti menyatukan hal-hal yang serupa dan terkait, untuk menyatukan atau menggabungkan bagian-bagian yang berbagi konten, fungsi, alasan atau tujuan . Dengan kata lain, kohesi rendah misalnya bisa berarti fungsi / kelas / entitas kode yang melayani berbagai tujuan daripada menjadi " to the point ". Salah satu ide yang diusung adalah melakukan satu hal dan melakukannya dengan baik . Yang lain dapat menyertakan fakta yang jelas bahwa Anda tidak meniru fungsi serupa di banyak tempat. Ini juga meningkatkan lokalitas basis kode, hal-hal tertentu ditemukan di tempat tertentu (file, kelas, serangkaian fungsi, ...) alih-alih tersebar.

Sebagai contoh, pertimbangkan kelas yang melayani dua atau tiga tujuan: Memuat / menyimpan sumber daya (misalnya file) dan kemudian menganalisis dan menampilkan konten. Kelas semacam itu memiliki kohesi yang rendah karena mengelola setidaknya dua tugas terpisah yang tidak terkait sama sekali (file I / O, analisis dan tampilan). Desain kohesi tinggi dapat menggunakan kelas yang berbeda untuk memuat dan menyimpan sumber daya, menganalisisnya dan kemudian menampilkannya.

Di sisi lain, kopling rendah bertujuan untuk memisahkan hal-hal yang berbeda - sehingga mereka berinteraksi sesedikit mungkin yang kemudian mengurangi kompleksitas dan menyederhanakan desain.

zxcdw
sumber
7

Ini berarti bahwa bagian-bagian dari suatu objek terkait erat dengan fungsi objek tersebut. Ini berarti bahwa ada sangat sedikit atau tidak ada pemborosan dalam objek dalam hal fungsi atau tanggung jawab. Ini pada gilirannya dapat meningkatkan pemahaman tentang apa objek yang dimaksud seharusnya digunakan.

Insinyur Dunia
sumber
bukankah itu juga berlaku untuk level yang lebih tinggi dari sekadar objek? mis., pengelompokan objek / fungsi yang terkait dengan tugas di ruang nama?
stijn