我想要实现的目标,比如我们有一个对象jacket
,而且我们知道只有一个人可以在代码中使用夹克:
Jacket jacket = createJacket();
bob.buy(jacket);
bob.useJacket(); // here bob has a reference to jacket
// now let's say bob is selling his jacket
bob.sellJacketTo(alice);
// now how to prevent bob from saving reference to
// jacket instance, because now it is alice jacket and
// only alice can use it
我现在的解决方案是创建一个“代理”来包装一个“物理”夹克:
public class Jacket implements Outerwear {
private String color;
private int size;
Jacket(String color, int size) {
this.color = color;
this.size = size;
}
@Override
public void use() {
System.out.printf("%s jacket in size %d is warming you right now ;)", color, size);
}
// ...
}
public class JacketOwnership implements Outerwear {
private Jacket jacket;
private JacketOwnership(Jacket jacket) {
this.jacket = jacket;
}
public boolean isValid() {
return (jacket != null);
}
@Override
public void use() {
if (!isValid())
throw new IllegalStateException("You no longer own the jacket!");
jacket.use();
}
public JacketOwnership takePossession() {
Jacket tmp = this.jacket;
this.jacket = null;
return new JacketOwnership(tmp);
}
public static JacketOwnership createJacket(JacketFactory jacketFactory) {
Jacket jacket = jacketFactory.create();
return new JacketOwnership(jacket);
}
}
以上所有类都在同一个包中,但是它们将在外面使用(换句话说,我们可能会在这里使用私有包的范围):
JacketFactory factory = new JacketFactory(); // crate is package scoped
JacketOwnership jacket = JacketOwnership.createJacket(factory);
jacket.use();
JacketOwnership nowJacketIsMine = jacket.takePossession();
nowJacketIsMine.use();
我觉得这个解决方案有点过于复杂,是否有更简单/更好的方法?
PS。我不需要有防弹解决方案 - 反射可能会破坏它,它只需要从Java语言的角度保存...
答案 0 :(得分:2)
如何将所有这些解耦?
只有你的夹克类,有夹克本身的信息(颜色,大小,等等)。没有做业务逻辑的方法。
那么你的人类,关于人本身的信息(姓名,年龄,等等)。没有做业务逻辑的方法。
然后是你的夹克所有者,你可以根据自己的喜好进行建模。那么你可以拥有夹克的回购(库存),并根据需要设置约束(例如,不允许相同的夹克出现两次)。在最简单的形式,夹克的回购可以包括
HashMap<Jacket, Person>
由于您在实体内部分离了夹克人并删除了业务,因此您可以轻松地获得所有&#34;链接&#34;并且只是作为服务的一部分(在您拥有业务逻辑的地方)将它们作为一个整体添加约束。
答案 1 :(得分:0)
我认为你需要的是关系 所有者(0-1)&lt; ---&gt; (*)夹克。 我的假设是所有者可以拥有零到多个夹克,夹克可以由最多一个所有者拥有。
我建议遵循简单的代码。添加其他复杂性可能会限制对方法的不必要访问(以避免API滥用),例如转移需要作为单一交易,只访问set方法会破坏关系。
Ionic 3
答案 2 :(得分:-1)
以这种方式写出sellJacketTo方法:
package Example;
public class Test2 {
WordCloud cloud;
FrequencyAnalyzer analyzer;
}