最近在看thinking in Java,学到了不少知识,主要的是书里面介绍了不仅语法,而且是java思想,看到了interface的那章,书里第一次提到了与之相关的factory method,于是顺道开始学习。
从MSDN上学到,software design也要注意能让代码时刻变化,假设empire building需要临时在底下再挖一层floor,或者在楼顶加个pool,我们要及时应对,所以要有design pattern,常见的有observer,factory等。
在factory pattern中说,An important facet of system design is the manner in which objects are created,尽管object的model和instance interaction也是如何的重要,但怎么created也很重要。这就是factory所做的改进。
一般的object的创建包括object instantiation (e.g. new, newobj, etc.) and initialization (e.g. constructors) mechanisms,比如一个自行车类产生一个自行车,一个汽车类产生一个汽车,都是explicit association between the creator and created classes,但为了照顾快速change的时代要求,factory的logical 如下:
这个pattern把product的创建从Client那里完全的抽象化了,This indirection enables the client to focus on its discrete role in the application without concerning itself with the details of how the product is created. Thus, as the product implementation changes over time, the client remains unchanged.
比如Client想要一个交通工具,factory里面可以implement汽车自行车三轮车手推车,Client只要保持不变,在factory和product变动即可。
实际操作有两个interface,一个factory一个product,另外需要对应的implementation,physical model如下:
最后上段codes in Java:
interface Currency {
String getSymbol();
}
// Concrete Rupee Class code
class Rupee implements Currency {
@Override
public String getSymbol() {
return "Rs";
}
}
// Concrete SGD class Code
class SGDDollar implements Currency {
@Override
public String getSymbol() {
return "SGD";
}
}
// Concrete US Dollar code
class USDollar implements Currency {
@Override
public String getSymbol() {
return "USD";
}
}
// Factroy Class code
class CurrencyFactory {
public static Currency createCurrency (String country) {
if (country. equalsIgnoreCase ("India")){
return new Rupee();
}else if(country. equalsIgnoreCase ("Singapore")){
return new SGDDollar();
}else if(country. equalsIgnoreCase ("US")){
return new USDollar();
}
throw new IllegalArgumentException("No such currency");
}
}
// Factory client code
public class Factory {
public static void main(String args[]) {
String country = args[0];
Currency rupee = CurrencyFactory.createCurrency(country);
System.out.println(rupee.getSymbol());
}
}