文章目錄
- 定義
- 策略模式的結構
- QuickStart | Demo
- Step1 | 策略接口
- Step2 | 策略實現
- Step3 | 上下文服務類
- Step4 | 客戶端
- 策略模式的特點
- 優點
- 缺點
定義
策略模式Strategy是一種行為模式,它能定義一系列算法,并將每種算法分別放入到獨立的類中,以使算法的對象能夠相互替換。
比如,你去機場,可以有三種策略:
- 自行車
- 公共汽車
- 出租車
這三種交通方案,自行車不要錢,能欣賞風景;公共汽車便宜速度快;出租車方便速度快,節省時間。這三種方案代表了三種策略,算法。
將上面三種出行方案封裝,我們可以靈活選用!
策略模式的結構
通過上圖我們知道,策略模式分為四個結構:
- 策略接口【核心】
- 策略實現類
- 上下文Context
- 具體要實現的業務代碼,業務邏輯。
- 客戶端Client
- 決定使用哪種策略。
QuickStart | Demo
接下來用一個非常容易理解的案例讓大家掌握策略模式。
項目結構如下:
├─.idea
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─linghu
│ │ │ └─designer
│ │ │ ├─dao
│ │ │ │ └─impl
│ │ │ └─service
│ │ └─resources
│ └─test
│ └─java
└─target
├─classes
│ └─com
│ └─linghu
│ └─designer
│ ├─dao
│ │ └─impl
│ └─service
└─generated-sources
└─annotations
Step1 | 策略接口
首先定義一個策略接口,這里面封裝了數據訪問層Dao層的策略方法。
/*** @author linghu* @date 2024/7/3 10:27*/
/*策略接?*/
public interface UserDao {public void insert();public void update();public void delete();public void findById();
}v
Step2 | 策略實現
面向客戶,用戶,開發者的時候,我們可以選擇不同的數據訪問方式,我們可以選擇:
- JDBC
- JNDI
- ODBC
具體怎么選,我們需要再客戶端讓用戶自己選。那么在這里我們需要定義好這三種策略實現類。
/*** @author linghu* @date 2024/7/3 10:28*/
public class JdbcDao implements UserDao {@Overridepublic void insert() {System.out.println("JDBC?式實現數據插?");}@Overridepublic void update() {System.out.println("JDBC?式實現數據更新");}@Overridepublic void delete() {System.out.println("JDBC?式實現數據刪除");}@Overridepublic void findById() {System.out.println("JDBC?式實現數據查找");}
}
package com.linghu.designer.dao.impl;import com.linghu.designer.dao.UserDao;/*** @author linghu* @date 2024/7/3 10:28*/
public class JndiDao implements UserDao {@Overridepublic void insert() {System.out.println("JndiDao?式實現數據插?");}@Overridepublic void update() {System.out.println("JndiDao?式實現數據更新");}@Overridepublic void delete() {System.out.println("JndiDao?式實現數據刪除");}@Overridepublic void findById() {System.out.println("JndiDao?式實現數據查找");}
}
package com.linghu.designer.dao.impl;import com.linghu.designer.dao.UserDao;/*** @author linghu* @date 2024/7/3 10:28*/
public class JndiDao implements UserDao {@Overridepublic void insert() {System.out.println("JndiDao?式實現數據插?");}@Overridepublic void update() {System.out.println("JndiDao?式實現數據更新");}@Overridepublic void delete() {System.out.println("JndiDao?式實現數據刪除");}@Overridepublic void findById() {System.out.println("JndiDao?式實現數據查找");}
}
package com.linghu.designer.dao.impl;import com.linghu.designer.dao.UserDao;/*** @author linghu* @date 2024/7/3 10:28*/
public class OdbcDao implements UserDao {@Overridepublic void insert() {System.out.println("OdbcDao?式實現數據插?");}@Overridepublic void update() {System.out.println("OdbcDao?式實現數據更新");}@Overridepublic void delete() {System.out.println("OdbcDao?式實現數據刪除");}@Overridepublic void findById() {System.out.println("OdbcDao?式實現數據查找");}
}
Step3 | 上下文服務類
上下文服務,持有某個策略對象dao,但是策略通過外部傳入,服務類本身主要完成業務邏輯 insert()
。
/*** @author linghu* @date 2024/7/3 10:33*/
/*Context*/
public class UserService {public UserDao dao = null;public UserService(UserDao dao) {this.dao = dao;}public void createUser(){System.out.println("正在創建?戶對象");dao.insert();}
}
在這里,我們的策略是通過外部傳入的:
public UserService(UserDao dao) {this.dao = dao;}
外部策略通過 UserDao dao
傳入。
Step4 | 客戶端
客戶端代碼如下:
/*** @author linghu* @date ${DATE} ${TIME}*/
public class Client {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String input = scanner.nextLine();UserDao dao = null;switch (input) {case "jdbc":dao = new JdbcDao();break;case "odbc":dao = new OdbcDao();break;case "jndi":dao = new JndiDao();break;}//策略的創建者在用戶端!UserService userService = new UserService(dao);userService.createUser();}
}
根據文本的不同創建不同的策略:
switch (input) {case "jdbc":dao = new JdbcDao();break;case "odbc":dao = new OdbcDao();break;case "jndi":dao = new JndiDao();break;}