摘要:本文深入浅出的讲述了设计模式中的策略模式
,
并给出了简单的示例
,
例子浅显易懂
,
并附带源代码。
策略
模式属于行为模式,其意图是定义一系列算法,把他们一个个封装起来,并且使他们可以互相替换,本末实使得算法可以独立与使用它的客户而变化。在做文字输入软件的时候,有很多的算法可以对一个正文流进行分析,将这些算法硬编码进使用他们的类中是不可取的,其原因如下:
l
需要换行功能的客户程序如果直接包含换行算法代码的话将会变得复杂,这使得客户程序大并且难以维护,尤其当需要支持多种换行算法时为会更严重。
l
不同的是欧需要不同的算法,我们不想支持我们并不使用的换行算法。
l
当换行功能是客户程序的一个难以分割的成分时,增加新的换行算法或改变现有算法将十分困难。
我们可以定义一些类来封装不同的换行算法,从而避免这些问题,一个以这种方法封装的算法成为策略。
例如一个把数组导出为表格的算法,输入一个数组,导出一个表格,当用户想改变导出的表格时,便可以通过改变输出的算法改变输出的结果。如果输出的内容用以网页显示,则输出
<table><tr><td>Jack</td></tr><tr><td>Maya</td></tr><tr><td>Mikes</td></tr><tr><td>Shadow</td></tr></table>
如果输出的结果用以直接的屏幕输出,则可以输出:
+----+----+-----+------+
|Jack|Maya|Mikes|Shadow|
+----+----+-----+------+
相应的UML如下图所示:
图
1
参与者:
Strategy(
策略
TableExporter):
定义所有支持算法的公共接口。
Context
使用这个接口来调用某
ConcreteStrategy
定义的算法,
ConcreteStrategy(
具体策略,如
HtmlExporter):
以
Strategy
接口实现某具体算法。
Context(
上下文
: client)
:
用一个
ConcreteStrategy
对象来配置。
维护一个对
Strategy
对象的引用。
可定义一个接口来让
Strategy
访问它的数据。
协作关系:
Strategy
和
Context
互相作用以实现选定的算法。当算法被调用时,
Context
可以将该算法所需要的所有数据都传递给该
Strategy,
或者
Context
可以将自身作为一个参数传递给
Strategy
操作,这就让
Strategy
在需要时可以回调
Context
。
Context
将它的客户的请求转发给他的
Strategy
。客户通常创建并传递一个
ConcreteStrategy
对象给该
Context
这样,客户仅与
Context
交互,通常有一系列的
ConcreteStrategy
类可以供客户从中选择。
适用性:
当存在以下情况时使用
Strategy
:
l
许多相关的类仅仅是行为有差别,策略提供了一种多个行为中的一个行为来配置一个类的方法。
l
需要使用一个算法的不同变体。
l
算法使用客户不应该知道的数据。
l
一个类定义了多种行为。
例子相关的代码:
TableExporter
代码:
package
strategy;
public
interface
TableExporter{
public
String getExported(String[] data);
}
HtmlExporter
代码:
package
strategy;
public
class
HtmlExporter
implements
TableExporter{
public
String getExported(String[] data){
if
(data ==
null
){
return
""
;
}
StringBuffer sb =
new
StringBuffer();
sb.append(
"<table>"
);
for
(
int
i=0;i<data.
length
;i++)
sb.append(
"<tr><td>"
+data[i]+
"</td></tr>"
);
sb.append(
"</table>"
);
return
sb.toString();
}
}
LineExporter
代码:
package
strategy;
public
class
LineExporter
implements
TableExporter{
public
String getExported(String[] data){
if
(data ==
null
){
return
""
;
}
StringBuffer top =
new
StringBuffer(
"+"
);
StringBuffer mid =
new
StringBuffer(
"|"
);
for
(
int
i =0;i<data.
length
;i++){
String str = data[i];
for
(
int
j=0;j<str.length();j++)
top.append(
"-"
);
mid.append(str);
top.append(
"+"
);
mid.append(
"|"
);
}
top.append(
"\n"
);
mid.append(
"\n"
);
return
top.toString()+mid.toString()+top.toString();
}
}
Client
代码:
package
strategy;
public
class
Client{
public
static
void
main(String[] args){
String[] data =
new
String[]{
"Jack"
,
"Maya"
,
"Mikes"
,
"Shadow"
};
TableExporter tb;
tb =
new
HtmlExporter();
System.
out
.println(tb.getExported(data));
tb =
new
LineExporter();
System.
out
.println(tb.getExported(data));
}
}
总结:
Strategy
策略使得改变一个算法的实现比较容易,在
Java
中的组件的布局便采用了策略模式,使用靠昨对齐还是居中对齐只是算法的区别。
附件:http://down.51cto.com/data/2348614
本文转自凌辉博客51CTO博客,原文链接http://blog.51cto.com/tianli/45377如需转载请自行联系原作者
lili00okok