动态构造合成对象 [英] Dynamically constructing composition object

查看:49
本文介绍了动态构造合成对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个课程复习表,该复习表由不同课程的多个对象组成.一个学生应该每月复习他所报名的课程.数学,科学,历史记录是单独的表格,但我将外键存储在其中评论"表,以便将课程的每个评论与各自的表相关联.

I have a review table for courses which is made up of multiple objects for different courses.A student should review the courses he is enrolled in every month.The Math,Science,History are tables by themselves but I store foreign keys in the Review table so that each review for the courses is associated with the respective table.

注意:一个学生只能参加两门课程

NOTE:a student can only be enrolled in two courses

@Entity
class Review{
//multiple time fields here here

@OneToOne(cascade=CascadeType.ALL,optional=true)
@JoinColumn(name="math_review_id")
Math m;

@OneToOne(cascade=CascadeType.ALL,optional=true)
@JoinColumn(name="science_review_id")
Science s;

@OneToOne(cascade=CascadeType.ALL,optional=true)
@JoinColumn(name="history_review_id")           
History h;

}

超级类

 @MappedSuperclass
 class Course {
   @Id
   @GeneratedValue(strategy=GenerationType.IDENTITY)
   @Column(name="id")
   int id;

   @ManyToOne(fetch = FetchType.LAZY, 
        cascade = { CascadeType.DETACH,
                    CascadeType.MERGE, 
                    CascadeType.PERSIST,
                    CascadeType.REFRESH },
                    )
   @JoinColumn(name = "student_id")
   private Student student;
 }

子类历史记录

@Entity
 class History extends Course{
//fields specific to history course
 }

子类数学

@Entity
class Math extends Course{
//fields specific to math course
}

学生班

@Entity
class Student{
//fields name,id,...
@OneToMany(mappedBy = "student", 
           cascade = CascadeType.ALL,
           fetch = FetchType.LAZY)
private List<Review> reviewsList;
}

我检查学生注册的课程,并相应地初始化Math,Science,History.我将Review对象传递给我的reviews.jsp并使用hibernate保存返回的@ModelAttribute.我不初始化学生不是的课程我认为未初始化的对象将不会保存,但是即使未初始化,hibernate也会生成空条目(我认为是因为它们映射到表并且在持久类内部).我需要帮助如何仅根据学生所注册的课程来动态构建Review对象.我当前的设计可能会有流程,任何更好的设计建议都将受到赞赏(我对Java和Hibernate的经验很少)

I check what courses the student is enrolled in and initialize the Math,Science,History accordingly.I pass a Review object to my reviews.jsp and save the returned @ModelAttribute using hibernate.I dont initialize the courses the student is not enrolled in.I thought uninitialized objects wont be saved but hibernate makes null entries even if not initialized ( I think because they are mapped to a table and are inside a persistent class). I need help how to dynamically construct Review object just with the courses the student is enrolled in.My current design might have flows,any better design suggestions are much appreciated(I have minimal experience in Java and hibernate)

推荐答案

作为建议,我认为您应该为每门课程创建一个课程感到厌倦. Course类的成员类型可能是不够的,该成员可以是数学,科学或历史.即使该类型本身也可以是实体:CourseType,您可以为其输入条目,因此在您的代码中将没有MathScienceHistory.而是将它们放在数据库中,而不是代码中.

As a suggestion I think you should be weary of creating a class per course. Would it not be sufficient to have a Course class which has a member of type, which could be Math, Science or History. Even that type could itself be an entity: CourseType, which you could have entries for so in your code there would be no Math, Science or History. Instead those are in a database, instead of code.

Review对象将仅与Course进行交互.只要考虑一下添加另一门课程时需要做的所有工作即可.您将不得不更新许多不同的文件,甚至在数据库中添加一个表,我认为您不需要这样做.

The Review object would only then interact with a Course. Just think of also all the work you will need to do when you add another course. You will have to update many different files and even add a table in your database, I don't believe you should need to do that.

我想您在课程类之间可能会有一些差异,并且将所有这些放在一个类中可能有点尴尬.但是根据我的经验,这通常是值得做的,因为它可以大大减少代码量,并允许在没有代码的情况下添加更多课程.

I imagine you may have some differences between Course classes, and it may be a bit awkward having all these in one class. But from my experience this is typically worth doing, as it drastically reduces the amount of code and allows for more courses to be added without code.

编辑我仍然强烈建议您考虑重新评估每门课程上一堂课的决定,但是无论如何都要做出决定.目前还不清楚此Review对象是什么.您说只有2门课程可以招收一名学生,所以我想象这些字段中有2个为空.但这使我感到困惑,因为您每门课程都上一堂课,但是您对所有科目都有一个全面的复习对象.我本来希望看到的:

Edit I still strongly recommend you consider reevaluating your decision of 1 class per a course, but anyway your decision. It's really unclear what this Review object is. You say that there are only 2 courses a student will be enrolled in so I imagine that 2 of these fields are null, then. But then it confuses me because you have one class per course, but you have an overeaching review object across all subjects. I would have expected to see:

