前言: 清晰性和简介性是最为重要的
一个模块的使用者永远也不应该被模块的行为所迷惑(那样就不清晰了),模块要尽可能的小,但又不能太小【术语模块(module):是指任何可重用的软件组件,从单个方法到包含多个包的复杂系统都可以是一个模块】。代码应该被重用,而不是拷贝,模块之间的相依性应该尽可能降低到最小,错误应该尽早被检测出来,理想的情况下是在编译的时刻。
NO.1 考虑用静态工厂方法代替构造函数
静态工厂方法好处:
①构造函数有命名的限制,而静态方法有自己的名字,更加易于理解。
②静态工厂方法在每次调用的时候不要求创建一个新的对象。这种做法对于一个要频繁创建相同对象的程序来说,可以极大的提高性能。它使得一个类可以保证是一个singleton;他使非可变类可以保证“不会有两个相等的实例存在”。
③静态工厂方法在选择返回类型时有更大的灵活性。使用静态工厂方法,可以通过调用方法时使用不同的参数创建不同类的实例,还可以创建非公有类的对象,这就封装了类的实现细节。
静态工厂方法坏处:
①如果一个类是通过静态工厂方法来取得实例的,并且该类的构造函数都不是公有的或者保护的,那该类就不可能有子类(被继承),子类的构造函数需要首先调用父类的构造函数,因为父类的构造函数是private的,所以即使我们假设继承成功的话,那么子类也根本没有权限去调用父类的私有构造函数,所以是无法被继承的 。
②毕竟通过构造函数创建实例还是SUN公司所提倡的,静态工厂方法跟其他的静态方法区别不大,这样创建的实例谁又知道这个静态方法是创建实例呢?弥补的办法就是:静态工厂方法名字使用valueOf或者getInstance.
总结:静态工厂方法和公有的构造函数都有他们各自的用途,我们要理解他们各自的长处,避免一上来就用构造函数,通常静态工厂更加合适。如果没有其他因素强烈的影响我们的选择,最好还是简单的选择构造函数,毕竟他是语言提供的规范。
NO.2 试用私有构造函数强化singleton属性
实现singleton的方法有两种:
方法一:公有的静态成员是一个final域,成员的声明很清楚的表达了这个类是一个singleton。
- public class Elvis {
- public static final Elvis INSTANCE = new Elvis();
- private Elvis() { }
- public void leaveTheBuilding() {
- System.out.println("Who a baby, I'm outta here!");
- }
- // This code would normally appear outside the class!
- public static void main(String[] args) {
- Elvis elvis = Elvis.INSTANCE;
- elvis.leaveTheBuilding();
- }
- }
方法二:提供一个公有的静态方法,而不是公有的静态final域。该方式提供了更大的灵活性,在不改变API的前提下,可以把该类改成singleton或者非singleton的。
- public class Elvis {
- private static final Elvis INSTANCE = new Elvis();
- private Elvis() { }
- public static Elvis getInstance() { return INSTANCE; }
- public void leaveTheBuilding() {
- System.out.println("Who a baby, I'm outta here!");
- }
- // This code would normally appear outside the class!
- public static void main(String[] args) {
- Elvis elvis = Elvis.getInstance();
- elvis.leaveTheBuilding();
- }
- }
NO.3 通过私有的构造函数强化不可实例化的能力