我想要实现的是,假设我们有一个对象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语言的角度来保存它……
发布于 2017-08-09 05:35:48
把所有这些都解耦出来怎么样?
只要有你的夹克类,关于夹克本身的信息(颜色,尺寸,无论什么)。没有执行业务逻辑的方法。
然后是person类,包含关于person本身的信息(姓名、年龄等)。没有执行业务逻辑的方法。
然后是你的jacketowner实体,你可以根据自己的喜好来建模。然后,您只需拥有一个夹克所有者的repo (库存),并具有所需的约束(例如,不允许同一夹克出现两次)。在最简单的形式中,夹克所有者的回购可以包含在
HashMap<Jacket, Person>由于您解耦了jacket-person并删除了实体内部的业务,因此您可以轻松地拥有所有“链接”的代码库,并只需将约束作为服务的一部分添加到整个服务中(其中您有自己的业务逻辑)。
发布于 2017-08-09 12:53:36
我认为你需要的是关系所有者(0-1) <->(*)夹克。我的假设是,所有者可以有零到多个夹克,夹克可以由最多一个所有者拥有。
我建议使用以下简单的代码。添加其他复杂性可能会限制对方法的不必要访问(以避免API误用),例如,传输需要作为单个事务,并且只访问set方法将破坏关系。
public class Jacket {
private Owner owner;
private int id;
public Jacket(int id) {
this.id = id;
}
public Owner getOwner() {
return owner;
}
public void setOwner(Owner owner) {
this.owner = owner;
}
}
public class Owner {
private String name;
private Set<Jacket> jackets = new HashSet<>();;
public Owner(String name) {
this.name = name;
}
public void sellJacketTo(Owner buyer) {
if (jackets.size() > 0) {
Jacket jacketForSell = new ArrayList<Jacket>(jackets).get(0);
jackets.remove(jacketForSell);
jacketForSell.setOwner(null);
buyer.add(jacketForSell);
}
}
public void add(Jacket jacket) {
if (jacket.getOwner() == null) {
this.jackets.add(jacket);
jacket.setOwner(this);
}
}
}
public static void main(String[] args) {
Jacket j1 = new Jacket(1);
Jacket j2 = new Jacket(2);
Jacket j3 = new Jacket(3);
Owner o1 = new Owner("O1");
Owner o2 = new Owner("O2");
o1.add(j1);
o1.add(j2);
o2.add(j1);
o2.add(j3);
o1.sellJacketTo(o2);
System.out.println(o1);
System.out.println(o2);
}发布于 2017-08-09 10:16:24
只需按如下方式编写sellJacketTo方法:
void sellJacketTo(Person p){
p.jacket = this.jacket;
this.jacket = null;
}https://stackoverflow.com/questions/45577053
复制相似问题