重读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]
第一条:考虑用静态工厂方法代替构造函数
好处:
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]
相关文章推荐
- Effective Java -- 遇到多个构造器参数时要考虑用构建器(Builder)
- JAVA内存泄露(Effective java学习)
- Effective Java - 类和接口 - 使类和成员的可访问性最小化(java 访问级别)
- Effective Java中文第四章第22节(个人渣翻)
- Effective Java(用函数对象表示策略、优先使用静态成员类)
- Effective Java(用函数对象表示策略、优先使用静态成员类)
- 《Effective Java(中文第二版)》【PDF】下载
- Effective Java 第三版——5. 使用依赖注入取代硬连接资源
- 《Effective Java》阅读笔记
- Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用
- Effective Java 3rd 条目17 最小化可变性
- Effective Java 第三版——30. 优先使用泛型方法
- 《Thinking In Java》 VS 《Effective Java》 VS 《深入理解Java虚拟机》
- 《Effective Java》——学习笔记(创建和销毁对象)
- 《Effective Java(中文第二版)》【PDF】
- Effective Java 3rd Edition(读书笔记+翻译)系列(第二章)
- effective java 第10条
- 《Effective Java》谨慎的覆盖clone()方法
- Effective Java 第三版——46. 优先考虑流中无副作用的函数
- 《Effective Java》读书笔记