美文网首页
Prototype Pattern in Java

Prototype Pattern in Java

作者: Lance_Xu | 来源:发表于2019-04-25 15:10 被阅读0次

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式是实现了一个原型接口(java.lang.Cloneable),该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

原型模式组成

原型(Prototype):实际对象的原型(Movie、Album、Show);

原型注册缓存(Prototype Registry):用于内存中缓存具体的原型对象(PrototypeFactory#protoTypes);

客户端:负责从注册表中获取原型对象。

案例实践

image.png

自定义一个接口类型,继承Cloneable接口,作为原型模式的接口类型。

package com.iblog.pattern.prototype;

/**
 * ProtoType pattern interface declaration.
 */
public interface ProtoTypeCapable extends Cloneable {
    ProtoTypeCapable clone() throws CloneNotSupportedException;
}

假设Movie、Album、Show对象的创建非常复杂,我们通过原型模式来覆盖其对象创建。

package com.iblog.pattern.prototype;

public class Movie implements ProtoTypeCapable {
    private String name;

    public ProtoTypeCapable clone() throws CloneNotSupportedException {
        // clone a Movie object in this.
        return (Movie) super.clone();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "movie => [name:" + name + "]";
    }
}
package com.iblog.pattern.prototype;

public class Album implements ProtoTypeCapable {
    private String name;

    @Override
    public ProtoTypeCapable clone() throws CloneNotSupportedException {
        return (Album) super.clone();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "album => [name:" + name + "]";
    }
}
package com.iblog.pattern.prototype;

public class Show implements ProtoTypeCapable {
    private String name;

    @Override
    public ProtoTypeCapable clone() throws CloneNotSupportedException {
        return (Show) super.clone();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Show => [name:" + name + "]";
    }
}

在案例中,我们将原型对象注册地址与原型客户端都封装在一个工厂操作类中。

package com.iblog.pattern.prototype;

import java.util.HashMap;
import java.util.Map;

public class ProtoTypeFactory {
    public static class ModelType {
        public static final String MOVIE = "Movie";
        public static final String ALBUM = "Album";
        public static final String SHOW = "Show";
    }

    private static Map<String, ProtoTypeCapable> protoTypes = new HashMap<>();

    static {
        protoTypes.put(ModelType.MOVIE, new Movie());
        protoTypes.put(ModelType.ALBUM, new Album());
        protoTypes.put(ModelType.SHOW, new Show());
    }

    public static ProtoTypeCapable getInstance(final String type) throws CloneNotSupportedException {
        return protoTypes.get(type).clone();
    }
}

这样在Java中可以通过在ProtoTypeFactory#getInstance(type)方法很方便克隆一个目标对象。

总结

原型模式属于创建型模式的一种,但是在我们实际应用中场景并不广泛,只有在对象创建十分复杂的情景中才考虑原型模式;此外需要注意原型模式在克隆对象时候对于其中的属性字段的拷贝。

github: pattern-example

相关文章

网友评论

      本文标题:Prototype Pattern in Java

      本文链接:https://www.haomeiwen.com/subject/rhlzgqtx.html