您的位置:首页 > Web前端

重读Effective Java(一)

2008-01-17 09:49 197 查看
这学期的任务做的差不多了,空出点时间,鉴于好长时间没有编程了,于是翻出《Effective Java》重读,顺便实现点里头的内容加深理解。恩,好书~~

第一条:考虑用静态工厂方法代替构造函数

好处:
1. 静态工厂方法有名字,更易于理解而且不易用错。
2. 每次被调用的时候不是非得创建一个新对象,而且可以根据需要创建指定数量的对象。(比如singleton)
3. 与构造函数不同,它们可以返回一个原返回类型的子类。同时,返回的类型在编写工厂方法的时候不一定真的存在

下面是书上例子的实现,可以看到MyRectangle类可以通过在编写完静态工厂方法之后再动态配置的方法添加,配置文件名为class.properties,字符串和类型名称的映射。

//Shape.java 基类
package Note01;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class Shape {
public void whoAmI() {
System.out.println("I am Shape.");
}

private static Map implementations = null;

//初始化类的映射表
private static synchronized void initMapIfNecessary() {
if (implementations == null) {
implementations = new HashMap();
}
try {
//加载配置文件
String path = System.getProperty("user.dir");
File file = new File(path + "/Note01/class.properties");
InputStream propFile = new FileInputStream(file);
Properties properties = new Properties();
properties.load(propFile);
Set keys = properties.keySet();
//好像这种写法是5.0之后才支持的吧
for(Object key : keys) {
String strKey = (String)key;
String className = properties.getProperty(strKey);
Class c = Class.forName("Note01." + className);
implementations.put(key, c);
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

//由名字获得类型
public static Shape getInstance(String key) {
initMapIfNecessary();
Class c = (Class)implementations.get(key);
if (c == null) {
return new Shape();
}
try {
return (Shape)c.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
return new Shape();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
return new Shape();
}
}
}

//MyCircle.java
package Note01;

public class MyCircle extends Shape {
public MyCircle() {
super();
}

public void whoAmI() {
System.out.println("I am Circle.");
}
}

//MyTriangle.java
package Note01;

public class MyTriangle extends Shape {

public MyTriangle() {
super();
}

public void whoAmI() {
System.out.println("I am triangle.");
}
}

//最初的class.properties文件,没有MyRectangle类的描述
[align=left]circle=MyCircle[/align]
triangle=MyTriangle

//Test.java
package Note01;

public class Test {
public static void main(String[] args) {
Shape.getInstance("circle").whoAmI();
Shape.getInstance("triangle").whoAmI();
Shape.getInstance("rectangle").whoAmI();
}

}
运行Test.java结果为:
[align=left]I am Circle.[/align]
[align=left]I am triangle.[/align]
I am Shape.

[align=left]在class.properties中增加[/align]
rectangle=MyRectangle
再次运行Test.java结果为:
[align=left]I am Circle.[/align]
[align=left]I am triangle.[/align]
[align=left]I am rectangle.[/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: