在日常开发中,常常会作一些状态判断,用到
swich-case
与
if-else
。在面向对象的环境里,有两种方式可以替代它们。一种是使用继承子类的多态,另一种是使用
state
模式。它们使用对象的间接性有效地摆脱了传统的状态判断。
举个例子。
Method.java
package
com.zj.original;
import
com.zj.utils.NoMethodTypeException;
public
class
Method {
private
int
_type
;
public
static
final
int
POST
= 0;
public
static
final
int
GET
= 1;
public
static
final
int
PUT
= 2;
public
static
final
int
DELETE
= 3;
public
Method(
int
type) {
_type
= type;
}
public
String getMethod()
throws
NoMethodTypeException {
switch
(
_type
) {
case
POST
:
return
"This is POST method"
;
case
GET
:
return
"This is GET method"
;
case
PUT
:
return
"This is PUT method"
;
case
DELETE
:
return
"This is DELETE method"
;
default
:
throw
new
NoMethodTypeException();
}
}
public
boolean
safeMethod() {
if
(
_type
==
GET
)
return
true
;
else
return
false
;
}
public
boolean
passwordRequired() {
if
(
_type
==
POST
)
return
false
;
else
return
true
;
}
}
|
类
Method
中,存在四个状态
Post
、
Get
、
Put
和
Delete
。有一个
switch-case
判断,用于输出四种方法的描述信息;两个
if-else
判断,分别判断方法是否安全
(
只有
Get
方法是安全的
)
,方法是否需要密码
(
只有
Post
方法不需要密码
)
。
1.
使用继承子类多态
使用继承子类多态的方式,通常对于某个具体对象,它的状态是不可改变的
(
在对象的生存周期中
)
。
现在使用四个子类分别代表四种类型的方法。这样就可以使用多态将各个方法的具体逻辑分置到子类中去了。
在抽象基类
Method
中可以提供创建子类实例的静态方法,当然也可以使用
Simple Factory
模式。对于
getMethod()
方法,延迟到子类中实现;对于
safeMethod()
方法和
passwordRequired()
方法,提供一个默认的实现,这个实现应该符合绝大部分子类的要求,这样的话,对于少数不符合默认实现的子类只需
override
相应方法即可。
<>Method.java
package
com.zj.subclass;
public
abstract
class
Method {
public
final
static
Method createPostMethod() {
return
new
PostMethod();
}
public
final
static
Method createGetMethod() {
return
new
GetMethod();
}
public
final
static
Method createPutMethod() {
return
new
PutMethod();
}
public
final
static
Method createDeleteMethod() {
return
new
DelMethod();
}
abstract
public
String getMethod();
public
boolean
safeMethod() {
return
false
;
}
public
boolean
passwordRequired() {
return
true
;
}
}
|
四个子类分别继承和
override
相应的方法。
PostMethod.java
package
com.zj.subclass;
public
class
PostMethod
extends
Method {
@Override
public
String getMethod() {
return
"This is POST method"
;
}
@Override
public
boolean
passwordRequired() {
return
false
;
}
}
|
GetMethod.java
package
com.zj.subclass;
public
class
GetMethod
extends
Method{
@Override
public
String getMethod() {
return
"This is GET method"
;
}
@Override
public
boolean
safeMethod() {
return
true
;
}
}
|
PutMethod.java
package
com.zj.subclass;
public
class
PutMethod
extends
Method {
@Override
public
String getMethod() {
return
"This is PUT method"
;
}
}
|
DelMethod.java
package
com.zj.subclass;
public
class
DelMethod
extends
Method{
@Override
public
String getMethod(){
return
"This is DELETE method"
;
}
}
|
2.
使用
state
模式
如果希望对象在生存周期内,可以变化自己的状态,则可以选择
state
模式。
这里抽象状态为一个接口
MethodType
,四种不同的状态实现该接口。
<>MethodType.java
package
com.zj.state;
public
interface
MethodType {
String getTypeDescription();
String getMethodDescription();
boolean
isSafe();
boolean
isRequired();
}
|
Post.java
package
com.zj.state;
public
class
Post
implements
MethodType{
public
String getMethodDescription() {
return
"This is POST method"
;
}
public
String getTypeDescription() {
return
"===POST==="
;
}
public
boolean
isRequired() {
return
false
;
}
public
boolean
isSafe() {
return
false
;
}
}
|
Get.java
package
com.zj.state;
public
class
Get
implements
MethodType{
public
String getMethodDescription() {
return
"This is GET method"
;
}
public
String getTypeDescription() {
return
"===GET==="
;
}
public
boolean
isRequired() {
return
true
;
}
public
boolean
isSafe() {
return
true
;
}
}
|
Put.java
package
com.zj.state;
public
class
Put
implements
MethodType{
public
String getMethodDescription() {
return
"This is PUT method"
;
}
public
String getTypeDescription() {
return
"===PUT==="
;
}
public
boolean
isRequired() {
return
true
;
}
public
boolean
isSafe() {
return
false
;
}
}
|
Delete.java
package
com.zj.state;
public
class
Delete
implements
MethodType{
public
String getMethodDescription() {
return
"This is DELETE method"
;
}
public
String getTypeDescription() {
return
"===DELETE==="
;
}
public
boolean
isRequired() {
return
true
;
}
public
boolean
isSafe() {
return
false
;
}
}
|
此时,在类
Method
中保存一个
field
表示
MethodType
,在某对象中,可以随时变化四种已知的状态
(
具体见
runAllMethods()
方法
)
。
Method.java
package
com.zj.state;
public
class
Method {
private
MethodType
_type
;
public
Method() {
_type
=
null
;
}
public
Method(MethodType type) {
_type
= type;
}
public
String getMethod() {
return
_type
.getMethodDescription();
}
public
boolean
safeMethod() {
return
_type
.isSafe();
}
public
boolean
passwordRequired() {
return
_type
.isRequired();
}
public
void
changeType(MethodType type) {
_type
= type;
}
public
void
runAllMethods() {
MethodType[] types =
new
MethodType[] {
new
Post(),
new
Get(),
new
Put(),
new
Delete() };
for
(MethodType type : types) {
System.
out
.println(type.getTypeDescription());
changeType(type);
System.
out
.println(getMethod());
System.
out
.println(safeMethod());
System.
out
.println(passwordRequired());
}
}
}
|
3.测试
在测试类中,分别使用上面
3
中机制展示结果。它们的结果应该是一致的。
Client.java
package
com.zj.utils;
public
class
Client {
static
void
print(String s) {
System.
out
.println(s);
}
static
void
print(Boolean b) {
System.
out
.println(b);
}
public
static
void
main(String[] args)
throws
NoMethodTypeException {
print(
"===original==="
);
print(
"===POST==="
);
com.zj.original.Method post1 =
new
com.zj.original.Method(
com.zj.original.Method.
POST
);
print(post1.getMethod());
print(post1.safeMethod());
print(post1.passwordRequired());
print(
"===GET==="
);
com.zj.original.Method get1 =
new
com.zj.original.Method(
com.zj.original.Method.
GET
);
print(get1.getMethod());
print(get1.safeMethod());
print(get1.passwordRequired());
print(
"===PUT==="
);
com.zj.original.Method put1 =
new
com.zj.original.Method(
com.zj.original.Method.
PUT
);
print(put1.getMethod());
print(put1.safeMethod());
print(put1.passwordRequired());
print(
"===DELETE==="
);
com.zj.original.Method del1 =
new
com.zj.original.Method(
com.zj.original.Method.
DELETE
);
print(del1.getMethod());
print(del1.safeMethod());
print(del1.passwordRequired());
print(
"===subclass==="
);
print(
"===POST==="
);
com.zj.subclass.Method post2 = com.zj.subclass.Method
.createPostMethod();
print(post2.getMethod());
print(post2.safeMethod());
print(post2.passwordRequired());
print(
"===GET==="
);
com.zj.subclass.Method get2 = com.zj.subclass.Method.createGetMethod();
print(get2.getMethod());
print(get2.safeMethod());
print(get2.passwordRequired());
print(
"===PUT==="
);
com.zj.subclass.Method put2 = com.zj.subclass.Method.createPutMethod();
print(put2.getMethod());
print(put2.safeMethod());
print(put2.passwordRequired());
print(
"===DELETE==="
);
com.zj.subclass.Method del2 = com.zj.subclass.Method
.createDeleteMethod();
print(del2.getMethod());
print(del2.safeMethod());
print(del2.passwordRequired());
print(
"===state==="
);
new
com.zj.state.Method().runAllMethods();
}
}
|