本文源碼:GitHub·點這裏 || GitEE·點這裏java
一、概念描述git
對類來講的,即一個類應該只負責一項職責。若是一個類負責兩個職責,可能存在職責1變化,引發職責2變化的狀況。能夠基於抽象邏輯,或者業務邏輯對類進行細化。github
二、案例演示編程
這裏基於方法和類的細化均可以,能夠根據實際業務選擇。設計模式
class Animal {
public void dogVoice (){
System.out.println("狗叫聲:旺旺");
}
public void cowVoice (){
System.out.println("牛叫聲:哞哞");
}
}
class DogVoice {
public String getDogVoice (){
return "旺旺" ;
}
}
class CowVoice {
public String getCowVoice (){
return "哞哞" ;
}
}
複製代碼
三、注意事項bash
減小代碼一處變動引發的程序大規模改動狀況,下降類的複雜度,提升類的可讀性,可維護性。一般狀況下,須要遵照單一職責原則,能夠適當違反單一職責原則。架構
一、概念描述ide
客戶端不該該依賴它不須要的接口,一個類對另外一個類的依賴,應該創建在最小的接口上。優化
二、案例演示this
interface ReadBlog {
String getBlog () ;
}
interface AdminBlog {
Boolean insertBlog () ;
Boolean updateBlog () ;
Boolean deleteBlog () ;
}
/** * 讀者只開放博客閱讀接口 */
class Reader implements ReadBlog {
@Override
public String getBlog() {
return null;
}
}
/** * 管理員有博客所有的管理權限 */
class AdminUser implements AdminBlog,ReadBlog {
@Override
public String getBlog() {
return null;
}
@Override
public Boolean insertBlog() {
return null;
}
@Override
public Boolean updateBlog() {
return null;
}
@Override
public Boolean deleteBlog() {
return null;
}
}
複製代碼
三、注意事項
接口的設計粒度越小,則應用系統程序越靈活,程序變得靈活也就意味同時結構複雜性提升,開發開發和理解的難度也會變大,可維護性下降。
一、概念描述
高層模塊不該該依賴低層模塊,二者應依賴其抽象;抽象不該該依賴細節,細節應該依賴抽象;中心思想是面向接口編程。
二、案例演示
public class C01_FarmFactory {
public static void main(String[] args) {
Animal animal = new Dog() ;
FarmFactory farm = new Farming() ;
farm.breed(animal) ;
animal = new Pig() ;
farm.breed(animal) ;
}
}
/** * 接口聲明依賴對象 */
interface FarmFactory {
void breed (Animal animal) ;
}
class Farming implements FarmFactory {
@Override
public void breed(Animal animal) {
System.out.println("農場飼養:"+animal.getAnimalName());
}
}
interface Animal {
String getAnimalName () ;
}
class Dog implements Animal {
@Override
public String getAnimalName() {
return "牧羊犬";
}
}
class Pig implements Animal {
@Override
public String getAnimalName() {
return "土豬一號";
}
}
複製代碼
三、注意事項
相對於系統開發的多變性,抽象的相對穩定。以抽象爲基礎搭建的架構比以細節爲基礎的架構要穩定靈活。下層模塊儘可能都要有抽象類或接口,程序穩定性更好。變量的聲明類型儘可能是抽象類或接口,這樣變量引用和實際對象之間存在一個過渡空間,利於程序擴展和優化。
一、概念描述
假設以下場景:
若是將全部類型爲T1的對象O1都替換成類型T2的對象O2,程序的行爲不發生改變。那麼類型T2是類型T1的子類型。換句話說,全部引用基類的地方必須能透明地使用其子類的對象。
二、案例演示
public class C01_Calculate {
public static void main(String[] args) {
BizCalculate bizCalculate = new BizCalculate() ;
System.out.println(bizCalculate.add(2,3));
}
}
class Calculate { }
class BaseCalculate extends Calculate {
public int add (int a,int b){
return a+b;
}
}
/** * 這裏使用組合的方式完成計算 */
class BizCalculate extends Calculate {
private BaseCalculate baseCalculate = new BaseCalculate() ;
public int add (int a,int b){
return this.baseCalculate.add(a,b);
}
}
複製代碼
三、注意事項
使用繼承時,遵循里氏替換原則,在子類中儘可能不要重寫父類的方法;子類能夠擴展父類的功能,但不能改變原有父類的功能;在適當的狀況下,能夠經過聚合,組合,依賴等方式解決問題。
一、概念描述
開閉原則是編程中最基礎、最重要的設計原則,在代碼結構的設計設計時,應該考慮對擴展開放,對修改關閉,抽象思惟搭建結構,具體實現擴展細節。
二、案例演示
public class C01_BookPrice {
public static void main(String[] args) {
ParityBook parityBook = new DiscountBook("Java",100.00) ;
System.out.println(parityBook.getPrice());
}
}
interface Book {
String getName () ;
Double getPrice () ;
}
/** * 平價書籍 */
class ParityBook implements Book {
private String name ;
private Double price ;
public ParityBook(String name, Double price) {
this.name = name;
this.price = price;
}
@Override
public String getName() {
return this.name ;
}
@Override
public Double getPrice() {
return this.price ;
}
}
/** * 打折數據擴展價格計算策略 */
class DiscountBook extends ParityBook {
public DiscountBook(String name, Double price) {
super(name, price);
}
@Override
public Double getPrice() {
double oldPrice = super.getPrice();
return oldPrice * 0.8 ;
}
}
複製代碼
三、注意事項
基於開閉原則設計的代碼結構能夠提升複用性和可維護性,經過接口或抽象類能夠約束類的變化行爲,基於指定策略對變化行爲進行封裝,而且可以實現對擴展開放,使用設計模式的基本原則就是遵循開閉原則。
一、概念描述
迪米特原則又叫最少知道原則,即一個類對本身依賴的類知道的越少越好。也就是說,對於被依賴的類無論多麼複雜,都儘可能將邏輯封裝在類的內部。對外除了提供的public方法,不對外開聽任何信息。類與類關係越密切,耦合度越大,耦合的方式不少,依賴,關聯,組合,聚合等。
兩個對象之間有耦合關係,就說這兩個對象之間是朋友關係。其中出現成員變量,方法參數,方法返回值中的類稱爲直接朋友,而出如今局部變量中的類不是直接朋友。從原則上說,陌生的類最好不要以局部變量的形式出如今類的內部。
二、案例演示
public class C01_Employee {
public static void main(String[] args) {
HeadCompanyEmpManage empManage = new HeadCompanyEmpManage() ;
BranchCompanyEmpManage branchEmp = new BranchCompanyEmpManage() ;
empManage.printEmp(branchEmp);
}
}
/** * 總公司員工 */
class HeadCompanyEmp {
public String name ;
public HeadCompanyEmp(String name) {
this.name = name;
}
@Override
public String toString() {
return "HeadCompanyEmp{name='" + name + '}';
}
}
/** * 分公司員工 */
class BranchCompanyEmp {
public String name ;
public BranchCompanyEmp(String name) {
this.name = name;
}
@Override
public String toString() {
return "BranchCompanyEmp{name='" + name + '}';
}
}
/** * 分公司員工管理 */
class BranchCompanyEmpManage {
// 添加分公司員工
public List<BranchCompanyEmp> addEmp (){
List<BranchCompanyEmp> list = new ArrayList<>() ;
for (int i = 1 ; i <= 3 ; i++){
list.add(new BranchCompanyEmp("分公司員工"+i)) ;
}
return list ;
}
// 獲取分公司員工
public void printBranchCompanyEmp (){
List<BranchCompanyEmp> list = addEmp () ;
for (BranchCompanyEmp emp:list){
System.out.println(emp);
}
}
}
/** * 總公司員工管理,基於迪米特原則,不出現陌生類 */
class HeadCompanyEmpManage {
// 添加總公司員工
public List<HeadCompanyEmp> addHeadEmp (){
List<HeadCompanyEmp> list = new ArrayList<>() ;
for (int i = 1 ; i <= 3 ; i++){
list.add(new HeadCompanyEmp("總公司員工"+i)) ;
}
return list ;
}
public void printEmp (BranchCompanyEmpManage empManage){
// 打印分公司員工
empManage.printBranchCompanyEmp();
List<HeadCompanyEmp> headEmpList = addHeadEmp () ;
for (HeadCompanyEmp headCompanyEmp:headEmpList){
System.out.println(headCompanyEmp);
}
}
}
複製代碼
三、注意事項
迪米特原則的初衷是下降類之間的耦合,因爲每一個類都減小了沒必要要的依賴,所以能夠下降耦合關係。下降耦合關係,並非要求徹底沒有依賴關係,過分的使用迪米特原則,容易產生大量的中間類,致使複雜度變大。因此在使用迪米特原則時要根據實際業務權衡。
設計模式和設計原則的核心思想都是:判斷業務應用中可能會變化模塊,而且把這些模塊獨立出來,基於指定的策略進行封裝,不要和那些變化的不大的模塊耦合在一塊兒,封裝思想上基於接口和抽象類,而不是針對具體的實現編程。核心目的就是下降交互對象之間的鬆耦合度。設計模式和原則都不是能夠生搬硬套的公式,我的理解:只要形似,神韻就天然不差。
GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent
複製代碼