- 浏览: 113847 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
ccfangle:
bestchenwu 写道什么时候用“==”还是“equals ...
操作符“==”与对象的equals()方法 -
bestchenwu:
什么时候用“==”还是“equals()”,跟你是把这个对象作 ...
操作符“==”与对象的equals()方法
Strategy : choosing the algorithm at run-time
Strategy also adds a “Context” which can be a surrogate class that controls the selection and use of the particular strategy object—just like State ! Here’s what it looks like:
//: strategy:StrategyPattern.java
package strategy;
import com.bruceeckel.util.*; // Arrays2.toString()
import junit.framework.*;
// The strategy interface:
interface FindMinima {
// Line is a sequence of points:
double[] algorithm(double[] line);
}
// The various strategies:
class LeastSquares implements FindMinima {
public double[] algorithm(double[] line) {
return new double[] { 1.1, 2.2 }; // Dummy
}
}
class NewtonsMethod implements FindMinima {
public double[] algorithm(double[] line) {
return new double[] { 3.3, 4.4 }; // Dummy
}
}
class Bisection implements FindMinima {
public double[] algorithm(double[] line) {
return new double[] { 5.5, 6.6 }; // Dummy
}
}
class ConjugateGradient implements FindMinima {
public double[] algorithm(double[] line) {
return new double[] { 3.3, 4.4 }; // Dummy
}
}
// The "Context" controls the strategy:
class MinimaSolver {
private FindMinima strategy;
public MinimaSolver(FindMinima strat) {
strategy = strat;
}
double[] minima(double[] line) {
return strategy.algorithm(line);
}
void changeAlgorithm(FindMinima newAlgorithm) {
strategy = newAlgorithm;
}
}
public class StrategyPattern extends TestCase {
MinimaSolver solver =
new MinimaSolver(new LeastSquares());
double[] line = {
1.0, 2.0, 1.0, 2.0, -1.0,
3.0, 4.0, 5.0, 4.0 };
public void test() {
System.out.println(
Arrays2.toString(solver.minima(line)));
solver.changeAlgorithm(new Bisection());
System.out.println(
Arrays2.toString(solver.minima(line)));
}
public static void main(String args[]) {
junit.textui.TestRunner.run(StrategyPattern.class);
}
} ///:~
//何止是相像,简直就是一样,从教程中的利用接口+组合来完成的过程,这个实现过程和State是一模一样!
//那么该如何理解这些模式之间的区别呢?很多实现的示例是通过继承(http://www.jdon.com/designpatterns/designpattern_Strategy.htm )来实现的,这个比较让人迷惑...但是,有一点//是可以肯定
//的:重要的是设计思想,只要是这个掌握了,具体使用哪个模式是可以转化重构!
倒是这些资料很有提示性:
http://archive.cnblogs.com/a/1420362/
http://zhongkang.iteye.com/blog/152403
http://blog.163.com/chenxuezhen_1/blog/static/9167375120100134622841/
具体的总结,得后续完结!(2011-12-29)
//重新整理了一下其中一个参考内容,感觉这个例子还是比较好的!
Strategy Pattern/State Pattern
(1)Strategy Pattern
(i)定义:定义了算法族,把变化的各个部分封装起来,使得算法可以相互替换并独立于使用该算法的客户。
(ii)结构图:见 4-State (Strategy和State的结构图是一样的)
分析:Strategy模式的接口封装了Context(应用类)中变化的部分,然后在Context中引用了封装的接口,把变化的部分操作委托给Strategy来实现,这样就可以在具体使用中,指定对应的类来实现封装类的不同实现。
class Employees{
String height;
String weight;
String diploma;
String role;
short hours;
int bonus;
int earning;
Employees(String role,short hours){
this.role = role;
this.hours = hours;
}
Employees(String role,int bonus){
this.role = role;
this.bonus = bonus;
}
Employees(String role,int bonus,int earning){
this.role = role;
this.bonus = bonus;
this.earning = earning;
}
public String Description(){
String desc="";
desc += "Heighht:"+height+";";
desc += "Weighht:"+weight+";";
desc += "Diploma:"+diploma+";";
return desc;
}
public double getWage(){
double wage = 0;
if("temp".equals(role)){
wage = 10*hours;
}
else if("accountant".equals(role)){
wage = 2000+ bonus;
}
else if("manager".equals(role)){
wage = 5000+bonus+ earning*0.05;
}
//还有其他的角色....
return wage;
}
public static void main(String[] args){
short s = 10;
Employees e = new Employees("temp",s);
System.out.println("Wage :"+e.getWage());
}
}
interface Wage{
double getWage();
}
public class TempWage implements Wage {
short hours;
TempWage(short hours){
this.hours = hours;
}
public double getWage() {
return 10*hours;
}
}
public class AccountantWage implements Wage {
int bonus;
AccountantWage(int bonus){
this.bonus = bonus;
}
public double getWage() {
return 2000+bonus;
}
}
public class ManagerWage implements Wage {
int bonus;
int earning;
ManagerWage(int bonus,int earning){
this.bonus = bonus;
this.earning = earning;
}
public double getWage() {
return 5000+bonus+earning*0.5;
}
}
class Employees2{
String height;
String weight;
String diploma;
String role;
Wage wage;
Employees2(Wage wage){
this.wage = wage;
}
public String Description(){
String desc="";
desc += "Heighht:"+height+";";
desc += "Weighht:"+weight+";";
desc += "Diploma:"+diploma+";";
return desc;
}
public double getWage(){
//double wage = 0;
return wage.getWage();
}
public static void main(String[] args){
short s = 12;
Wage wage = new TempWage(s);
double d = new Employees2(wage).getWage();
System.out.println("Wage = "+d);
}
}
(i) 定义:允许对象在内部状态改变的时候改变其行为,使得对象看起来好像改变了它的类。
(ii) 结构图:见 4-State (Strategy和State的结构图是一样的)
(iii) 意图:把与对象状态相关的行为放入状态组成的类中,使对象状态的行为能够随着状态的改变而该变。
(iv) 用到的OO原则:和Strategy Pattern一样。
(v) 具体样例:
这里我们用TCP连接来举例,TCP连接有三个状态:Open,Lisening, Close,初步实现如下:
package com.xforward.test.state;
enum StateFlag{
OPEN,CLOSED,LISTENING
}
public class TCPConnection {
StateFlag state = StateFlag.CLOSED;
public String Open(){
if(state == StateFlag.OPEN){
return "TCP has been opened";
}else if(state == StateFlag.CLOSED){
state = StateFlag.OPEN;
return "open successfully";
}else if(state == StateFlag.LISTENING){
return "TCP is listening";
}
return null;
}
public String Close(){
if(state == StateFlag.OPEN){
state =StateFlag.CLOSED;
return "Closed Successfully";
}else if(state == StateFlag.CLOSED){
return "TCP has been closed";
}else if(state == StateFlag.LISTENING){
state =StateFlag.CLOSED;
return "Closed Successfully";
}
return null;
}
public String Listening(){
if(state == StateFlag.OPEN){
state =StateFlag.LISTENING;
return "Listen Successfully";
}else if(state == StateFlag.CLOSED){
return "TCP has been closed";
}else if(state == StateFlag.LISTENING){
return "TCP is listening";
}
return null;
}
}
这样,如果我们每加一个State的话,要为每个函数都加一条实现语句,不仅麻烦还很容易出现bug.于是我们就想到了State Pattern。(这个例子需要后续完善一下,尤其是测试部分,不是很自然)
实现一个State接口:
package com.xforward.test.state;
public interface State {
String open();
String close();
String listening();
}
实现各个具体状态类:
package com.xforward.test.state;
public class OpenState implements State {
TCPConnection2 tcp;//用于记录状态
OpenState(TCPConnection2 tcp){
this.tcp = tcp;
}
public String open() {
return "TCP has been opened";
}
public String close() {
tcp.state1 = tcp.closeState;
return "Closed Successfully";
}
public String listening() {
tcp.state1 = tcp.listenState;
return "Listen Successfully";
}
}
package com.xforward.test.state;
public class ListenState implements State {
TCPConnection2 tcp;//用于记录状态
ListenState(TCPConnection2 tcp){
this.tcp = tcp;
}
public String open() {
return "TCP is listening";
}
public String close() {
tcp.state1 = tcp.closeState;
return "Closed Successfully";
}
public String listening() {
return "TCP is listening";
}
}
package com.xforward.test.state;
public class CloseState implements State {
TCPConnection2 tcp;//用于记录状态
CloseState(TCPConnection2 tcp){
this.tcp = tcp;
}
public String open() {
tcp.state1 = tcp.openState;
return "Open Successfully";
}
public String close() {
return "TCP has been Closed";
}
public String listening() {
tcp.state1 = tcp.listenState;
return "Listen Successfully";
}
}
这样改了之后TCPConnection就可以写成:
package com.xforward.test.state;
public class TCPConnection2 {
OpenState openState = new OpenState(this);
CloseState closeState = new CloseState(this);
ListenState listenState = new ListenState(this);
State state1 = closeState ;
public static void main(String[] args){
TCPConnection2 t = new TCPConnection2();
t.state1.close();
t.state1.open();
t.state1.listening();
}
}
使用State Pattern后如果加入新的状态,我们只需要加入新状态的一个State子类就可以了。
(3)Strategy Pattern和State Pattern 异同点:
(i)相同点:两种模式的结构图一样,做法都是用接口或者抽象类来封装变化的方法。一般来说在类中有许多判断语句的时候就可以考虑使用这两种模式。(当然模式使用 时基于变化的,如果判断语句的条件是定死的,那么不用设计模式也没有问题)
(ii) 不同点:意图不一样:State Pattern中很显著的特点就是有状态和行为,并且行为随着状态的改变而改变,相当于判断语句中的条件是一种种状态。State Pattern中实现的状态子类中是有耦合的。而Strategy Pattern,我个人认为判断语句中的条件是类别,不同的类型实现的操作不一样,这样就可以把操作抽象出来。抽象出来的操作子类之间是解耦的。
发表评论
-
25-设计模式学习总结
2012-02-06 15:42 985在学习Thinking in patterns之前 ... -
24-Prototype
2012-02-06 14:56 863Prototype(原型模式):用原型实例指定创建 ... -
23-Interpreter
2012-02-05 14:51 901If the application user n ... -
22-Visitor
2012-02-05 11:12 847The assumption is that yo ... -
21-Memento
2012-02-03 17:57 921Use serialization to crea ... -
20-Chain of responsibility
2012-02-03 16:25 955Chain of Responsibility ... -
19-Command: choosing the operation at run-time
2012-02-01 17:45 933A Command is a function o ... -
18-Facade
2012-01-15 15:22 900Facade模式 : 为子系统中的一组接口提供一个一致的 ... -
17-Mediator
2012-01-14 19:40 825Mediator模式:用一个中介对象来封装一系列 ... -
16-Observer
2012-01-12 21:35 752好久之前看过Observer,但是,当时不是很清楚 ... -
15-Composite
2012-01-12 10:11 827Composite模式,有时又叫做部分-整体模式(Pa ... -
14-Bridge
2012-01-11 17:06 823思考了好一阵,总 ... -
13-Adapter
2012-01-10 21:38 762接下来的两个模式目的就是:Connecting differe ... -
12-Decorator:too many classes
2012-01-06 20:17 952呵,从翻译这 ... -
11-Flyweight: too many objects
2012-01-06 16:10 921The odd thing about flyweight, ... -
10-Builder
2012-01-06 09:14 798The goal of builder is to separ ... -
9-Factory method(Simple Factory method&Abstract factories)
2012-01-03 19:16 840//工厂方法的理解比较容易,重要还是如何在实践中应用。以下范例 ... -
8-Template method
2012-01-01 20:50 718An application framework allow ... -
7-Policy: generalized strategy
2012-01-01 15:58 1118Although GoF says that Policy i ... -
5-Iterators: decoupling algorithms from containers
2011-12-27 15:39 855In the process, he realized th ...
相关推荐
描述IGP的经典书籍,CCIE 之路必备资料。
OSPF部署规划大型的网络,给学友们的东东!!!!!希望大家下来看看!!!
Explores the criteria for choosing a strategy or a class of equipment, and provides tools for efficient and effective test-strategy decisions. Explores engineering, marketing and management concerns ...
* 1.3.2: Fix windows not responding and focus-follows-mouse choosing the wrong window, add an option to open windows as master * 1.3.3: Fix movement losing windows, add workaround for steam update ...
training* protocol, which is taking all the samples from one domain as the source or target domain, and *dowm-sample* protocol, which is choosing 20 or 8 samples per category to use as the domain data...
NGUI 是一款非常强大的 UI 系统和...- NEW: You can now specify per-symbol colorization settings, choosing which symbols get affected by label colors and which don't. - FIX: UIProgressBar.onChange will exe
git clone https://github.com/jianhuchen/Course-Choosing-SSE-USTC.git 修改配置文件conf.py 在项目根目录运行: python main.py 退出方法 使用ps -aux命令,找到此进程的PID(如:10036),再用kill 10036杀死...
数据到单词 人类在记忆或交流1和0方面不是很熟练,但是我们在使用单词进行交流方面很熟练。 该项目试图将数据转换为无需使用... -seed=0: Seed for choosing words -size=0: Dictionary size. 0 to select the maximu
To view the sample's output in Xcode, open the Console by choosing "Console" from the "Run" menu (or entering Command-Shift-R). See the comments for -countByEnumeratingWithState:objects:count: for ...
六年级上英语学案-Unit 4 Choosing a gift Lesson 5 北师大版.docx
container: 'juma-quiz', // className of the container surrounding the questions, default is 'juma-quiz' progress: true, // show progress bar, default is true nextAuto: false // show next question ...
选择 JavaScript 框架中的示例应用程序这些是来自选择 JavaScript 框架中的应用程序。提供文件如果需要 Web 服务器,请执行: ./serve只要进程正在运行,这个应用程序中的文件就可以通过访问; Ctrl-C杀死服务器。...
It is the book to help you choose the correct database technology at a time when concepts such as Big Data, NoSQL and NewSQL are making what used to be an easy choice into a complex decision with ...
choosing the option "Use a File Installation Key" and supply the following FIK 09806-07443-53955-64350-21751-41297 b) Replace/overwrite libmwservices.dlib with the patched one. By default, path should...
The choices you make about which technologies to focus on and which business domains to master have at least as much impact on your success as your technical knowledge itself--don't let those choices ...
Enterprises are experimenting with using Hadoop to build Big Data Lakes, but many projects are stalling or failing because the approaches that worked at Internet companies have to be adopted for the ...
- Install choosing the option "Use a File Installation Key" and supply the following FIK 09806-07443-53955-64350-21751-41297 - To install Matlab Production Server,using this 40236-45817-26714-51426-...
You’ll study the difference between supervised and unsupervised models, as well as the importance of choosing the appropriate algorithm for each dataset. You’ll apply unsupervised clustering ...
logback贡献 制作说明 运行以下命令进行构建: ... or (per the licensee's choosing) under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation.