Enam prinsip corak reka bentuk: 1. Prinsip tanggungjawab tunggal, terasnya adalah untuk mengawal kebutiran kelas, memisahkan objek, dan meningkatkan kesepaduan mereka; 2. Prinsip pembukaan dan penutup, yang boleh dicapai melalui "kekangan abstrak", perubahan enkapsulasi" untuk dicapai; 3. Prinsip penggantian Liskov terutamanya menerangkan beberapa prinsip mengenai warisan; 4. Prinsip penyongsangan kebergantungan mengurangkan gandingan antara klien dan modul pelaksanaan; 5. Prinsip pengasingan antara muka adalah untuk mengekang antara muka , Mengurangkan pergantungan kelas pada antara muka 6. Undang-undang Demeter memerlukan mengehadkan lebar dan kedalaman komunikasi antara entiti perisian.
Persekitaran pengendalian tutorial ini: sistem Windows 7, versi Java 8, komputer DELL G3.
Mengenai corak reka bentuk, saya telah membaca banyak buku corak reka bentuk suatu masa dahulu, beberapa daripadanya beberapa kali, dan saya sentiasa berharap bahawa saya boleh menggunakan corak reka bentuk ini semasa mengekod. Walau bagaimanapun, dalam pengekodan harian, singleton paling banyak digunakan, diikuti oleh pola pemerhati dan pembina (pembina), yang digunakan lebih kerap, dan yang lain jarang digunakan.
Sebab mengapa ia tidak digunakan ialah mereka masih tidak memahami idea corak reka bentuk dan tidak boleh menghubungkan corak reka bentuk ini dengan masalah yang dihadapi dalam pengekodan, jadi mereka tidak boleh menggunakan corak reka bentuk.
Malah, corak reka bentuk dicadangkan untuk menyelesaikan masalah biasa. Oleh itu, apabila anda berfikir tentang corak reka bentuk yang mana untuk diguna pakai, anda harus terlebih dahulu bertanya kepada diri sendiri apakah masalah semasa? Pilih corak reka bentuk yang sesuai berdasarkan masalah.
Selepas anda membiasakan diri dengan corak reka bentuk, anda akan mendapati bahawa terdapat hubungan inklusif antara beberapa corak reka bentuk, malah ia sangat serupa, tetapi corak reka bentuk yang berbeza menyelesaikan masalah yang berbeza.
Apabila kami mereka bentuk modul, kami boleh mempertimbangkannya dari perspektif berikut:
Apakah hubungan antara modul ini dengan modul lain?
Bahagian modul manakah yang malar, bahagian mana yang sentiasa berubah, dan bagaimana?
Apakah hubungan antara kelas Mengapa kita perlu bergantung kepada mereka?
Adakah anda mahu menambah antara muka? Apakah masalah yang wujud antara muka untuk diselesaikan?
Sudah tentu, artikel ini tidak mengajar anda cara menggunakan corak reka bentuk. Sebaliknya, ia menerangkan prinsip reka bentuk corak reka bentuk. Corak reka bentuk juga mengikut beberapa peraturan apabila ia direka bentuk.
Enam prinsip corak reka bentuk adalah seperti berikut:
Prinsip tanggungjawab tunggal (kelas, kaedah, antara muka)
Prinsip pembuka dan penutup (terbuka untuk sambungan, ditutup untuk pengubahsuaian)
Prinsip penggantian Liskov (hubungan antara kelas asas dan subkelas )
Prinsip Penyongsangan Kebergantungan (bergantung pada antara muka abstrak, bukan objek konkrit)
Prinsip pengasingan antara muka (antara muka dibahagikan mengikut fungsi)
Hukum Demeter (hubungan rapat antara kelas)
Terdapat kurungan di sebelah setiap prinsip reka bentuk untuk menerangkan atau menerangkan skop aplikasi. Setiap prinsip diterangkan secara terperinci di bawah.
Prinsip Tanggungjawab Tunggal (SRP) juga dipanggil prinsip fungsi tunggal. Tanggungjawab di sini merujuk kepada sebab perubahan kelas Prinsip tanggungjawab tunggal menetapkan bahawa kelas harus mempunyai dan hanya satu sebab untuk perubahannya, jika tidak kelas itu harus dipecahkan (Tidak boleh ada lebih daripada satu sebab untuk kelas. untuk berubah).
Prinsip ini menyatakan bahawa objek tidak boleh mengambil terlalu banyak tanggungjawab Jika objek mengambil terlalu banyak tanggungjawab, akan terdapat sekurang-kurangnya dua kelemahan berikut:
Perubahan dalam satu tanggungjawab mungkin melemahkan atau menghalang keupayaan kelas ini untuk melaksanakan tanggungjawab lain
Apabila pelanggan memerlukan tanggungjawab tertentu; objek, ia mestilah tidak Tidak termasuk semua tanggungjawab lain yang tidak perlu membawa kepada kod berlebihan atau kod terbuang.
Kelebihan Prinsip Tanggungjawab Tunggal
Teras Prinsip Tanggungjawab Tunggal adalah untuk mengawal kebutiran kelas. Jika anda mengikuti prinsip tanggungjawab tunggal, anda akan mendapat kelebihan berikut.
Kurangkan kerumitan kelas. Jika kelas bertanggungjawab untuk hanya satu tanggungjawab, logiknya pasti lebih mudah berbanding jika ia bertanggungjawab untuk pelbagai tanggungjawab.
Tingkatkan kebolehbacaan kelas. Kerumitan dikurangkan, dan kebolehbacaan dipertingkatkan secara semula jadi.
Meningkatkan kebolehselenggaraan sistem. Kebolehbacaan yang dipertingkatkan secara semula jadi akan menjadikannya lebih mudah untuk diselenggara.
Pengurangan risiko yang disebabkan oleh perubahan. Perubahan tidak dapat dielakkan Jika prinsip tanggungjawab tunggal dipatuhi dengan baik, apabila satu fungsi diubah suai, kesan ke atas fungsi lain boleh dikurangkan dengan ketara.
Bagaimana untuk melaksanakan prinsip tanggungjawab tunggal
Prinsip tanggungjawab tunggal adalah yang paling mudah tetapi paling sukar untuk menerapkan Prinsip ini memerlukan pereka bentuk untuk menemui dan memisahkan tanggungjawab yang berbeza bagi sesebuah kelas, dan kemudian merangkumnya ke dalam kelas atau modul yang berbeza. Pelbagai tanggungjawab kelas penemuan memerlukan pereka bentuk mempunyai keupayaan analisis dan reka bentuk yang kukuh serta pengalaman pemfaktoran semula yang berkaitan.
Contoh
public interface UserService { public void login(String username, String password); public void register(String email, String username, String password); public void logError(String msg); public void sendEmail(String email); }
这段代码很显然存在很大的问题,UserService 既要负责用户的注册和登录,还要负责日志的记录和邮件的发送,并且后者的行为明显区别于前者。<br>
假设我要修改发送邮件的逻辑就得修改这个类,这时候 qa 还得回归登录注册逻辑,这样明显不合理。
Jadi kita perlu lakukan Split, mengikut fungsi tertentu, ia boleh dibahagikan seperti berikut:
UserService: hanya bertanggungjawab untuk log masuk dan pendaftaran
public interface UserService { public void login(String username, String password); public void register(String email, String username, String password); }
LogService: 只负责日志<br>
public interface LogService { public void logError(String msg); }
EmailService: Hanya bertanggungjawab untuk menghantar e-mel
public interface EmailService { public void sendEmail(String email); }
这时候,咱们再去回顾前面提到的优点,就能深深体会了。
Di sini kita hanya bercakap tentang antara muka Sebenarnya, ia adalah sama untuk kelas, malah kaedahnya adalah sama.
Untuk kelas, berdasarkan nama kelas, pastikan semua kaedah yang disediakan tergolong dalam kelas ini.
Untuk kaedah, jangan hantar kejadian objek yang tidak berkaitan sebagai parameter. Jika anda mendapati bahawa kaedah bergantung pada objek yang tidak berkaitan, mungkin terdapat masalah dengan pelaksanaan kaedah tersebut.
Sebagai contoh, selepas memuat turun imej dalam android dan memaparkannya dalam imageView, saya menyediakan kaedah berikut:
loadImage(String url, ImageView view) { // 下载图片,展示图片 }
Untuk kaedah loadImage, url parameter ialah ok, tetapi Parameter ImageView tidak munasabah. Kerana dua operasi dilakukan di sini, memuat turun gambar dan memaparkan gambar. Kaedah ini harus dibahagikan kepada:
// 下载图片 loadImage(String url) { } // 显示图片 displayImage(String url, ImageView view) { // 调用 getBitmap (url) 获取图片 // 获取图片后将其设置到 view 中。 } // 根据 url 获取图片, getBitmap(String url) { }
supaya keseluruhan logiknya jelas. Jika anda perlu mengubah suai logik muat turun kemudian, ia tidak akan menjejaskan logik paparan. Sudah tentu, sebenarnya terdapat satu lagi soalan: adakah kedua-dua kaedah ini perlu diletakkan dalam kelas?
Cara melaksanakan prinsip pembukaan dan penutup: Prinsip pembukaan dan penutup boleh direalisasikan melalui "kekangan abstrak dan perubahan enkapsulasi" , iaitu melalui antara muka atau kelas Abstrak mentakrifkan lapisan abstraksi yang agak stabil untuk entiti perisian dan merangkum faktor pembolehubah yang sama dalam kelas pelaksanaan konkrit yang sama.
Oleh kerana abstraksi mempunyai fleksibiliti yang baik dan kebolehsuaian yang luas, selagi abstraksi adalah munasabah, kestabilan seni bina perisian pada asasnya boleh dikekalkan. Butiran yang tidak menentu dalam perisian boleh dilanjutkan daripada kelas pelaksanaan yang diperoleh daripada abstraksi Apabila perisian perlu diubah, anda hanya perlu memperoleh semula kelas pelaksanaan mengikut keperluan untuk melanjutkannya.
Contoh
// 矩形 public class Rectangle { public double getWidth() { return width; } public double getHeight() { return height; } }
需要计算矩形的面积
// 面积计算器 public class AreaCalculator { public double area(Rectangle shape){ return shape.getWidth() * shape.getHeight(); } }
Andaikan pada masa ini , Terdapat satu lagi kelas bulatan
// 圆形 public class Circular { public double getRadius(){ return radius; } }
同样也需要计算他的面积,这时候就会变成下面这样子:
public class AreaCalculator { public double area(Object shape){ if(shape instanceof Rectangle) { Rectangle rectangle = (Rectangle) shape; return rectangle.getWidth() * rectangle.getHeight(); } else if (shape instanceof Circular) { Circular circular = (Circular) shape; return circular.getRadius() * circular.getRadius() * Math.PI; } else { throw new RuntimeException("There is no such type."); } } }
Dengan perubahan ini selesai, tiada masalah sama sekali . Walau bagaimanapun, dalam persekitaran pengeluaran sebenar, keadaan lebih rumit dan perubahan melibatkan banyak bahagian, yang mungkin menjejaskan seluruh badan. Selain itu, beberapa fungsi yang ditulis dan diuji sebelum ini perlu diuji semula, malah menyebabkan beberapa fungsi menjadi tidak tersedia.
Versi yang dipertingkatkan, menjadikan logik awam mengira kawasan menjadi antara muka:
public interface Shape { public double getArea(); } public class Rectangle implements Shape{ public double getWidth() { return width; } public double getHeight() { return height; } public double getArea() { return getWidth() * getHeight(); } }
Dengan cara ini, apabila diperlukan Tukar, apabila kita perlu mengira luas bulatan, kita hanya perlu mencipta kelas bulatan dan melaksanakan antara muka Bentuk: <code class="java language-java">这样,当需求变更,需要计算圆形面积的时候,我们只需创建一个圆形的类,并实现 Shape 接口即可:<br>
public class Circular implements Shape { public double getRadius(){ return radius; } public double getArea() { return getRadius() * getRadius() * Math.PI; } }
计算三角形面积、四边形面积... 的时候,我们只需让它们去实现 Shape 接口即可,无需修改源代码。
Prinsip Penggantian Liskov terutamanya menerangkan beberapa prinsip mengenai pewarisan, iaitu apabila ia harus digunakan Warisan, apabila tidak menggunakan warisan, dan prinsip di sebaliknya. Penggantian Liskov pada asalnya adalah asas untuk penggunaan semula warisan Ia mencerminkan hubungan antara kelas asas dan subkelas, menambah prinsip pembukaan dan penutup, dan mengawal langkah khusus untuk mencapai abstraksi.
Fungsi prinsip penggantian Liskov
Fungsi utama prinsip penggantian Liskov adalah seperti berikut.
Prinsip penggantian Liskov ialah salah satu cara penting untuk merealisasikan prinsip pembukaan dan penutup.
Ia mengatasi kelemahan kebolehgunaan semula yang lemah disebabkan oleh mengatasi kelas induk dalam warisan.
Ia adalah jaminan ketepatan tindakan. Iaitu, lanjutan kelas tidak akan memperkenalkan ralat baru ke dalam sistem sedia ada, mengurangkan kemungkinan ralat kod.
Tingkatkan keteguhan program, dan pada masa yang sama mencapai keserasian yang sangat baik apabila menukar, meningkatkan kebolehselenggaraan dan kebolehskalaan program, dan mengurangkan masa diperlukan untuk menukar keperluan yang diperkenalkan risiko.
Bagaimana untuk melaksanakan prinsip penggantian Liskov (warisan)
Dalam istilah awam, penggantian Liskov prinsip Iaitu: subkelas boleh memanjangkan fungsi kelas induk, tetapi mereka tidak boleh mengubah fungsi asal kelas induk. Dalam erti kata lain: apabila subkelas mewarisi kelas induk, cuba untuk tidak mengatasi kaedah kelas induk kecuali menambah kaedah baharu untuk melengkapkan fungsi baharu.
Berdasarkan pemahaman di atas, takrifan prinsip penggantian Liskov boleh diringkaskan seperti berikut:
Sesuatu subkelas boleh melaksanakan kaedah abstrak induk kelas, tetapi tidak boleh mengatasi kelas induk Kaedah bukan abstrak kelas
Subkelas boleh menambah kaedah unik mereka sendiri
Apabila kaedah subkelas mengatasi kaedah kelas induk, prasyarat kaedah (iaitu parameter input kaedah) adalah lebih longgar daripada kaedah kelas induk
Apabila kaedah subkelas melaksanakan kaedah kelas induk (menimpa/melebihi beban atau melaksanakan kaedah abstrak), postcondition kaedah (iaitu nilai output/pulangan bagi kaedah) adalah lebih ketat atau sama dengan kelas induk
Walaupun mudah untuk menulis fungsi baharu dengan mengatasi kaedah kelas induk, kebolehgunaan semula keseluruhan sistem warisan akan menjadi agak lemah, terutamanya apabila perbandingan polimorfik digunakan Selalunya, kebarangkalian ralat menjalankan program akan menjadi sangat tinggi.
Jika program melanggar prinsip penggantian Liskov, objek kelas yang diwarisi akan mempunyai ralat masa jalan di mana kelas asas muncul.
Kaedah pembetulan pada masa ini ialah: batalkan hubungan warisan asal dan reka bentuk semula hubungan antara mereka.
Bagi contoh prinsip penggantian Liskov, yang paling terkenal ialah "segi empat bukan segi empat tepat". Sudah tentu, terdapat banyak contoh yang serupa dalam kehidupan Sebagai contoh, penguin, burung unta dan kiwi diklasifikasikan sebagai burung dari perspektif biologi, tetapi dari hubungan warisan kelas, kerana mereka tidak boleh mewarisi keupayaan "burung" untuk terbang, jadi mereka tidak boleh ditakrifkan sebagai subkelas "burung". Begitu juga, kerana "ikan belon" tidak boleh berenang, ia tidak boleh ditakrifkan sebagai subkategori "ikan"; "meriam mainan" tidak boleh meletupkan musuh, jadi ia tidak boleh ditakrifkan sebagai subkategori "meriam", dsb.
Cara terbaik untuk segi empat sama dan segi empat tepat ialah menambah kelas induk yang lain, dan kelas induk ini mewarisi daripada kelas induk ini pada masa yang sama.
Prinsip penyongsangan kebergantungan ialah salah satu cara penting untuk merealisasikan prinsip pembukaan dan penutupan antara pelanggan dan modul pelaksanaan antara.
Oleh kerana dalam reka bentuk perisian, butiran boleh diubah, manakala lapisan pengabstrakan agak stabil, jadi seni bina yang dibina pada pengabstrakan adalah lebih stabil daripada seni bina yang dibina pada butiran . Abstrak di sini merujuk kepada antara muka atau kelas abstrak, dan butiran merujuk kepada kelas pelaksanaan tertentu.
Tujuan menggunakan antara muka atau kelas abstrak adalah untuk merumuskan spesifikasi dan kontrak tanpa melibatkan sebarang operasi khusus, dan menyerahkan tugas untuk menunjukkan butiran kepada kelas pelaksanaannya.
Fungsi prinsip kebergantungan dan penyongsangan
Fungsi utama prinsip penyongsangan kebergantungan adalah seperti berikut.
Prinsip penyongsangan kebergantungan boleh mengurangkan gandingan antara kelas.
Prinsip penyongsangan kebergantungan boleh meningkatkan kestabilan sistem.
Prinsip penyongsangan kebergantungan boleh mengurangkan risiko yang disebabkan oleh pembangunan selari.
Prinsip penyongsangan kebergantungan boleh meningkatkan kebolehbacaan dan kebolehselenggaraan kod.
依赖倒置原则的实现方法
依赖倒置原则的目的是通过要面向接口的编程来降低类间的耦合性,所以我们在实际编程中只要遵循以下4点,就能在项目中满足这个规则。
每个类尽量提供接口或抽象类,或者两者都具备。
变量的声明类型尽量是接口或者是抽象类。
任何类都不应该从具体类派生。
使用继承时尽量遵循里氏替换原则。
依赖倒置原则在“顾客购物程序”中的应用。
分析:本程序反映了 “顾客类”与“商店类”的关系。商店类中有 sell() 方法,顾客类通过该方法购物以下代码定义了顾客类通过韶关网店 ShaoguanShop 购物
class Customer { public void shopping(ShaoguanShop shop) { //购物 System.out.println(shop.sell()); } }
但是,这种设计存在缺点,如果该顾客想从另外一家商店(如婺源网店 WuyuanShop)购物,就要将该顾客的代码修改如下:
class Customer { public void shopping(WuyuanShop shop) { //购物 System.out.println(shop.sell()); } }
顾客每更换一家商店,都要修改一次代码,这明显违背了开闭原则。
存在以上缺点的原因是:顾客类设计时同具体的商店类绑定了,这违背了依赖倒置原则。
解决方法是:定义“婺源网店”和“韶关网店”的共同接口 Shop,顾客类面向该接口编程,其代码修改如下:
class Customer { public void shopping(Shop shop) { //购物 System.out.println(shop.sell()); } } class Customer { public void shopping(Shop shop) { //购物 System.out.println(shop.sell()); } }
这样,不管顾客类 Customer 访问什么商店,或者增加新的商店,都不需要修改原有代码了,其类如下图所示:
package principle; public class DIPtest { public static void main(String[] args) { Customer wang=new Customer(); System.out.println("顾客购买以下商品:"); wang.shopping(new ShaoguanShop()); wang.shopping(new WuyuanShop()); } } //商店 interface Shop { public String sell(); //卖 } //韶关网店 class ShaoguanShop implements Shop { public String sell() { return "韶关土特产:香菇、木耳……"; } } //婺源网店 class WuyuanShop implements Shop { public String sell() { return "婺源土特产:绿茶、酒糟鱼……"; } } //顾客 class Customer { public void shopping(Shop shop) { //购物 System.out.println(shop.sell()); } }
程序的运行结果如下:
顾客购买以下商品: 韶关土特产:香菇、木耳…… 婺源土特产:绿茶、酒糟鱼……
Prinsip Pengasingan Antara Muka (ISP) memerlukan pengaturcara untuk cuba membahagikan antara muka kembung kepada antara muka yang lebih kecil dan lebih spesifik, supaya antara muka hanya mengandungi kaedah yang diminati pelanggan.
Pada tahun 2002, Robert C. Martin mendefinisikan "Prinsip Pengasingan Antara Muka" sebagai: Pelanggan tidak boleh dipaksa untuk bergantung pada kaedah yang mereka tidak gunakan). Terdapat definisi lain bagi prinsip ini: Kebergantungan satu kelas kepada kelas lain harus bergantung pada antara muka terkecil yang mungkin.
Maksud dua takrifan di atas ialah: untuk mewujudkan antara muka khusus yang mereka perlukan untuk setiap kelas, dan bukannya cuba membina antara muka yang besar untuk semua kelas yang bergantung padanya untuk memanggil.
Prinsip pengasingan antara muka dan tanggungjawab tunggal kedua-duanya adalah untuk meningkatkan kesepaduan kelas dan mengurangkan gandingan antara mereka, merangkumi idea pengkapsulan, tetapi kedua-duanya berbeza:
Prinsip tanggungjawab tunggal memfokuskan pada tanggungjawab, manakala prinsip pengasingan antara muka memfokuskan pada pengasingan kebergantungan antara muka.
Prinsip tanggungjawab tunggal terutamanya mengekang kelas, yang menyasarkan pelaksanaan dan butiran program, prinsip pengasingan antara muka terutamanya mengekang antara muka, terutamanya menyasarkan pengabstrakan dan program; secara keseluruhan Pembinaan rangka kerja.
Kelebihan prinsip pengasingan antara muka
Prinsip pengasingan antara muka adalah untuk mengekang antara muka dan mengurangkan kelas -kebergantungan antara muka, mengikut prinsip pengasingan antara muka mempunyai lima kelebihan berikut.
Mengurai antara muka kembung kepada berbilang antara muka berbutir kecil boleh menghalang penyebaran perubahan luaran dan meningkatkan fleksibiliti dan kebolehselenggaraan sistem.
Pengasingan antara muka meningkatkan kesepaduan sistem, mengurangkan interaksi luaran dan mengurangkan gandingan sistem.
Jika kebutiran antara muka ditakrifkan secara munasabah, kestabilan sistem boleh dijamin walau bagaimanapun, jika takrifan terlalu kecil, akan ada juga; banyak antara muka, yang akan menjadikan reka bentuk Kerumitan jika definisi terlalu besar, fleksibiliti akan dikurangkan, perkhidmatan tersuai tidak dapat disediakan, dan risiko yang tidak dijangka akan dibawa ke keseluruhan projek.
Menggunakan berbilang antara muka khusus juga boleh mencerminkan hierarki objek, kerana takrifan antara muka keseluruhan boleh dicapai melalui pewarisan antara muka.
boleh mengurangkan lebihan kod dalam kejuruteraan projek. Antara muka yang terlalu besar biasanya mengandungi banyak kaedah yang tidak digunakan Apabila melaksanakan antara muka ini, anda terpaksa mereka bentuk kod berlebihan.
Cara melaksanakan prinsip pengasingan antara muka
Apabila menggunakan prinsip pengasingan antara muka secara khusus, perkara berikut perlu dipatuhi Beberapa peraturan untuk diukur.
Antara muka hendaklah sekecil mungkin, tetapi dalam had. Antara muka hanya menyediakan satu sub-modul atau logik perniagaan.
Sesuaikan perkhidmatan untuk kelas yang bergantung pada antara muka. Hanya sediakan kaedah yang diperlukan oleh pemanggil dan sekat kaedah yang tidak diperlukan.
Fahami persekitaran dan enggan mengikut membuta tuli. Setiap projek atau produk mempunyai faktor persekitaran yang dipilih Persekitaran yang berbeza mempunyai piawaian yang berbeza untuk pemisahan antara muka.
Meningkatkan perpaduan dan mengurangkan interaksi luaran. Jadikan antara muka menggunakan kaedah paling sedikit untuk mencapai kebanyakan perkara.
Untuk pengasingan antara muka, anda masih boleh merujuk kepada contoh yang dinyatakan dalam tanggungjawab tunggal:
public interface UserService { public void login(String username, String password); public void register(String email, String username, String password); public void logError(String msg); public void sendEmail(String email); }
这时候,应该就能理解拆分的好处了。
迪米特法则(Law of Demeter,LoD)又叫作最少知识原则(Least Knowledge Principle,LKP),产生于 1987 年美国东北大学(Northeastern University)的一个名为迪米特(Demeter)的研究项目,由伊恩·荷兰(Ian Holland)提出,被 UML 创始者之一的布奇(Booch)普及,后来又因为在经典著作《程序员修炼之道》(The Pragmatic Programmer)提及而广为人知。
迪米特法则的定义是:只与你的直接朋友交谈,不跟“陌生人”说话(Talk only to your immediate friends and not to strangers)。其含义是:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。
迪米特法则中的“朋友”是指:当前对象本身、当前对象的成员对象、当前对象所创建的对象、当前对象的方法参数等,这些对象同当前对象存在关联、聚合或组合关系,可以直接访问这些对象的方法。
迪米特法则的优点
迪米特法则要求限制软件实体之间通信的宽度和深度,正确使用迪米特法则将有以下两个优点。
降低了类之间的耦合度,提高了模块的相对独立性。
由于亲合度降低,从而提高了类的可复用率和系统的扩展性。
但是,过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。所以,在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰。
迪米特法则的实现方法
从迪米特法则的定义和特点可知,它强调以下两点:
从依赖者的角度来说,只依赖应该依赖的对象。
从被依赖者的角度说,只暴露应该暴露的方法。
所以,在运用迪米特法则时要注意以下 6 点。
在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。
在类的结构设计上,尽量降低类成员的访问权限。
在类的设计上,优先考虑将一个类设置成不变类。
在对其他类的引用上,将引用其他对象的次数降到最低。
不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法)。
谨慎使用序列化(Serializable)功能
明星与经纪人的关系实例。
分析:明星由于全身心投入艺术,所以许多日常事务由经纪人负责处理,如与粉丝的见面会,与媒体公司的业务洽淡等。这里的经纪人是明星的朋友,而粉丝和媒体公司是陌生人,所以适合使用迪米特法则,其类图如下图所示。
package principle; public class LoDtest { public static void main(String[] args) { Agent agent=new Agent(); agent.setStar(new Star("林心如")); agent.setFans(new Fans("粉丝韩丞")); agent.setCompany(new Company("中国传媒有限公司")); agent.meeting(); agent.business(); } } //经纪人 class Agent { private Star myStar; private Fans myFans; private Company myCompany; public void setStar(Star myStar) { this.myStar=myStar; } public void setFans(Fans myFans) { this.myFans=myFans; } public void setCompany(Company myCompany) { this.myCompany=myCompany; } public void meeting() { System.out.println(myFans.getName()+"与明星"+myStar.getName()+"见面了。"); } public void business() { System.out.println(myCompany.getName()+"与明星"+myStar.getName()+"洽淡业务。"); } } //明星 class Star { private String name; Star(String name) { this.name=name; } public String getName() { return name; } } //粉丝 class Fans { private String name; Fans(String name) { this.name=name; } public String getName() { return name; } } //媒体公司 class Company { private String name; Company(String name) { this.name=name; } public String getName() { return name; } }
程序的运行结果如下:
粉丝韩丞与明星林心如见面了。 中国传媒有限公司与明星林心如洽淡业务。
到此,设计模式的六大原则就讲完了。
更多编程相关知识,请访问:编程教学!!
Atas ialah kandungan terperinci Apakah enam prinsip corak reka bentuk?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!