【设计模式】(二十二)–行为型模式–责任链模式
责任链模式定义
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("更换挡风玻璃!");
}
}
结果
实现说明
一个汽车维修厂,按照维修部门流水线的方式进行维修汽车。