r******r 发帖数: 700 | 1 原来的 code:
for(FileDefinition file : FileDefinitions){
if( filePath.contains("Generic")){
HashSet entries = file.loadGenericLexicon();
}else if( filePath.contains("NNP")){
HashSet entries = file.loadNNPLexicon();
}else if( filePath.contains("TPO")){
HashSet entries = file.loadTPOLexicon();
}
}
class FileDefinition{
...
public HashSet loadGenericLexicon(){
HashSet features = new HashSet();
// reach each line from a file, extract information and store
...
return features
}
public HashSet loadNNPLexicon(){
// similar as above
}
public HashSet loadTPOLexicon(){
// similar as above
}
}
Refactoring Code (是不是很有点多此一举的感觉?):
for(FileDefinition file : FileDefinitions){
if( filePath.contains("Generic")){
HashSet entries = file.load(StrategyType.GenericLexicon);
}else if( filePath.contains("NNP")){
HashSet entries = file.load(StrategyType.NNPLexicon);;
}else if( filePath.contains("TPO")){
HashSet entries = file.load(StrategyType.TPOLexicon);
}
}
class FileDefinition{
...
private LoadContext loadContext_;
HashSet load(StrategyType type ){
switch( type ){
case GenericLexicon:
loadContext_ = new LoadContext(new GenericLexiconLoad(resource,
language));
break;
case NNPLexicon:
loadContext_ = new LoadContext(new NNPLexiconLoad(resource,
language));
break;
case TPOLexicon:
loadContext_ = new LoadContext(new TPOLexiconLoad(resource,
language));
break;
default:
throw new RuntimeException("Invalid strategy type: " + type);
}
return loadContext_.executeLoad();
}
interface LoadStrategy{
HashSet load();
public static enum StrategyType { GenericLexicon, NNPLexicon, TPOLexicon
}
public static final String LABEL_MARKER = "**";
}
abstract class LexiconLoad implements LoadStrategy{
protected String resource_;
protected Language language_;
public LexiconLoad(){
resource_ = null;
language_ = null;
}
public LexiconLoad(String resource, Language language){
resource_ = resource;
language_ = language;
}
public abstract HashSet load();
}
class NNPLexiconLoad extends LexiconLoad{
public NNPLexiconLoad(String resource, Language language){
super(resource, language);
}
public HashSet load(){
HashSet features = new HashSet();
...
return features;
}
}
class TPOLexiconLoad extends LexiconLoad{
public TPOLexiconLoad(String resource, Language language){
super(resource, language);
}
public HashSet load(){
HashSet features = new HashSet();
...
return features;
}
}
class GenericLexiconLoad extends LexiconLoad{
public GenericLexiconLoad(String resource, Language language){
super(resource, language);
}
public HashSet load(){
HashSet features = new HashSet();
...
return features;
}
}
class LoadContext{
private LoadStrategy loadStrategy_;
public LoadContext(LoadStrategy strategy){
loadStrategy_ = strategy;
}
public HashSet executeLoad(){
return this.loadStrategy_.load();
}
} |
z*******3 发帖数: 13709 | 2 你能不能把缩进改成8个格子的?
4格的看起来好难受
然后你能不能说一下你改了什么地方?
看这么长代码没有高亮之类的
很痛苦 |
Y**G 发帖数: 1089 | 3 standard pattern
create a lexion resolver bean and have it route to 3 different beans that is
capible of doing lexion process
wirling can be configed in a spring context file
【在 z*******3 的大作中提到】 : 你能不能把缩进改成8个格子的? : 4格的看起来好难受 : 然后你能不能说一下你改了什么地方? : 看这么长代码没有高亮之类的 : 很痛苦
|
r******r 发帖数: 700 | 4 看来问对了。 把直观明了的,改成拐弯抹角的了
行数增加了好多倍
【在 z*******3 的大作中提到】 : 你能不能把缩进改成8个格子的? : 4格的看起来好难受 : 然后你能不能说一下你改了什么地方? : 看这么长代码没有高亮之类的 : 很痛苦
|
r******r 发帖数: 700 | 5 敬仰一下
is
【在 Y**G 的大作中提到】 : standard pattern : create a lexion resolver bean and have it route to 3 different beans that is : capible of doing lexion process : wirling can be configed in a spring context file
|
F****n 发帖数: 3271 | 6 你这个最大的问题是没有把提炼出来的 configurable properties
写成declarative格式(XML, properties file, lookup table),
用switch语句反而弄巧成拙。被PM看见了会被K吧
【在 r******r 的大作中提到】 : 看来问对了。 把直观明了的,改成拐弯抹角的了 : 行数增加了好多倍
|
Y**G 发帖数: 1089 | 7 separate data and code is important principle
【在 F****n 的大作中提到】 : 你这个最大的问题是没有把提炼出来的 configurable properties : 写成declarative格式(XML, properties file, lookup table), : 用switch语句反而弄巧成拙。被PM看见了会被K吧
|
r******r 发帖数: 700 | 8 谢谢指教。不过,我这个重点是 exercise Strategy。 原来的一个类,三个方法
Class FileDefinition{
HashSet loadGenericLexicon();
HashSet loadNNPLexicon();
HashSet loadTPOLexicon();
}
变成了一个接口,LoadStrategy, 一个抽象类 LexiconLoad, 三个子类,
GenericLexiconLoad, NNPLexiconLoad and TPOLexiconLoad(), 以及一个 context 类
, LoadContext, 和原来的客户类, FileDefinition.
画了个图,不知对不对。
【在 F****n 的大作中提到】 : 你这个最大的问题是没有把提炼出来的 configurable properties : 写成declarative格式(XML, properties file, lookup table), : 用switch语句反而弄巧成拙。被PM看见了会被K吧
|
z*******3 发帖数: 13709 | 9 //pattern impl
interface Lexicon{
HashSet executeLoad();
}
class GenericLexicon implements Lexicon
class NNPLexicon implements Lexicon
class TPOLexicon implements Lexicon
---------------------------
//to use strategy pattern
private Lexicon getLexiconByFilePath(String path){
if(path.contains("Generic")) return new GenericLexicon();
if(path.contains("NNP")) return new NNPLexicon();
if(path.contains("TPO")) return new TPOLexicon();
}
for(FileDefinition file : FileDefinitions){
Lexicon l = getLexiconByFilePath(path);
HashSet entries = l.executeload();
} |
z*******3 发帖数: 13709 | 10 strategy的好处是可以使得具体的策略dispatch代码非常直观而且简短
不会分散在不同的类中,集中在一个地方管理
然后再用前面几个人说的spring做config进一步优化 |
|
|
F****n 发帖数: 3271 | 11 一个AbstractLoader 三个子类就够了
class AbstractLoader
class GenericLoader
class NNPLoader
class TPOLoader
【在 r******r 的大作中提到】 : 谢谢指教。不过,我这个重点是 exercise Strategy。 原来的一个类,三个方法 : Class FileDefinition{ : HashSet loadGenericLexicon(); : HashSet loadNNPLexicon(); : HashSet loadTPOLexicon(); : } : 变成了一个接口,LoadStrategy, 一个抽象类 LexiconLoad, 三个子类, : GenericLexiconLoad, NNPLexiconLoad and TPOLexiconLoad(), 以及一个 context 类 : , LoadContext, 和原来的客户类, FileDefinition. : 画了个图,不知对不对。
|
r******r 发帖数: 700 | 12 小小点评一下:
Lexicon 最好改名为 LexiconLoad or LoadLexicon. Interface 最好用具有动词意义
的动词,名称或形容词。Lexicon 给人的直观印象就是一个类名. 不过,Java API 里
面也有名词的 interface, 比如, Collection, 不过,那是确实没有更好的选择。
当然,如果确实有三个子类,GenericLexicon, NNPLexicon, TPOLexicon, load() 只
是其行为的一部分,那这样也可以。不过,这就不是 Strategy 了。就是普通的类实现
接口
看你的客户类怎么使用的,都是直接用子类,都没有用到公共的接口方法。不过,也许
多数人也就这么用,这也是为什么严格使用 pattern 的并不多,出了 singleton,
factory 比较常见的了。
所以,我也觉得自己这里是多此一举!
【在 z*******3 的大作中提到】 : //pattern impl : interface Lexicon{ : HashSet executeLoad(); : } : class GenericLexicon implements Lexicon : class NNPLexicon implements Lexicon : class TPOLexicon implements Lexicon : --------------------------- : //to use strategy pattern : private Lexicon getLexiconByFilePath(String path){
|
r******r 发帖数: 700 | 13 你这个跟 Strategy 就差的更远啦。连 interface 都没有。不过,简洁或许更好。
看看标准的 Strategy 模型。如图
【在 F****n 的大作中提到】 : 一个AbstractLoader 三个子类就够了 : class AbstractLoader : class GenericLoader : class NNPLoader : class TPOLoader
|
z*******3 发帖数: 13709 | 14 interface自然是用名词好
方法才用动词
srategy本身的实现就是用一个接口搞定
context方法其实是一个使用者,可以自由定义,一般是component
这是wikipedia上的strategy实现,也就是一个接口了事
interface Strategy {
int execute(int a, int b);
}
你把strategy模式给想复杂了
gof模式的实现普遍都很简单
【在 r******r 的大作中提到】 : 小小点评一下: : Lexicon 最好改名为 LexiconLoad or LoadLexicon. Interface 最好用具有动词意义 : 的动词,名称或形容词。Lexicon 给人的直观印象就是一个类名. 不过,Java API 里 : 面也有名词的 interface, 比如, Collection, 不过,那是确实没有更好的选择。 : 当然,如果确实有三个子类,GenericLexicon, NNPLexicon, TPOLexicon, load() 只 : 是其行为的一部分,那这样也可以。不过,这就不是 Strategy 了。就是普通的类实现 : 接口 : 看你的客户类怎么使用的,都是直接用子类,都没有用到公共的接口方法。不过,也许 : 多数人也就这么用,这也是为什么严格使用 pattern 的并不多,出了 singleton, : factory 比较常见的了。
|
F****n 发帖数: 3271 | 15 别读死书,这个就是Strategy,
AbstractLoader == Strategy,
用AbstractClass可以share三个Loader都可能用到的代码
containment class = Context
之所以书上专门写个Context类,是为了说明会有公用到一些外部的Info(所以叫
Context)
实际应用中领会就可,没必要非搞个多余的类
这个属于很常见的技巧,精髓其实就是把一个Function变成可configure的,
但这个东西只有实际写过很多Code的人体会得到,不留神容易弄巧成拙
【在 r******r 的大作中提到】 : 你这个跟 Strategy 就差的更远啦。连 interface 都没有。不过,简洁或许更好。 : 看看标准的 Strategy 模型。如图
|
z*******3 发帖数: 13709 | 16 EJB CONTAINER就有必要用到多余的类
她这个太简单用不到而已,CONTEXT还是很好的类
至少在EJB时候常用到这个
另外这个CONFIG FUNCTION,也要看是什么类
她这个用CREATIONAL模式来做,FACTORY之类的
如果是生产中,这种ENTITY要用HIBERNATE等来做
如果是你说的这种,STRATEGY的CONFIG,其实是EJB-JAR.XML
【在 F****n 的大作中提到】 : 别读死书,这个就是Strategy, : AbstractLoader == Strategy, : 用AbstractClass可以share三个Loader都可能用到的代码 : containment class = Context : 之所以书上专门写个Context类,是为了说明会有公用到一些外部的Info(所以叫 : Context) : 实际应用中领会就可,没必要非搞个多余的类 : 这个属于很常见的技巧,精髓其实就是把一个Function变成可configure的, : 但这个东西只有实际写过很多Code的人体会得到,不留神容易弄巧成拙
|
z*******3 发帖数: 13709 | 17 我一般不直接使用子类,你这里需要建造了我才去直接使用子类
其实我操作的都是接口本身
要是我进一步修改的话
第一个改的是
HashSet
->
Set
第二个要改的话
我可能会把private getLexiconByFilePath
给封装起来,变成一个独立的类
如果有spring我就inject
如果没有,我就把这个方法static
如果要讲究设计模式的话,我会给这个起名
LexiconFactory.buildLexiconByFilePath(String);
【在 r******r 的大作中提到】 : 小小点评一下: : Lexicon 最好改名为 LexiconLoad or LoadLexicon. Interface 最好用具有动词意义 : 的动词,名称或形容词。Lexicon 给人的直观印象就是一个类名. 不过,Java API 里 : 面也有名词的 interface, 比如, Collection, 不过,那是确实没有更好的选择。 : 当然,如果确实有三个子类,GenericLexicon, NNPLexicon, TPOLexicon, load() 只 : 是其行为的一部分,那这样也可以。不过,这就不是 Strategy 了。就是普通的类实现 : 接口 : 看你的客户类怎么使用的,都是直接用子类,都没有用到公共的接口方法。不过,也许 : 多数人也就这么用,这也是为什么严格使用 pattern 的并不多,出了 singleton, : factory 比较常见的了。
|
z*******3 发帖数: 13709 | 18 java里面的接口基本上都是名词
List
Set
AppletStub
Registry
还有一些是形容词
Comparable
Serializable
Remote
动词貌似还真没有用来做接口名的
多数时候都是方法名
【在 r******r 的大作中提到】 : 小小点评一下: : Lexicon 最好改名为 LexiconLoad or LoadLexicon. Interface 最好用具有动词意义 : 的动词,名称或形容词。Lexicon 给人的直观印象就是一个类名. 不过,Java API 里 : 面也有名词的 interface, 比如, Collection, 不过,那是确实没有更好的选择。 : 当然,如果确实有三个子类,GenericLexicon, NNPLexicon, TPOLexicon, load() 只 : 是其行为的一部分,那这样也可以。不过,这就不是 Strategy 了。就是普通的类实现 : 接口 : 看你的客户类怎么使用的,都是直接用子类,都没有用到公共的接口方法。不过,也许 : 多数人也就这么用,这也是为什么严格使用 pattern 的并不多,出了 singleton, : factory 比较常见的了。
|