我一直在研究几个Grails示例应用程序,教程和书籍(Grails 2 QuickStart),试图了解如何在Grails中实现业务逻辑。来自railsbackground我期望在模型中看到这些东西,但我在各种例子中看到的都是约束等等。
以下是原型"帐户"具有平衡和透支属性的对象以及makeDeposit和makeWithdrawal方法。它展示了我所有的问题。 (评论内联)。
所有这些事情在Rails中并不难做到,但由于我所看到的所有书籍示例都没有在Domain类中使用这些方法,因此Domain Classes并不意味着有很多自定义代码他们。请欣赏一个如何正确实现像Grails Domain类这样的东西的例子(或者你应该像这样的规则。
class Account {
List deposits
List withdrawals
public long balance = 0;
//is setting a default value the right way to initialize
// this value to 0 in the db?
private Date accountCreated;
//Does private modifer mean accountCreated won't get persisted to the db?
//Assuming I want it in the db, where do initialize this to a client
//supplied value, but make it write-once? I gather I need to have
//parameterless-constructor, so I can't supply it with
//"new Account(creationDate) as you might do in Java.
public boolean isOverdrawn = false;
private void setIsOverdrawn() {}
//does the private setIsOverdrawn method below make this a readOnly to
//other objects in my application?
static hasMany = [deposits: Long, withdrawals: Long]
static constraints = {
balance nullable: false
accountCreated() //if I do this, does that turn this from a
// field into a column?
}
private void setBalance(long newBalance) {
//will the private modifier prevent other objects
//from setting balance directly?
this.balance = newBalance;
if (balance < 0) this.isOverdrawn = true else this.isOverdrawn = false;
}
//this should be the only way for clients to change the balanace in the account.
public void makeDeposit(Long amount) {
deposits.add(amount)
setBalance(this.balance += amount);
this.save()
}
public void makeWithdrawal(Long amount) {
withdrawals.add(amount);
setBalance(this.balance -= amount)
this.save();
}
}
答案 0 :(得分:0)
好的,所以你有一个更大的问题“我应该把业务逻辑放在哪里?”然后还有你的示例域类中的许多其他问题。
让我们从更大的问题开始:“我应该把业务逻辑放在哪里?”。你可以在这里做两个选择。首先,正如您已经演示的那样,可以将业务逻辑放在域类本身中。这在Grails中并不常见,因为域类通常更像是一个贫血的域类。为了有效地做到这一点,你必须真正理解GORM和数据绑定是如何工作的,以便完成很多事情。一如既往地阅读整个Grails documentation将有助于您了解Grails希望如何完成任务。
最常见的方法是将所有业务逻辑放在服务层中的服务中。这些单例类负责访问和协调您的域类,以作为一个有凝聚力的系统。同样,Grails documentation on services在理论上涵盖了这一点。文档甚至指出:
Grails中的服务是放置大部分逻辑的地方 你的申请......
现在你的例子中有一些小问题。总的来说,你对GORM和域类在Grails中的工作原理有明显的误解。 Public vs Private在域类中没有任何影响。为了使某些内容成为只读内容,您需要查看beforeInsert
和beforeUpdate
以及甚至transients
的hibernate事件。我推荐Grails文档的GORM section以获取更多信息。
由于您有使用Rails的经验,因此您需要尝试停止比较这两者。 Grails可能会分享一些共同点,但它有自己的方法。阅读文档将帮助您发现方法上的差异。 (是的,我知道这是很多阅读,但它写得很好,并且有很多非常好的信息。)