目的
Balking Pattern用于防止对象在不完整或不适当的情况下执行某些代码。
维基百科说
balking模式是一种软件设计模式,仅在对象处于特定状态时才对对象执行操作。例如,如果一个对象读取ZIP文件,而一个调用方法在zip文件未打开时调用该对象的get方法,则该对象将在请求时“停止”。例如,在Java编程语言中,在这些情况下可能会抛出IllegalStateException。
源代码
在这个示例实现中,WashingMachine是一个对象,它有两种状态:启用和清洗。如果机器已启用,则状态将更改为“正在清洗”,任何其他线程都无法调用及执行此操作。另一方面,如果它已经清洗过,则任何其他线程无法再执行wash()操作。
类图

第1步:创建洗衣机类。
package com.iluwatar.balking;
import org.slf4j.Logger; import org.slf4j.LoggerFactory;
/<strong> * Washing machine class */ public class WashingMachine {
private static final Logger LOGGER = LoggerFactory.getLogger(WashingMachine.class);
private WashingMachineState washingMachineState;
public WashingMachine() { washingMachineState = WashingMachineState.ENABLED; }
public WashingMachineState getWashingMachineState() { return washingMachineState; }
/</strong> * Method responsible for washing * if the object is in appropriate state */ public void wash() { synchronized (this) { LOGGER.info("{}: Actual machine state: {}", Thread.currentThread().getName(), getWashingMachineState()); if (washingMachineState == WashingMachineState.WASHING) { LOGGER.error("ERROR: Cannot wash if the machine has been already washing!"); return; } washingMachineState = WashingMachineState.WASHING; } LOGGER.info("{}: Doing the washing", Thread.currentThread().getName()); try { Thread.sleep(50); } catch (InterruptedException ie) { ie.printStackTrace(); } endOfWashing(); }
/<strong> * Method responsible of ending the washing * by changing machine state */ public synchronized void endOfWashing() { washingMachineState = WashingMachineState.ENABLED; LOGGER.info("{}: Washing completed.", Thread.currentThread().getId()); }
}
|
第2步: 创建WashingMachineState描述机器的状态,它可以启用并准备好在洗涤期间工作。
package com.iluwatar.balking;
public enum WashingMachineState { ENABLED, WASHING }
|
第3步:让我们测试一下这种设计模式。
public class BalkingPatternDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/</strong> * @param args the command line arguments - not used */ public static void main(String... args) { final WashingMachine washingMachine = new WashingMachine(); ExecutorService executorService = Executors.newFixedThreadPool(3); for (int i = 0; i < 3; i++) { executorService.execute(washingMachine::wash); } executorService.shutdown(); try { executorService.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException ie) { LOGGER.error("ERROR: Waiting on executor service shutdown!"); } }
}
|
适用性
使用Balking模式时
- 对象通常只处于一种容易暂时停止的状态,但时间不确定。