Architecture 坚持树上有苹果这一事实

Architecture 坚持树上有苹果这一事实,architecture,oop,Architecture,Oop,如果我有一棵树上有苹果,我应该如何模拟苹果是树上有苹果的事实呢。考虑有3个数据库表:树、苹果、树苹果。p> 在我看来,会有一个AppleCorator类,这样Tree就可以有多个AppleCorator,并为每个AppleCorator调用->save(),从而将关联写入Tree\u Apple。苹果公司不知道它是树公司的 从tree类中引用tree_apples表而不是获取所有树的ID似乎是错误的,因为tree类正在为它拥有的每种类型的对象引用一个表(并且需要存储它拥有一个表的事实)。甚至获取

如果我有一棵树上有苹果,我应该如何模拟苹果是树上有苹果的事实呢。考虑有3个数据库表:树、苹果、树苹果。p> 在我看来,会有一个AppleCorator类,这样Tree就可以有多个AppleCorator,并为每个AppleCorator调用->save(),从而将关联写入Tree\u Apple。苹果公司不知道它是树公司的

从tree类中引用tree_apples表而不是获取所有树的ID似乎是错误的,因为tree类正在为它拥有的每种类型的对象引用一个表(并且需要存储它拥有一个表的事实)。甚至获取ID也可以被卸载到迭代器之类的东西中


当应用程序需要存储一个对象拥有N个其他对象的事实时,该如何处理?(在这种情况下,我的类需要存储其他5种类型对象的关联)。

将苹果放在树上的列表或集合中


如果您使用的是O/R映射器,那么可以使用tree_appes表作为联接表来注释或指示列表是一对多对苹果。可以使用苹果列表(在树中)的级联保存来保存连接。

我可以使用另一个结构来完成此操作:

public interface ITreeSaver {

  public void save(Tree t);
  public Tree load(String treeId);

}
然后,您可以以任何方式实现这个(基本DAO)。使用Hibernate,可以对MySQL驱动程序、XStream或其他任何对象进行原始调用

树、苹果或任何其他模型对象都不需要知道/理解它是如何保存或加载的

要通过直接SQL调用实现这一点,需要采取以下措施:

public class SQLTreeSaver implements ITreeSaver {

    public void save(Tree t) {

        String id = t.getId();
        if(id == null || id.isEmpty()) {
            id = /*generate Id here*/;
        }

        SQL.execute("delete from TREES where id="+id);
        SQL.execute("insert into TREES values (id, prop1, prop2) ("+id+",'"+t.getProp2()+"','"+t.getProp3()+"'");

        SQL.execute("delete from APPLES where treeId="+id);

        for(Apple a : t.getApples()) {
            String appleId = a.getId();
            if(appleId == null || appleId.isEmpty()) {
                appleId = /*generate Id here*/;
            }           
            SQL.execute("insert into APPLES values (id, tree, prop1) ("+appleId+","+id+",'"+a.getProp1()+"'");
        }

    }

    public Tree load(String id) {

        Tree t = new Tree();

        if(id == null || id.isEmpty()) return t;

        ResultSet treeSet = SQL.execute("select top 1 * from TREES where id="+id);

        while(treeSet.hasNext()) {
            t.setId(treeSet.getString("id"));
            t.setProp1(treeSet.getString("prop1"));
            t.setProp2(treeSet.getString("prop2"));

            ResultSet appleSet = SQL.execute("select * from APPLES where tree="+id);

            ArrayList<Apple> appleList = new ArrayList<Apple>();

            while(appleSet.hasNext()) {
                Apple a = new Apple();
                a.setId(appleSet.getString("id");
                /* omit the following if your apples have no idea who they belong to */
                a.setTree(id);
                a.setProp1(appleSet.getString("prop1"));

                appleList.add(a);
            }

            if(appleList.size() > 0) {
                treeSet.setApples(appleList);
            }

        }

        return t;
    }

}

现在。。。你知道我要干什么。您使用某种方法来选择要使用的ITreeSaver实现,然后您就有了一些灵活性或适应性。如果您的客户端使用的数据库不受Hibernate支持,该怎么办?如果他们使用平面文件呢?我觉得只要再多努力一点,就可以很好地分离关注点,并能够轻松响应和更改以适应系统上的新情况或需求。

树\u只有当一个苹果可以属于多棵树时,苹果才有效。(m:n关系)

这可能只是一个不好的比喻,但如果我们坚持使用“一棵树有许多苹果”,在关系数据库中,苹果通常存储对它来自的树的引用

Tree
  TreeId
  TreeName

Apple
  AppleId
  IsRotten
  TreeId (foreign key)

对于内存中的数据模型(即面向对象),您可能有一个从苹果到树的返回指针,也可能没有。i、 你们通常有树。苹果,其中苹果是苹果对象的某种集合,但你们不经常有苹果树

我不太清楚为什么我会被否决。我指出你不会用装饰图案来做这个。您不希望将保存/加载的责任添加到苹果或树,而是完全添加到其他对象。很明显,提出问题的人了解sql模式和中间联接表。正如罗伯特·保尔森(Robert Paulson)指出的那样:这看起来像是一种m:n关系。(回应他:这可能只是一个糟糕的比喻。)无论如何,我已经编辑了我的回答,使之更为恰当。我认为没有ORM,它不会有太大的变化,这可能甚至不是一件好事。保存对象时,将在持久化树后持久化列表中的所有苹果。我认为所有语言在这一点上都有某种形式的ORM——它们确实更容易。是的,但这里的全部问题是,将列表中的对象持久化到表树的代码放在哪里?持久化逻辑应该放在数据访问对象(DAO)中类-这个类上有一个与DAO.storeTree(tree)类似的方法,它具有树和子的逻辑。我想我问的问题是错误的。为了简单起见,假设我们使用了直接SQL。树中是否存在“updatetree\u apples”查询,或其他类,如“tree apples”?若它存在于树中,那个么让树对这么多其他表进行更新似乎有点奇怪。如果它被卸载到另一个类,比如TreeApples,那么这个新类是从Tree派生的还是包含Tree?我的意思是“这个新类是从Apple派生的还是包含一个Apple”。类TreeApples扩展了Apple实现了可列表的{private}uid;公共构造(treeId,appleId);//还将调用父构造函数来加载Apple public save();public delete();}或类TreeApples实现了可列表的{private}uid;private Apple}Apple;公共构造(treeId,appleId);//将把一个苹果装入这个容器对象public save();public delete();}没错,这不是最好的比喻。我要问的问题是,你把保存苹果的代码放在哪里?树必须表为Tree\u apples吗?@Dewayne你是在寻找m:n,因为Tree-Apple关系不是m:n,不需要TreeApple-join表,这就是我忽略它的原因(因此,我对所选择的苹果树比喻的恰当性发表了评论,因为我无法判断您是否需要连接表方面的帮助,或者您是否需要关系建模方面的帮助)但是,我可以推荐《企业架构模式》(Fowler)一书。关于加载和保存数据的主题有很多内容(例如数据映射器)
Tree
  TreeId
  TreeName

Apple
  AppleId
  IsRotten
  TreeId (foreign key)