第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Lambda 表達式的設(shè)計原則

Java 編程最基本的原則就是要追求高內(nèi)聚和低耦合的解決方案和代碼模塊設(shè)計,這里我們主要討論在 Lambda 表達式的環(huán)境下來設(shè)計我們程序時的兩點原則:單一原則開放閉合原則

1. 單一原則

程序中的類或者方法只有一個改變的理由

當(dāng)需要修改某個類的時候原因有且只有一個。換句話說就是讓一個類只做一種類型責(zé)任,當(dāng)這個類需要承當(dāng)其他類型的責(zé)任的時候,就需要分解這個類。 類被修改的幾率很大,因此應(yīng)該專注于單一的功能。如果你把多個功能放在同一個類中,功能之間就形成了關(guān)聯(lián),改變其中一個功能,有可能中止另一個功能,這時就需要新一輪的測試來避免可能出現(xiàn)的問題,非常耗時耗力。

我們來看一個質(zhì)數(shù)統(tǒng)計的例子:

//這是一個違反單一原則的例子  
public SRPDemo{  
	public static long countPrimes(int maxNum){  
		long total = 0;  
		for(int i = 1; i<maxNum;i++){  
			boolean isPrime = true;  
			for( int j=2; j<i;j++){  
				if(i%j ==0){  
					isPrime = false;  
				}  
			}  
			if(isPrime){  
				total = total +1;  
			}  
		}  
		return total;  
	}  
	?  
	public static void main(String ...s){  
		System.out.println(countPrimes(100));  
	}  
}
輸出結(jié)果:

26

上面的例子違反了單一原則,一個方法包含了兩重職責(zé):

  • 計數(shù);
  • 判斷是否為一個質(zhì)數(shù)。

我們把上面的代碼重構(gòu),將兩種職責(zé)拆分到兩個方法中:

//符合單一原則的例子  
public SRPDemo{  
	//計數(shù)  
	public static long countPrimes(int maxNum){  
		long total = 0;  
		for(int i= 1;i<maxNum;i++){  
			if(isPrime(i))
				total = total+1;  
		}  
			return total;  
	}  
	//判斷是否為一個質(zhì)數(shù)  
	public static boolean isPrime(int num){  
		for(int i = 2;i<num; i++){  
			if(num%i ==0){  
				return false;  
			}  
		}  
		return true;  
	}  
?  
	public static void main(String ...s){  
		System.out.println(countPrimes(100));  
	}  
}

我們現(xiàn)在使用集合流來重構(gòu)上面代碼:

public SRPDemo{  
	public static long countPrimes(int maxNum){  
		return IntStream.range(1,maxNum).filter(MultipleInterface::isPrime).count();  
	}  
	public static boolean isPrime(int num){  
		return IntStream.range(2,num).allMatch(x -> num%x != 0);  
	}  
	?  
	public static void main(String ...s){  
		System.out.println(countPrimes(100));  
	}  
}

可見,我們使用集合流在一定程度上可以輕松地幫我們實現(xiàn)單一原則。

2. 開放閉合原則

軟件應(yīng)該是擴展開放,修改閉合

  • 通過增加代碼來擴展功能,而不是修改已經(jīng)存在的代碼;
  • 若客戶模塊和服務(wù)模塊遵循同一個接口來設(shè)計,則客戶模塊可以不關(guān)心服務(wù)模塊的類型,服務(wù)模塊可以方便擴展服務(wù)(代碼);
  • 開放閉合原則支持替換的服務(wù),而不用修改客戶模塊。

我們來看一個發(fā)送消息的例子,假設(shè)我們現(xiàn)在有一個消息通知模塊用來發(fā)送郵件和短信:

//這是一個違反開放閉合原則的例子  
public class OCPDemo{  
	//發(fā)送郵件  
	public boolean sendByEmail(String addr, String title, String content) {  
		System.out.println("Send Email");  
		return true;  
	}  
	//發(fā)送短信  
	public boolean sendBySMS(String addr, String content) {  
		System.out.println("Send sms");  
		return true;  
	}  
}  

想必很多人都會這么寫,這么寫有一個問題,如果哪一天需求變更要求增加微信消息通知,這個時候不僅需要增加一個 sendWechat的方法,還需要在調(diào)用它的地方進行修改,所以違反了 OCP 原則?,F(xiàn)在我們來做一下修改:

//一個滿足開放閉合原則的例子  
public class OCPDemo{  
	@Data  
	public static class Message{  
		private String addr;  
		private String title;  
		private String content;  
		private int type;  
	}  
	public boolean send(Message message){  
		switch (message.getType()){  
			case 0: {  
				System.out.println("Send Email");  
				return true;  
			}  
			case 1:{  
				System.out.println("Send sms");  
				return true;  
			}  
			case 2:{  
				System.out.println("Send QQ");  
				return true;  
			}  
			default:return false;  
		}  
	}  
}

我們創(chuàng)建了一個 Message 對象來描述發(fā)送消息的所有信息,并增加了一個 type 字段用來區(qū)分發(fā)送渠道。在遇到類似的情況窩子需要在 send 方法中增加一個對應(yīng) 渠道類型 type 的處理邏輯就可以了,對存量代碼無需求改。滿足了 OCP 原則。

現(xiàn)在我們再來看下使用函數(shù)式接口怎么來優(yōu)化我們的程序:

@Data  
public class OCPDemo{  
	@Data  
	public static class Message{  
		private String addr;  
		private String title;  
		private String content;  
	}  
?  
	private Message message;  
	?  
	public boolean send(Function<Message , Boolean>  function){  
		return function.apply(message);  
	}  
?  
	public static void main(String ...s){  
		Message message = new Message();  
		message.setTitle("this is a qq msg");  
		OCPDemo demo = new OCPDemo();  
		demo.setMessage(message);  
		demo.send((msg)->{  
			System.out.println("send qq:\t"+msg.getTitle());  
			return true;  
		});  
	}  
}  
輸出:

send qq:  this is a qq msg

此時,我們運用函數(shù)接口 Function 來處理 Message,省去了消息類型的判斷,僅當(dāng)調(diào)用的時候決定使用哪種渠道發(fā)送,當(dāng)然我們可以把發(fā)送邏輯都寫在一個工具類里面,利用 Lambda 引用來調(diào)用。

3. 小結(jié)

圖片描述

本節(jié)主要討論的是我們?nèi)绾卧谖覀兊某绦蛟O(shè)計中來使用 Lambda 表達式時所涉及的兩條原則 —— 單一原則開放閉合原則

這里關(guān)注的是程序整體,而不是具體的某一個方法。其前提是對于 Lambda 表達式的深度理解和熟練運用,為了說明問題,例子大多相對簡單,想了解更詳細的設(shè)計原則還是需要閱讀相關(guān)的專著(比如 S.O.L.I.D 原則),并在日常的編碼過程中不斷實踐和思考。