您的位置:首页 > 编程语言 > Java开发

java 设计模式---创建对象

2017-03-24 09:53 357 查看
静态工厂,JavaBeans 模式,builder 模式,单例

1、静态工厂方法

入口Boolean创建对象,原码如下:

    public static Boolean valueOf(String s) {

        return parseBoolean(s) ? TRUE : FALSE;

    }

优势:

1)有方法名称,如果有多个构造器,可能不知道要调用那一个构造器,代码更容易阅读。

2)不必有每次调用时都创建一个新的对象,使用不可变类(如String)提供单例,可以进行重复利用(注意是不可变对象)

3)可以返回类型的任何子类型的对象。这样选择返回对象的类型就有了更大的灵活性。

这种灵活性应用:

i)如 Collections.emptyList() 是通过静态工厂方法返回一个 Collections 的一个不可实例化的内部私有类EmptyList。

如上例:这样会使API 变变得很简洁。这种技术适用于“接口框架”,接口为静态工厂方法提供了自然返回类型。返回的对象不仅可以是非公有的,只要是已声明返回类型子类型都是允许的,这样就提高了可维护性和性能,每次改版实现修改后,不影响调用。

ii)静态工厂返回的对象所属的类,在编写包含该静态工厂方法时可以不必存在。这种灵活的静态工厂方法构成了“服务提供者框架”(多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把他们从多个实现中解耦出来。如JDBC)的基础。

4)在创建参数化类型实例 的时候,代码变得简洁(jdk7 已经实现)。

如:Map<String,String> map = new HashMap<>(); 

这种写法调用了静态工厂方法:
public static <K, V> HashMap<K, V> newInstance(){
   return new HashMap<K, V>();

    }

缺点:

1)如果没有公用的构造器,就不能被子类化(被继承)。

2)和其它静态方法没有区别,在API中没有像构造器那样被标识出来。

3)不好扩展多个可选的参数

2、JavaBeans 模式

多个构造器参数时可以使用构造重叠方式(多个构造器,参数不同)来创建对象,但是这样代码不简洁,使用者不知道要用那一个构造器。可以使用JavaBeans 模式,调用一个无参构造器创建对象,然后调用setter 方法设置参数,创建实例容易,代码也容易阅读。

例如有一个类A,创建A对象

A a = new A();

a.set...();

a.set...();

a.set...();

JavaBeans 有一个严重缺点:构造的过程被分到了几个调用中,在构造过程中JavaBean 可能处于不一致的状态。试图使用处于不一致状态的对象,会失败,也会不好调试。对象是可变的,就会带来线程安全问题。

3、builder 模式

拥有构造重叠那样的安全性,也有JavaBeans 模式的好的可读性。

示例:

public class User {

    private String name;

    private int age;

    private String email;

    public static class Builder{

        private String name;

        private int age;

        private String email;

        public Builder(String name){

            this.name = name;

        }

        public Builder age(int age){

            this.age = age;

            return this;

        }

        public Builder email(String email){

            this.email = email;

            return this;

        }

        public User builder(){

            return new User(this);

        }

    }

    private User(Builder builder){

        this.name  =  builder.name;

        this.age = builder.age;

        this.email = builder.email;

    }

    public static void main(String[] args) {

        //创建User 对象

        User u = new User.Builder("name").age(10).email("email").builder();

    }

}

注意:对参数加强约束要在将参数从builder copy到对象中之后(User 私有构造方法中),而不是在builder() 方法中。

可以使用builder 这样方法就可以创建一个或者多个对象,builder可以在创建对象期间进行调整,也可以根据不同的对象而改变。

可以把builder 对象传递给方法,此方法可以创建一个或者多个对象,即:抽象工厂。

4、单例

1)1.5之前有两种方法实现,都是把构造器私有化,并导出公有的静态成员。如:

private static finale A a = new A();

public static A getInstance(){
return a;

}

private A(){}

如果对象A 是可序列化的,只声明是“implements Serializable ” 是不行的,那么就不再是一个Singleton。必须声明所有的实例域都是瞬时(transient,不能被序列化)的并且要提供一个 readResolve 方法:

private A readResolve(){
return a

}

2)1.5 之后可以编写包含单个元素的枚举,好处是jvm保证了对象被创建一次,并且提供了可序列化。代码:

public class SingletonEnum {

    private SingletonEnum(){}

    public static SingletonEnum getInstance(){

        return Singleton.INSTANCE.getInstance();

    }

    private static enum Singleton{

        INSTANCE;

        private SingletonEnum singleton;

        //JVM会保证此方法绝对只调用一次

        private Singleton(){

            singleton = new SingletonEnum();

        }

        public SingletonEnum getInstance(){

            return singleton;

        }

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 设计模式