基礎概念
-定義:按套路先解釋一下什么是策略模式:一個類的行為,能夠在運行時,被更改,是行為模式的一種.(直接傳傳遞一個對象不就好了)
-場景: 排序工具類, 需要對任何對象進行排序,需要對任何對象進行比較.但有一個前提,你不能改變sort方法本身(設計原則:開閉原則)
-實現(xiàn)方式:按功能,設計接口, Comparator ,定義了compare方法. (PS單方法體接口,可以用lambda表達式),定義ComparatorImpl 實現(xiàn)compare 接口,一種策略一種比較方式.在sort方法中,傳入 Comparator 對象即可.這樣就可以實現(xiàn)不改變sort本身,來實現(xiàn)增加策略的方式.
-目的:思考這個問題,很簡單,如果不用這種方式,你需要做到針對各種策略,按身高排序的sort1 按體重排序的sort2,破壞了原來色sort類.(目的只有一個,橫向擴展,而不是垂直式的修改)
源碼應用
- Comparator(比較器)
int compare(T o1, T o2);
- spring Resource ,Spring 會針對不同的底層資源兼雄,提供不同的 Resource 實現(xiàn)類
* @see WritableResource
* @see ContextResource
* @see UrlResource
* @see FileUrlResource
* @see FileSystemResource
* @see ClassPathResource
* @see ByteArrayResource
* @see InputStreamResource
public interface Resource extends InputStreamSource {
boolean exists();
default boolean isReadable() {
return exists();
}
default boolean isOpen() {
return false;
}
default boolean isFile() {
return false;
}
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
default ReadableByteChannel readableChannel() throws IOException {
return Channels.newChannel(getInputStream());
}
long contentLength() throws IOException;
long lastModified() throws IOException;
Resource createRelative(String relativePath) throws IOException;
@Nullable
String getFilename();
String getDescription();
}
- InstantiationStrategy 負責使用 Bean 類的默認構(gòu)造函數(shù)脉课、帶參構(gòu)造函數(shù)或者工廠方法等來實例化 Bean,是一個策略模式的接口在塔。InstantiationStrategy 接口源碼如下。
public interface InstantiationStrategy {
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
throws BeansException;
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
Constructor<?> ctor, Object... args) throws BeansException;
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, Method factoryMethod, Object... args)
throws BeansException;
}
模式核心
- 對象:client(sort類) , N策略對象以及其對應的接口
- 組裝方式, 可以直接以屬性注入,也可以以方法參數(shù)傳入.這種方式,就是直接以靜態(tài)屬性的方式注入.(可以對比一下comparable ,comparable只能固定一種實現(xiàn),畢竟 是以接口實現(xiàn)方式,無法做到不同的實現(xiàn).)
private static Comparator YXTopComparator = new Comparator() {
public int compare(Object var1, Object var2) {
Curve var3 = ((Edge)var1).getCurve();
Curve var4 = ((Edge)var2).getCurve();
double var5;
double var7;
if ((var5 = var3.getYTop()) == (var7 = var4.getYTop()) && (var5 = var3.getXTop()) == (var7 = var4.getXTop())) {
return 0;
} else {
return var5 < var7 ? -1 : 1;
}
}
};
3.優(yōu)化了哪種代碼?業(yè)務場景如下(優(yōu)化if,else),這種寫法的問題,如果業(yè)務有變化,需要增加 e,f,g 甚至更多的類型,每次都需要去更改調(diào)用類(這種方式是特別不友好的,),因此需要抽象一個策略接口,去做實體類,橫向擴展,即可
//根據(jù)類型不同,調(diào)用不同的物流接口(比如說順豐,申通等等)
if (type == "a") {
} else if (type=="b") {
} else if (type=="c"){
}
//優(yōu)化,抽象物流策略接口
public interface ShipStrategy{
//發(fā)運接口
void ship();
}
//順豐物流發(fā)運,策略實現(xiàn)類
public class SFShipStrategy implement ShipStrategy {
//發(fā)運接口
void ship(){
//發(fā)運
.....
}
}
//客戶端調(diào)用(調(diào)用問題解決了,如何解決對象構(gòu)造的if -else? ,根據(jù) type = a 構(gòu)建 a的策略)
shipStrategy.ship();
//1.維護 type 和class的映射關系. 2.通過spring獲取策略對象(原理是反射.)
Enum ShipType{
SF("SF", "com.dzq.ship.SFShipStrategy "), ADD("ST", "com.dzq.shipSTShipStrategy");
}
//2.通過反射獲取到到對象
Class.forName(clazz).newInstance()
.....
image.png