class EnrolementReview{
    Course courseA;
    Course courseB;
}

否则,如果您的评论取决于您的MathScience课程中的字段,我希望每门课程都有一个评论班:

Otherwise if your review depends on fields in your Math, or Science courses, I would expect to have a review class for each course:

class MathReview {
    MathCourse course;
}

或者您可能有一个通用的基类供审核

Or you might have a generic base class for review

abstract class CourseReview<C extends Course> {
    C course;
}

,如果它们之间具有共同的功能.然后是SemesterReview类,用于在一个学期中复习2个课程:

if you had common functionality between them. And then an SemesterReview class for reviewing 2 classes in a semester:

class SemesterReview{
    CourseReview review1;
    CourseReview review2;
}

dynamic composition而言,IMO我认为在静态类型语言中此概念没有多大意义.您有构建器模式,蛋糕模式等.某些编程语言在该领域具有一些不错的东西,例如Scala特性,但是好处非常有限,Java中您无法做的事只能等待几个类转换,虽然有些邪恶,但可以完成工作.

As far as dynamic composition, IMO I don't think it makes much sense in a statically typed language this notion. You have builder patterns and cake patterns and the like. Some programming languages have some nice stuff in this area like Scala traits but the benefits are very limited, nothing you couldn't do in Java wait a couple of class casts which are a bit evil but it gets the job done.

对于开发人员可以使用的所有许多设计模式和方法,我认为查看设计决策的某些输出要容易一些,例如:

For all the many permutations of design patterns and methods available to you as a developer, I think it's a bit easier to look at some of the outputs of your design decision, such as:

  • 我要写几节课?
  • 我将能够添加更多课程而无需编写代码和更改 数据库表?
  • 其他人可以理解我的代码吗?
  • How many classes am I going to write?
  • Will I be able to add more courses without writing code and changing the database tables?
  • Can somebody else understand my code?

最后编辑 关于许多空字段,您有一些选择.您要么有空字段(您似乎不喜欢),要么您将变量类型封装为一个实体(例如,每门课程都有一个字符串,整数,双打等的列表),我见过使用了在许多不同的情况下都可以.可以,但是您确实延迟了一些可能已在运行时编译的区域,因为您可能需要一个变量名称为scienceCategory的整数等.如果您有一些结构化数据,这也可能会很尴尬.通常,只有当您真的不知道客户端将如何使用您的系统,并且因此将更多的客户端暴露给他们使用时,这种方法才是好的.

Last Edit In regards to many null field being a concern, you have some options. Either you have null fields (which you seem to not like), or you do something like encapsulate variable types as an entity (for example each course has a list of Strings, Integers, Doubles etc), which I've seen used quite a bit in many different situations. That works out ok but you do delay some areas which may have been at compile to run-time, as you may need an integer which has a variable name of scienceCategory etc. It also can be awkward if you have some structured data. In general that approach is only good if you really don't know how a client is going to use your system and so you expose more of it to them to use.

但是,我个人最喜欢的是遵循您班级的自然组成,并将变量系列封装到自己的班级中,您希望它们永远不会适用,就好像一个人都不适用,其他所有人也不可能.这些类是否存在的逻辑应该非常明确,但是,它们应该是Optional<ScienceInformation>,或者您应该在某处具有一些返回boolean的方法,无论此选项是否存在.然后可以在您创建的系统中的那些选项上执行操作.只需注意您不要创建嵌套太深的对象,就像创建由对象组成的对象或由对象组成的对象一样(并非总是有问题,但通常是这样).

However my personal favourite, is to follow the natural composition of your class, and encapsulate families of variables into their own class, which you expect wont always be applicable, as in if one isn't applicable all the others wont be either. The logic whether these classes are present should be very explicit however, either they should be Optional<ScienceInformation> or you should have some methods somewhere which returns a boolean whether or not this option should exist or not. Then operations can be performed on those options in the system you create. Just need to be careful you don't create objects which are too deeply nested as in objects which are made up of objects, which are made up of objects, (not always a problem but usually it is).

但实际上我认为选择哪种方式并不重要,它们都不会让您感到编写类给您带来舒适的感觉.只需考虑如何将这些实体(例如课程)抽象化,而不会导致您陷入无法维护的困境.您显然对域非常了解,但是您应该以一种使我(不知道一个学期有多少门课程的人)可以阅读代码,然后在不阅读注释的情况下找到代码的方式编写代码(那将是欺骗),这个问题的答案是什么.

But really I don't think it's super important what way you choose, none of them will give you the comfy feeling that writing a class gives you. Just need to think about how you are going to abstract over these entities (eg. Course) in a way which will not lead you to an un-maintainable mess. You clearly have a very complete knowledge of your domain but you should write your code in a way where I (somebody who doesn't know about how many courses are in a semester) can read the code and then find that out without reading comments (that would be cheating), what the answer to that question is.

这篇关于动态构造合成对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