【設計模式】(二十二)–行爲型模式–責任鏈模式
責任鏈模式定義
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
意思是:使多個對象都有機會處理請求,從而避免了請求的發送者和接受者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有對象處理他爲止。
責任鏈模式一般有兩個元素:
- Handler 抽象處理器,提供給所有實際處理器進行繼承,擁有一個handleRequest方法,用來接收需要處理的請求。
- Concrete Handler 具體處理器,實現了handleRequest方法。每個具體的處理器都維持一個引用,指向下一個具體處理器。如果自身無法處理請求,則傳遞給下一個具體處理器。
責任鏈模式的優點
- 1、降低耦合度。它將請求的發送者和接收者解耦。
- 2、簡化了對象。使得對象不需要知道鏈的結構。
- 3、增強給對象指派職責的靈活性。通過改變鏈內的成員或者調動它們的次序,允許動態地新增或者刪除責任。
- 4、增加新的請求處理類很方便。
責任鏈模式除了以上優點,但是有如下缺點:
- 1、不能保證請求一定被接收。
- 2、系統性能將受到一定影響,而且在進行代碼調試時不太方便,可能會造成循環調用。
- 3、可能不容易觀察運行時的特徵,有礙於不易於調試、除錯。
責任鏈模式的使用場景
- 1、有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。
- 2、在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
- 3、可動態指定一組對象處理請求。
責任鏈模式的簡單實現
類圖
實現
public class Test {
public static void main(String[] args) {
Garage garage = new Garage();
Car car = new Car("大少", "輪胎", "擋風玻璃", "發動機");
garage.repair(car);
}
}
public class Car {
private String owner;
/**
* 損壞位置列表
*/
private List<String> damageLocationList = null;
public Car(String owner, String... damageLocations) {
this.owner = owner;
damageLocationList = new ArrayList<>();
if (damageLocations == null) {
return;
}
for (String damageLocation : damageLocations) {
damageLocationList.add(damageLocation);
}
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public List<String> getDamageLocationList() {
return damageLocationList;
}
public void setDamageLocationList(List<String> damageLocationList) {
this.damageLocationList = damageLocationList;
}
}
public class Garage {
private AbstractWorkshop repairChain = null;
public Garage() {
AbstractWorkshop gearboxWorkshop = new GearboxWorkshop();
AbstractWorkshop tyreWorkshop = new TyreWorkshop();
AbstractWorkshop windshieldWorkshop = new WindshieldWorkshop();
AbstractWorkshop engineWorkshop = new EngineWorkshop();
gearboxWorkshop.setNextWorkShop(tyreWorkshop);
tyreWorkshop.setNextWorkShop(windshieldWorkshop);
windshieldWorkshop.setNextWorkShop(engineWorkshop);
engineWorkshop.setNextWorkShop(null);
this.repairChain = gearboxWorkshop;
}
public void repair(Car car) {
System.out.println(car.getOwner() + "的車進入維修廠,車損壞部位有" + car.getDamageLocationList());
repairChain.repairCar(car);
}
}
public abstract class AbstractWorkshop {
protected String damageLocation;
protected AbstractWorkshop nextWorkshop;
abstract protected void doRepair(Car car);
protected void setNextWorkShop(AbstractWorkshop workShop) {
this.nextWorkshop = workShop;
}
protected void repairCar(Car car) {
if (car.getDamageLocationList().contains(damageLocation)) {
this.doRepair(car);
} else {
System.out.println(damageLocation + "車間無需處理!");
}
if (nextWorkshop != null) {
nextWorkshop.repairCar(car);
}
}
}
public class EngineWorkshop extends AbstractWorkshop {
public EngineWorkshop() {
this.damageLocation = "發動機";
}
@Override
protected void doRepair(Car car) {
System.out.println("更換發動機!");
}
}
public class GearboxWorkshop extends AbstractWorkshop {
public GearboxWorkshop() {
this.damageLocation = "變速箱";
}
@Override
protected void doRepair(Car car) {
System.out.println("更換變速箱!");
}
}
public class TyreWorkshop extends AbstractWorkshop {
public TyreWorkshop() {
this.damageLocation = "輪胎";
}
@Override
protected void doRepair(Car car) {
System.out.println("更換輪胎!");
}
}
public class WindshieldWorkshop extends AbstractWorkshop {
public WindshieldWorkshop() {
this.damageLocation = "擋風玻璃";
}
@Override
protected void doRepair(Car car) {
System.out.println("更換擋風玻璃!");
}
}
結果
實現說明
一個汽車維修廠,按照維修部門流水線的方式進行維修汽車。