Skip to content

Commit c1bd578

Browse files
committed
状态模式
1 parent d88a940 commit c1bd578

File tree

1 file changed

+198
-0
lines changed

1 file changed

+198
-0
lines changed

docs/book/25-Patterns.md

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,205 @@ Implementation.h()
221221

222222
**状态模式**
223223

224+
状态模式向代理对象添加了更多的实现,以及在代理对象的生命周期内从一个实现切换到另一种实现的方法:
224225

226+
```Java
227+
// patterns/StateDemo.java // Simple demonstration of the State pattern
228+
interface StateBase {
229+
void f();
230+
231+
void g();
232+
233+
void h();
234+
235+
void changeImp(StateBase newImp);
236+
}
237+
238+
class State implements StateBase {
239+
private StateBase implementation;
240+
241+
State(StateBase imp) {
242+
implementation = imp;
243+
}
244+
245+
@Override
246+
public void changeImp(StateBase newImp) {
247+
implementation = newImp;
248+
}// Pass method calls to the implementation: @Override public void f() { implementation.f(); } @Override public void g() { implementation.g(); } @Override
249+
250+
public void h() {
251+
implementation.h();
252+
}
253+
}
254+
255+
class Implementation1 implements StateBase {
256+
@Override
257+
public void f() {
258+
System.out.println("Implementation1.f()");
259+
}
260+
261+
@Override
262+
public void g() {
263+
System.out.println("Implementation1.g()");
264+
}
265+
266+
@Override
267+
public void h() {
268+
System.out.println("Implementation1.h()");
269+
}
270+
271+
@Override
272+
public void changeImp(StateBase newImp) {
273+
}
274+
}
275+
276+
class Implementation2 implements StateBase {
277+
@Override
278+
public void f() {
279+
System.out.println("Implementation2.f()");
280+
}
281+
282+
@Override
283+
public void g() {
284+
System.out.println("Implementation2.g()");
285+
}
286+
287+
@Override
288+
public void h() {
289+
System.out.println("Implementation2.h()");
290+
}
291+
292+
@Override
293+
public void changeImp(StateBase newImp) {
294+
}
295+
}
296+
297+
public class StateDemo {
298+
static void test(StateBase b) {
299+
b.f();
300+
b.g();
301+
b.h();
302+
}
303+
304+
public static void main(String[] args) {
305+
StateBase b = new State(new Implementation1());
306+
test(b);
307+
b.changeImp(new Implementation2());
308+
test(b);
309+
}
310+
}
311+
/* Output:
312+
Implementation1.f()
313+
Implementation1.g()
314+
Implementation1.h()
315+
Implementation2.f()
316+
Implementation2.g()
317+
Implementation2.h()
318+
*/
319+
```
320+
321+
在main()中,首先使用第一个实现,然后改变成第二个实现。代理模式和状态模式的区别在于它们解决的问题。设计模式中描述的代理模式的常见用途如下:
322+
323+
1. 远程代理。它在不同的地址空间中代理对象。远程方法调用(RMI)编译器rmic会自动为您创建一个远程代理。
324+
325+
2. 虚拟代理。这提供了“懒加载”来根据需要创建“昂贵”的对象。
326+
327+
3. 保护代理。当您希望对代理对象有权限访问控制时使用。
328+
329+
4. 智能引用。要在被代理的对象被访问时添加其他操作。例如,跟踪特定对象的引用数量,来实现写时复制用法,和防止对象别名。一个更简单的例子是跟踪特定方法的调用数量。您可以将Java引用视为一种保护代理,因为它控制在堆上实例对象的访问(例如,确保不使用空引用)。
330+
331+
在设计模式中,代理模式和桥接模式并不是相互关联的,因为它们被赋予(我认为是任意的)不同的结构。桥接模式,特别是使用一个单独的实现,但这似乎对我来说是不必要的,除非你确定该实现是你无法控制的(当然有可能,但是如果您编写所有代码,那么没有理由不从单基类的优雅中受益)。此外,只要代理对象控制对其“前置”对象的访问,代模式理就不需要为其实现使用相同的基类。不管具体情况如何,在代理模式和桥接模式中,代理对象都将方法调用传递给具体实现对象。
332+
333+
**状态机**
334+
335+
桥接模式允许程序员更改实现,状态机利用一个结构来自动地将实现更改到下一个。当前实现表示系统所处的状态,系统在不同状态下的行为不同(因为它使用桥接模式)。基本上,这是一个利用对象的“状态机”。将系统从一种状态移动到另一种状态的代码通常是模板方法模式,如下例所示:
336+
337+
```Java
338+
// patterns/state/StateMachineDemo.java
339+
// The StateMachine pattern and Template method
340+
// {java patterns.state.StateMachineDemo}
341+
package patterns.state;
342+
343+
import onjava.Nap;
344+
345+
interface State {
346+
void run();
347+
}
348+
349+
abstract class StateMachine {
350+
protected State currentState;
351+
352+
Nap(0.5);
353+
System.out.println("Washing"); new
354+
355+
protected abstract boolean changeState();
356+
357+
// Template method:
358+
protected final void runAll() {
359+
while (changeState()) // Customizable
360+
currentState.run();
361+
}
362+
}
363+
364+
// A different subclass for each state:
365+
class Wash implements State {
366+
@Override
367+
public void run() {
368+
}
369+
}
370+
371+
class Spin implements State {
372+
@Override
373+
public void run() {
374+
System.out.println("Spinning");
375+
new Nap(0.5);
376+
}
377+
}
378+
379+
class Rinse implements State {
380+
@Override
381+
public void run() {
382+
System.out.println("Rinsing");
383+
new Nap(0.5);
384+
}
385+
}
386+
387+
class Washer extends StateMachine {
388+
private int i = 0;
389+
390+
// The state table:
391+
private State[] states = {new Wash(), new Spin(), new Rinse(), new Spin(),};
392+
393+
Washer() {
394+
runAll();
395+
}
396+
397+
@Override
398+
public boolean changeState() {
399+
if (i < states.length) {
400+
// Change the state by setting the
401+
// surrogate reference to a new object:
402+
currentState = states[i++];
403+
return true;
404+
} else return false;
405+
}
406+
}
407+
408+
public class StateMachineDemo {
409+
public static void main(String[] args) {
410+
new Washer();
411+
}
412+
}
413+
/*
414+
Output:
415+
Washing
416+
Spinning
417+
Rinsing
418+
Spinning
419+
*/
420+
```
421+
422+
在这里,控制状态的类(本例中是状态机)负责决定下一个状态。然而,状态对象本身也可以决定下一步移动到什么状态,通常基于系统的某种输入。这是更灵活的解决方案。
225423

226424

227425
<!-- Factories: Encapsulating Object Creation -->

0 commit comments

Comments
 (0)