java - 相同配置的多个构造函数应该只创建一个实例

标签 java design-patterns

我定义了几个类: 食物 面包 黄油 食品工厂

如下:

食物.java

public abstract class Food {
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public abstract void eat();

    public Food(String id) {
        this.id = id;

        FoodFactory.getInstance().foodWasConstructed(this);
    }
}

食品工厂.java

public class FoodFactory {
    private Map<String, Food> map = new HashMap<String, Food>();
    private static FoodFactory factory = new FoodFactory();

    private FoodFactory() {
    }

    public static FoodFactory getInstance() {
        return factory;
    }

    public synchronized Food getFood(String id, String type) {
        if(map.get(id) != null) {
            return map.get(id);
        } else {
            if(type.equals("bread")) {
                Food food = new Bread(id);
                map.put(id, food);
                return food;
            } else if(type.equals("butter")) {
                Food food = new Butter(id);
                map.put(id, food);
                return food;
            }
        }
        return null;
    }

    public void foodWasConstructed(Food food) {
        if(!map.containsKey(food.getId()))
            this.map.put(food.getId(), food);
    }
}

面包.java

public class Bread extends Food {
    static int i;
    public Bread(String id) {
        super(id);
        i++;
    }

    public void eat() {
        System.out.println("Eating bread : " + i);
    }
}

黄油.java

public class Butter extends Food {

    public Butter(String id) {
        super(id);
    }

    public void eat() {
        System.out.println("Eating butter");
    }

}

现在我的要求是我不能创建两个具有相同 ID 的 Food 实例。 我尝试运行以下代码:

public class SampleTest {
    public static void main(String[] args) {
        Food food1 = new Bread("1");
        Food food2 = new Bread("1");

        // food2 should return food1 reference. How can I accomplish this.
        // food2 creates entirely new instance. What I want is it should refer to food1 instance.
        // How can i do this. Is there any design flaw?
        FoodFactory.getInstance().getFood("1", "bread").eat();
    }
}

得到如下输出:

Eating bread : 2

我的问题如评论中所述: food2 应该返回 food1 引用。我怎样才能做到这一点。 food2 创建了全新的实例。我想要的是它应该引用 food1 实例。我怎样才能做到这一点。是否存在设计缺陷?

最佳答案

您需要根据变量 id 为 Food 类实现 hashCode()equals() 方法。因此,对于传递给构造函数的每个类似 id,只会创建一个类。由于 Bread 类扩展了 Food,它获得相同的行为并且只为相同的 id 创建一个类。

您可以将Food 类更改为以下

 public abstract class Food {
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public abstract void eat();

    public Food(String id) {
        this.id = id;

        FoodFactory.getInstance().foodWasConstructed(this);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Food other = (Food) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

}

示例测试.java

<pre><code>public class SampleTest {
    public static void main(String[] args) {
        Food food1 = new Bread("1");
        Food food2 = new Bread("1");

        System.out.println(food1.hashCode());

        System.out.println(food2.hashCode());
        System.out.println(food1.equals(food2));

        // food2 should return food1 reference. How can I accomplish this.
        // food2 creates entirely new instance. What I want is it should refer
        // to food1 instance.
        // How can i do this. Is there any design flaw?
        FoodFactory.getInstance().getFood("1", "bread").eat();
    }
}</pre></code>

输出

  80
    80
    true
    Eating bread : 2

关于java - 相同配置的多个构造函数应该只创建一个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31316707/

相关文章:

java - Spring中RestTemplate中的unicode转换

java - 必须有更好的方法来编码这个 :(

c# - 在 Entity framework6 Repository 模式中限制用户只能访问他/她的实体

java - 我应该使用哪种模式来根据命令名称运行某些操作?

c# - 用于返回可能并不总是完全填充的数据结构对象的设计模式?

javascript:私有(private)成员和只读属性

java - 带 ListView 的 Viewpager

java - 如何在 Gatling 脚本中添加 Status = KO?

java - java swing中的setvisible方法挂起系统

java - 是否有可能检测到输出的去向 - 终端或管道/文件?