太複雜地嵌套if else 會致使難以閱讀,以及擴展性極差,違反了單一職責原則和開閉原則.html
好比下邊這個例子java
一個方法不應作太多事情,它應當專一於本身.極端狀況下就像是函數式編程的純函數.git
優化前github
double getPayAmount(){
double result;
if(_isDead) {
result = deadAmount();
}else{
if(_isSeparated){
result = separatedAmount();
}
else{
if(_isRetired){
result = retiredAmount();
else{
result = normalPayAmount();
}
}
}
return result;
}
複製代碼
優化後編程
double getPayAmount(){
if(_isDead)
return deadAmount();
if(_isSeparated)
return separatedAmount();
if(_isRetired)
return retiredAmount();
return normalPayAmount();
}
複製代碼
整個方法就像是漏斗同樣,只有真正知足條件的請求,可以走下去.邏輯清晰了不少app
舉一個簡單的例子ide
String str = "Hello World!";
if (str != null) {
System.out.println(str);
} else {
System.out.println("Null");
}
複製代碼
優化後函數式編程
Optional<String> strOptional = Optional.of("Hello World!");
strOptional.ifPresentOrElse(System.out::println, () -> System.out.println("Null"));
複製代碼
這裏的例子比較簡單,你可能看不出Optional的威力.函數
再來個複雜的.優化
public class Test {
public static void main(String[] args) {
// creepy initialization step, dont worry
Employee employee = new Employee();
// 優化前
if(employee != null){
Salary salary = employee.getSalary();
if(salary !=null){
Unit unit = salary.getUnit();
if(unit != null){
System.out.println("I discovered the variable finally " + unit);
}
}
}
// 優化後
Optional.ofNullable(employee)
.map(Employee::getSalary)
.map(Salary::getUnit)
.map(Unit::getPrecision)
.ifPresent(e -> System.out.println("I discovered the variable finally " + e));
}
static class Employee {
Salary salary;
public Salary getSalary() {
return salary;
}
public void setSalary(Salary salary) {
this.salary = salary;
}
}
class Salary {
// 單位
Unit unit;
public Unit getUnit() {
return unit;
}
public void setUnit(Unit unit) {
this.unit = unit;
}
}
class Unit {
// 精度
Integer precision;
public Integer getPrecision() {
return precision;
}
public void setPrecision(Integer precision) {
this.precision = precision;
}
}
}
複製代碼
表驅動法是一種編程模式,它的本質是,從表裏查詢信息來代替邏輯語句(if,case)。
舉個簡單的例子
/** * 表驅動法 */
public class TableDrivenApproach {
//private static Map<?, Function<?,?> > actionsMap =new HashMap<>();
// private static Map<Integer, Function<Integer, Integer>> actionsMap = new HashMap<>();
private static HashMap<Integer, Function<Integer, Integer>> actionsMap = new HashMap<>();
static {
actionsMap.put(1, e -> e + 1);
actionsMap.put(2, e -> e + 2);
actionsMap.put(3, e -> e + 3);
}
public static void main(String[] args) {
System.out.println(actionsMap.get(1).apply(0));
System.out.println(actionsMap.get(2).apply(0));
System.out.println(actionsMap.get(3).apply(0));
}
}
複製代碼
if else 的本質是分支判斷,找到一個符合條件的分支而後執行其內部邏輯.
那麼咱們其實能夠把一個一個分支拆成handler,使用責任鏈模式.
static abstract class Handler {
/** * 持有後繼的責任對象 */
protected Handler successor;
/** * 示意處理請求的方法,雖然這個示意方法是沒有傳入參數的 * 但實際是能夠傳入參數的,根據具體須要來選擇是否傳遞參數 */
public abstract void handleRequest();
/** * 取值方法 */
public Handler getSuccessor() {
return successor;
}
/** * 賦值方法,設置後繼的責任對象 */
public void setSuccessor(Handler successor) {
this.successor = successor;
}
}
static class ConcreteHandler extends Handler {
/** * 處理方法,調用此方法處理請求 */
@Override
public void handleRequest() {
/** * 判斷是否有後繼的責任對象 * 若是有,就轉發請求給後繼的責任對象 * 若是沒有,則處理請求 */
if (getSuccessor() != null) {
System.out.println("放過請求");
getSuccessor().handleRequest();
} else {
System.out.println("處理請求");
}
}
}
複製代碼
經過 Java 註解(或其它語言的相似機制)定義執行某個方法/類的條件。
在程序執行時,經過對比入參與註解中定義的條件是否匹配,再決定是否調用此方法。具體實現時,能夠採用表驅動或職責鏈的方式實現。
能夠給個輕量級的規則引擎的例子. easyrules
策略加工廠