設計原則
找出應用中可能需要的變化之處,把他們獨立出來(封裝),不要和哪些不需要變化的代碼混在一起
實際舉例
- 我們實現一個鴨子,且這個鴨子有很多種,且有各個屬性。我們應該如何設計這個鴨子呢?
- 首先鴨子不變的屬性有哪些? 外觀,游泳。等(先定義這兩個)
- 鴨子變的屬性有哪些? 有的會叫,有的會飛等
- 那我們怎麼去定義 紅鴨子,黑鴨子,還有玩具鴨子?
show me code
- 由於鴨子都會游泳和有外觀,那麼我們創建一個最基礎的鴨子
package 設計模式;
/**
* @author yuanxindong
* @date 2020/7/4 12:38 上午
*/
public abstract class Duck {
/**
* 由於不是所有的外形都是一樣的所以定義一個可以被實現外形的抽象方法
*/
public abstract void disPlay();
//所有的鴨子都會呱呱叫,所以這個行爲可以放在基類裏面,
// 由於有部分鴨子不會游泳所以不能寫在基類上
// String quack() {
// return "呱呱掛";
// }
/**
* 所有的鴨子都能游泳
*
* @return
*/
String Swim() {
return "游泳ING";
}
}
- 剛開始我們使用抽象類,定義一個鴨子,且將有可能有不同的顏色的情況輕易爲抽象方法,這個抽象方法可以起到一個約束的作用,意思也就是你是鴨子必須有外觀。
package 設計模式;
/**
* @authoryuanxindong
* @date: 2020/7/4 12:57 上午
*/
public interface FlyAble {
void fly();
}
package 設計模式;
import io.netty.handler.codec.mqtt.MqttUnsubAckMessage;
/**
* @author yuanxindong
* @date 2020/7/4 12:58 上午
*/
public interface QuackAble {
void quack();
}
package 設計模式;
/**
* @authoryuanxindong
* @date: 2020/7/4 12:58 上午
*/
public interface SwingAble {
void Swing();
}
- 但是由於不同的鴨子有可能不會飛也不會叫如橡皮鴨,所以這種情況下,我們就得想法實現了,要麼在實現的每個鴨子裏面寫下自己的屬性。這樣的花會產生大量的重複代碼,所以我們可以通過接口定義,將幾種行爲方式起一個接口。繼承整個接口且實現就可以輕鬆的展示自己的特點了。還有就是我們定義了接口後還會被其他的屬性使用,比如狗也會叫等等。
- 通過接口和抽象方式定義各個鴨子
package 設計模式;
/**
* @author yuanxindong
* @date 2020/7/4 12:43 上午
*/
public class BlackDuck extends Duck implements SwingAble{
/**
* 由於是繼承於Duck的且duck是沒有被實現的,所以duck必須要定義這個
* 這個約束讓代碼變得規範
*/
@Override
public void disPlay() {
System.out.println("我是一個黑鴨子");
}
@Override
public void Swing() {
System.out.println("游泳高手");
}
}
package 設計模式;
/**
* @author yuanxindong
* @date 2020/7/4 12:55 上午
*/
public class RubberDuck extends Duck implements SwingAble {
/**
* 這個鴨子只有外觀
*/
@Override
public void disPlay() {
System.out.println("灰色");
}
@Override
public void Swing() {
System.out.println("游泳");
}
}
總結
- 在設計代碼的時候:將不變的和經常變得代碼分開。
- 實現的方式:可以通過抽象類和接口的繼承和實現的方式。
參考
《Head first 設計模式》