前言
去年的11月份吧,我考下了中級軟體設計師的證照,裡面的必考題之一就是設計模式,雖然也沒有很難考,但是如果你是要去國企工作的讀者,其實我建議還是考上一考,一方面是對知識的複習,另一方面就是多少加一點工資。 以下附上一個報名的連結:bm.ruankao.org.cn/sign/welcom…
思維導圖
六大原則
文章結構:定義 ---> 白話
單一職責原則
定義:就一個類而言,應該僅有一個引起它變化的原因。
其實字面意思就已經表達的比較明確,單一
,也就是幹盡量少的事情。在HDU中可以對耦合和內聚程度的評判有一定的瞭解。
什麼叫做少,其實很難有一個標準。但是在Android的MVC框架中,Activity既作為View,又起著Controller的作用的時候是否顯得會很臃腫呢?他需要進行頁面的重新整理,網路處理,訊息處理等等,寫起來容易,但是在我們進行維護的時候,是不是會很頭疼呢。
開放封閉原則
定義:類,模組,函式等應該是可以擴充套件的,但是不可以修改。
在日常的專案開發中,需求一直是處於一個變動的狀態,但是這同樣也會成為專案開發的壁壘,如果你的Bean
今天是一隻貓,明天就需要是一隻狗呢?重新打補丁嗎?顯然是一個很不合適的做法。而開放封閉原則,解決的就是這一類問題。不論是貓,還是狗,他們總會有相同的特徵,抽象化也就是這個原則實現的基礎。
// 定義一個動物抽象類
public abstract class Animal {
abstract void do();
}
// 貓實現抽象方法
class Cat extends Animal {
@Override
void do() {
System.out.println("喵");
}
}
// 狗實現抽象方法
class Dog extends Animal {
@Override
void do() {
System.out.println("汪");
}
}
複製程式碼
里氏替換原則
定義:所有引用基類(一般來說都是抽象類或介面)的地方必須能透明的使用其子類的物件。
定義的具體含義就是將一個基類物件替換成其子類物件,程式將不會產生任何錯誤和異常,反過來則不成立,如果一個軟體實體使用的是一個子類物件的話,那麼它不一定能夠使用基類物件。 或者你還是不理解的話,以下兩段程式碼,就很清晰的解析了上述的含義。
List list = new ArrayList<String>();
ArrayList list = new List<String>();
複製程式碼
ArrayList
作為我們擼程式碼日子裡的親人,你見過第二種寫法嗎?
接下來就是里氏替換原則的具體實現了。
/**
* 基於里氏替換原則實現
*/
class Manage1 {
private Animal animal;
public void setAnimal(Animal animal) {
this.animal = animal;
}
void getSound() {
animal.do();
}
}
/**
* 使用子類實現
*/
class Manage2 {
private Cat cat;
public void setAnimal(Cat cat) {
this.cat = cat;
}
void getSound() {
cat.do();
}
}
複製程式碼
以上基於兩種寫法,給予讀者評判,如果使用Manage2
,如果我們希望獲得Dog
的聲音,那麼就需要重新實現Manager3
,然後差異就是隻是把Cat
置換成Dog
。而Manage1
很好的解決了這個問題,因為不論是Cat
還是Dog
都是Animal
的子類。
依賴倒置原則
定義:高層模組不應該依賴底層模組,兩者都應該依賴於抽象。抽象不應該依賴於細節,細節應該依賴於抽象。
兩個概念:
- 抽象/高層模組:介面或者抽象類,一般只定義了有什麼操作,但是沒有具體實現。
- 細節/底層模組:實現介面或者繼承抽象類而產生的,一般來說就是new出來的物件。
這裡的程式碼與里氏替換原則一致。
迪米特原則
定義:一個軟體實體應當少的與其他實體發生相互作用。
其實和上面的內容差不多,同樣都是為了降低耦合程度,直接用Demo證明就清楚明瞭了。
電話網路形式
- 打電話的人 --> 接電話的人
- 打電話的人 --> 中間服務商轉接 --> 接電話的人
第一種已經被時代拋棄了,雖然我們並不知覺,但是第一種電話網路模式,如果用在現代社會,那麼帶來的後果就是你再也看不見太陽了,頭頂密密麻麻的電話線,更何況那是座機互聯的時代,能夠靠電話線來解決,但是這個時代呢?移動互聯的時代呢,不能再靠著電話線來解決問題,而是中間商的介入就改變了這個現狀。
第一種電話網路模式
/**
* 打電話的人
*/
class Call {
private Receiver receiver;
public void setReceicer(Receiver receiver) {
this.receiver = receiver;
}
public void call() {
receiver.receive();
}
}
/**
* 接電話的人
*/
class Receiver{
private String number;
Receiver(String number){
this.number = number;
}
public void receive() {
System.out.println("接通電話");
}
}
class Main{
public static void main(String[] args) {
Call call = new Call();
call.setReceicer(new Receiver("電話號碼"));
call.call();
}
}
複製程式碼
第二種電話網路模式
/**
* 轉接
*/
public abstract class Manager {
abstract void link();
}
/**
* 打電話的人
*/
class Call {
private Manager manager;
public void setManager(Manager manager) {
this.manager = manager;
}
public void call() {
manager.link();
}
}
/**
* 接電話的人
*/
class Receiver{
private String number;
Receiver(String number){
this.number = number;
}
public void receive() {
System.out.println("接通電話");
}
}
class CMCC extends Manager {
private String number;
CMCC(String number){
this.number = number;
}
public void link() {
System.out.println("連線接電話的人");
Receiver receiver = new Receiver();
receiver.receive();
}
}
class Main{
public static void main(String[] args) {
Call call = new Call();
call.setManager(new CMCC("電話號碼"));
call.call();
}
}
複製程式碼
這個時候兩個實體通過加入中間商的形式降低了耦合度。
介面隔離原則
定義:一個類對另一個類的依賴應該建立在最小的介面上
一個介面內要實現的函式數量可控,有那麼一點像資料庫裡的第一正規化。讓我們從Demo看看使用原則的與否的不同之處。
正常實現
// 特徵
interface Character {
void look();
void nature();
}
class Dog implements Character{
@Override
void look() {
System.out.println("能看");
}
@Override
void nature() {
System.out.println("淘氣");
}
}
複製程式碼
基於介面隔離原則實現
// 外觀
interface Facade {
void look();
}
// 內在
interface Inherent {
void nature();
}
class Dog implements Inherent{
@Override
void nature() {
System.out.println("淘氣");
}
}
複製程式碼
總結
七大原則其實表明的意思還是比較明確的,雖然可能寫法上的難度會有一定的增加,但是如果使用得當,後期的維護成本將會大大降低。
以上就是我的學習成果,如果有什麼我沒有思考到的地方或是文章記憶體在錯誤,歡迎與我分享。
相關文章推薦: