身份地图模式Java中的真实世界示例

时间:2018-04-14 13:05:42

标签: java design-patterns

我正努力在Java中获得Identity Map Pattern现实生活(行业实现)示例。

我一直在研究企业应用程序架构模式的身份图模式。

我理解这种模式的用法和适用性,但我没有找到任何真实的例子。

您能提供这种设计模式的任何实际例子吗?

2 个答案:

答案 0 :(得分:1)

JPA持久化上下文是身份映射模式的一个很好的例子。 在JPA中,实体身份在事务内和实体管理器内维护。例如:

Employee employee1 = entityManager.find(Employee.class, 123);
Employee employee2 = entityManager.find(Employee.class, 123);
assert (employee1 == employee2);

Assert表达式将返回true。第二个调用将从持久化上下文中获取实体,而不查询数据库。

来自EntityManager javadoc

  

持久性上下文是一组实体实例,其中对于任何持久性实体标识,都存在唯一的实体实例。在持久性上下文中,管理实体实例及其生命周期。 EntityManager API用于创建和删除持久性实体实例,按主键查找实体以及查询实体。

另请参阅JPA wikibook对象标识说明。

答案 1 :(得分:0)

对于初学者:here是关于身份地图模式的真实例子的一篇很好的文章。

另一个重要的待遇:here是上面提到的企业应用程序架构模式(Martin Fowler!)的链接。

至于这里的一个实际例子:我认为这个模式(以及我读过的其他几个来源)在精神上与延迟初始化类似。

基本和反复出现的概念是:您有一个重量级对象,您希望检索它(通常是一个数据库实体,但没有理由仅限于DB),并且您使用地图来存储此对象的新实例(如果它尚不存在于Map中。

所以记住这一点(这很快,很脏,没有适当的泛型等等):

import java.util.*;
import java.util.stream.*;

interface HeavyWeightInterface {
    public String myToString();
}

class ConcreteHeavyWeight implements HeavyWeightInterface {
    private static final int NUMBER_OF_OBJECTS = 100000;
    // non DB heavy class
    private String base;
    private List<String> dummyObjects;

    public ConcreteHeavyWeight(String keyBase) {
        this.base = keyBase;
        this.dummyObjects = new ArrayList<>();
        IntStream.range(0, NUMBER_OF_OBJECTS).forEach(
           nbr -> { 
               dummyObjects.add(base + " : " + nbr);
           });
    }

    public String myToString() {
        return "My base is : " + base + " with an internal DS of " + dummyObjects.size() + " entities";
    }
}

interface HeavyWeightFactory {
    public HeavyWeightInterface build(String key);
}

class ConcreteHeavyWeightFactory implements HeavyWeightFactory{
    public HeavyWeightInterface build(String key) {
        return new ConcreteHeavyWeight(key);
    }
}

class IdentityMap {

    private Map<String,HeavyWeightInterface> internalMap;
    private HeavyWeightFactory hwfactory;
    public IdentityMap(HeavyWeightFactory hwfactory) {
        this.internalMap = new HashMap<>();
        this.hwfactory = hwfactory;
    }
    public HeavyWeightInterface retreive(String key) {
        if(!internalMap.containsKey(key)) {
            internalMap.put(key,hwfactory.build(key));
        }
        return internalMap.get(key);
    }

}

public class MyClass {
    public static void main(String[] args){
        IdentityMap im = new IdentityMap(new ConcreteHeavyWeightFactory());
        HeavyWeightInterface hw0 = im.retreive("Test0");
        im.retreive("Test1");
        im.retreive("Test2");
        im.retreive("Test3");
        HeavyWeightInterface hw1 = im.retreive("Test0");
        System.out.println("First call with Test0 key = " + hw0 + ", Second call with Test0 key = " + hw1);
        System.out.println(hw1.myToString());
    }
}

输出是:

First call with Test0 key = ConcreteHeavyWeight@224aed64, Second call with Test0 key = ConcreteHeavyWeight@224aed64
My base is : Test0 with an internal DS of 100000 entities