mirror of
https://github.com/LingCoder/OnJava8.git
synced 2026-09-04 05:42:48 +08:00
状态模式
This commit is contained in:
@@ -221,7 +221,205 @@ Implementation.h()
|
||||
|
||||
**状态模式**
|
||||
|
||||
状态模式向代理对象添加了更多的实现,以及在代理对象的生命周期内从一个实现切换到另一种实现的方法:
|
||||
|
||||
```Java
|
||||
// patterns/StateDemo.java // Simple demonstration of the State pattern
|
||||
interface StateBase {
|
||||
void f();
|
||||
|
||||
void g();
|
||||
|
||||
void h();
|
||||
|
||||
void changeImp(StateBase newImp);
|
||||
}
|
||||
|
||||
class State implements StateBase {
|
||||
private StateBase implementation;
|
||||
|
||||
State(StateBase imp) {
|
||||
implementation = imp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeImp(StateBase newImp) {
|
||||
implementation = newImp;
|
||||
}// Pass method calls to the implementation: @Override public void f() { implementation.f(); } @Override public void g() { implementation.g(); } @Override
|
||||
|
||||
public void h() {
|
||||
implementation.h();
|
||||
}
|
||||
}
|
||||
|
||||
class Implementation1 implements StateBase {
|
||||
@Override
|
||||
public void f() {
|
||||
System.out.println("Implementation1.f()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void g() {
|
||||
System.out.println("Implementation1.g()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void h() {
|
||||
System.out.println("Implementation1.h()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeImp(StateBase newImp) {
|
||||
}
|
||||
}
|
||||
|
||||
class Implementation2 implements StateBase {
|
||||
@Override
|
||||
public void f() {
|
||||
System.out.println("Implementation2.f()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void g() {
|
||||
System.out.println("Implementation2.g()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void h() {
|
||||
System.out.println("Implementation2.h()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeImp(StateBase newImp) {
|
||||
}
|
||||
}
|
||||
|
||||
public class StateDemo {
|
||||
static void test(StateBase b) {
|
||||
b.f();
|
||||
b.g();
|
||||
b.h();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
StateBase b = new State(new Implementation1());
|
||||
test(b);
|
||||
b.changeImp(new Implementation2());
|
||||
test(b);
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
Implementation1.f()
|
||||
Implementation1.g()
|
||||
Implementation1.h()
|
||||
Implementation2.f()
|
||||
Implementation2.g()
|
||||
Implementation2.h()
|
||||
*/
|
||||
```
|
||||
|
||||
在main()中,首先使用第一个实现,然后改变成第二个实现。代理模式和状态模式的区别在于它们解决的问题。设计模式中描述的代理模式的常见用途如下:
|
||||
|
||||
1. 远程代理。它在不同的地址空间中代理对象。远程方法调用(RMI)编译器rmic会自动为您创建一个远程代理。
|
||||
|
||||
2. 虚拟代理。这提供了“懒加载”来根据需要创建“昂贵”的对象。
|
||||
|
||||
3. 保护代理。当您希望对代理对象有权限访问控制时使用。
|
||||
|
||||
4. 智能引用。要在被代理的对象被访问时添加其他操作。例如,跟踪特定对象的引用数量,来实现写时复制用法,和防止对象别名。一个更简单的例子是跟踪特定方法的调用数量。您可以将Java引用视为一种保护代理,因为它控制在堆上实例对象的访问(例如,确保不使用空引用)。
|
||||
|
||||
在设计模式中,代理模式和桥接模式并不是相互关联的,因为它们被赋予(我认为是任意的)不同的结构。桥接模式,特别是使用一个单独的实现,但这似乎对我来说是不必要的,除非你确定该实现是你无法控制的(当然有可能,但是如果您编写所有代码,那么没有理由不从单基类的优雅中受益)。此外,只要代理对象控制对其“前置”对象的访问,代模式理就不需要为其实现使用相同的基类。不管具体情况如何,在代理模式和桥接模式中,代理对象都将方法调用传递给具体实现对象。
|
||||
|
||||
**状态机**
|
||||
|
||||
桥接模式允许程序员更改实现,状态机利用一个结构来自动地将实现更改到下一个。当前实现表示系统所处的状态,系统在不同状态下的行为不同(因为它使用桥接模式)。基本上,这是一个利用对象的“状态机”。将系统从一种状态移动到另一种状态的代码通常是模板方法模式,如下例所示:
|
||||
|
||||
```Java
|
||||
// patterns/state/StateMachineDemo.java
|
||||
// The StateMachine pattern and Template method
|
||||
// {java patterns.state.StateMachineDemo}
|
||||
package patterns.state;
|
||||
|
||||
import onjava.Nap;
|
||||
|
||||
interface State {
|
||||
void run();
|
||||
}
|
||||
|
||||
abstract class StateMachine {
|
||||
protected State currentState;
|
||||
|
||||
Nap(0.5);
|
||||
System.out.println("Washing"); new
|
||||
|
||||
protected abstract boolean changeState();
|
||||
|
||||
// Template method:
|
||||
protected final void runAll() {
|
||||
while (changeState()) // Customizable
|
||||
currentState.run();
|
||||
}
|
||||
}
|
||||
|
||||
// A different subclass for each state:
|
||||
class Wash implements State {
|
||||
@Override
|
||||
public void run() {
|
||||
}
|
||||
}
|
||||
|
||||
class Spin implements State {
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Spinning");
|
||||
new Nap(0.5);
|
||||
}
|
||||
}
|
||||
|
||||
class Rinse implements State {
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("Rinsing");
|
||||
new Nap(0.5);
|
||||
}
|
||||
}
|
||||
|
||||
class Washer extends StateMachine {
|
||||
private int i = 0;
|
||||
|
||||
// The state table:
|
||||
private State[] states = {new Wash(), new Spin(), new Rinse(), new Spin(),};
|
||||
|
||||
Washer() {
|
||||
runAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changeState() {
|
||||
if (i < states.length) {
|
||||
// Change the state by setting the
|
||||
// surrogate reference to a new object:
|
||||
currentState = states[i++];
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class StateMachineDemo {
|
||||
public static void main(String[] args) {
|
||||
new Washer();
|
||||
}
|
||||
}
|
||||
/*
|
||||
Output:
|
||||
Washing
|
||||
Spinning
|
||||
Rinsing
|
||||
Spinning
|
||||
*/
|
||||
```
|
||||
|
||||
在这里,控制状态的类(本例中是状态机)负责决定下一个状态。然而,状态对象本身也可以决定下一步移动到什么状态,通常基于系统的某种输入。这是更灵活的解决方案。
|
||||
|
||||
|
||||
<!-- Factories: Encapsulating Object Creation -->
|
||||
|
||||
Reference in New Issue
Block a user