有人可以解释这3个概念以及它们之间在MVC框架方面的差异以及一个例子.对我来说,这些似乎几乎相同,似乎它们在某些文章中可互换使用,而在其他文章中则不然.
model-view-controller entity design-patterns model domain-object
什么是软件架构中的域对象和域服务?我不熟悉它们或它们与业务逻辑层有何不同?
在Web应用程序中使用Symfony2中的ACL实现时,我们遇到了一个用例,其中建议的使用ACL的方法(检查单个域对象的用户权限)变得不可行.因此,我们想知道是否存在可用于解决问题的ACL API的某些部分.
用例位于控制器中,该控制器准备要在模板中呈现的域对象列表,以便用户可以选择她想要编辑的对象.用户无权编辑数据库中的所有对象,因此必须相应地过滤列表.
这可以(根据其他解决方案)根据两种策略完成:
1)一个查询过滤器,它使用当前用户的ACL为对象(或多个对象)附加有效对象id的给定查询.即:
WHERE <other conditions> AND u.id IN(<list of legal object ids here>)
2)一个查询后过滤器,用于删除用户在从数据库中检索完整列表后没有正确权限的对象.即:
$objs   = <query for objects>
$objIds = <getting all the permitted obj ids from the ACL>
for ($obj in $objs) {
    if (in_array($obj.id, $objIds) { $result[] = $obj; } 
}
return $result;
第一种策略是可取的,因为数据库正在进行所有过滤工作,并且都需要两次数据库查询.一个用于ACL,一个用于实际查询,但这可能是不可避免的.
在Symfony2中是否有任何一种策略(或实现预期结果)的实现?
能否用简单的术语解释Transfer对象和Domain对象之间的区别?如果你能给出一个Java例子,那就太棒了..
在我们基于Symfony2的应用程序中,我们想要创建一个列表,列出系统中哪些用户对给定的域对象具有权限.我们正在使用ACL,我们的直接本能是查看从相关域对象的ACLProvider返回的ACL对象,以查找可以返回具有权限的用户(或至少是SecurityIdentities)的方法,但我找不到这样的方法.
我们确信此功能可通过API获得,但我们无法找到隐藏这些方法的位置.
编辑另一种方法是直接在acl-tables中查找这些连接并找出那种方式,但它不是很漂亮,我们可能会重新发明轮子.
我有以下示例,其中我倾向于使用几个类来创建一个简单的Web应用程序.
文件层次结构如下所示.
> cupid 
    - libs 
        - request
        - router 
        - database
        - view 
    - bootstrap.php 
  - index.php 
在index.php刚刚调用bootstrap.php又包含这样的事情:
// bootstrap.php
namespace cupid
use request, router, database, view; 
spl_autoload_register(function($class){ /* autoload */ });
$request  = new view; 
$response = new response; 
$router   = new router; 
$database = new database; 
$router->get('/blog/{id}', function($id) use ($database, $view) {
    $article = $database->select("SELECT blog, content FROM foo WHERE id = ?",[$id]); 
    $view->layout('blogPage', ['article'=>$article]);
}); 
你可能会说,我的问题是这一行:
$article = $database->select("SELECT blog, content FROM …我刚刚接手了一个ASP.NET MVC项目,需要进行一些重构,但我希望得到一些关于最佳实践的想法/建议.
该站点有一个SQL Server后端,这里是对解决方案内项目的回顾:
我看到的第一个"问题"是,虽然Domain对象类几乎是POCO,并且在计算字段周围有一些额外的"get"属性,但Domain Objects中有一些表示代码.例如,在DomainObjects项目中,有一个Person对象,我在该类上看到了这个属性:
 public class Person
 {
    public virtual string NameIdHTML
    {
        get
        {
           return "<a href='/People/Detail/" + Id + "'>" + Name + "</a> (" + Id + ")";
        }
    }
 }
显然,在域对象中使用HTML生成的内容似乎是错误的.
重构方法:
我的第一个本能是将它移动到MVC项目中的ViewModel类,但是我发现有很多视图符合这个代码,因此我不想在每个视图模型中复制代码.
第二个想法是创建PersonHTML类,它是:
2A.在构造函数中接受Person的包装器
2B.从Person继承并具有所有这些HTML呈现方法的类.
视图Model会将任何Person对象转换为PersonHTML对象,并将其用于所有渲染代码.
我只是想看看:
如果这里有最好的做法,因为这似乎是一个常见的问题/模式
这个当前状态有多糟糕,因为除了感觉不对外,它并没有真正导致理解代码或创建任何不良依赖关系的任何重大问题.任何有助于描述为什么将代码保持在这种状态下的实际意义上的错误(与理论上的关注点分离相比)都会有所帮助,并且团队中是否存在争论是否值得改变.
我知道域逻辑应放在域对象中.但是如果我的域逻辑需要来自数据库的数据呢?(例如,检查唯一值,计算值等等)我认为将存储库注入我的域对象是不对的.服务层也不应包含业务规则.那么如何解决这种业务逻辑呢?
在集合中使用域对象或在地图中使用键是不好的做法?
在过去,我做过很多这样的事情
Set<Book> someBooks = [] as Set
someBooks.addAll (Book.findAllByAuthorLike('%hofstadter%'))
someBooks.add (Book.findByTitleLike ('%eternal%'))
但是我注意到,在findAllByAuthorLike返回Hibernate Proxy对象列表时会经常遇到问题com.me.Book_$$_javassist_128但findByTitleLike会返回正确的com.me.Book对象.这会导致集合中的重复,因为真实对象和代理被认为不相等.
我发现在使用像这样的域对象集时我需要非常小心,我觉得它可能是我不应该首先做的事情.
替代方案当然是使用id的集合/映射,但它使我的代码冗长并容易产生误解
Set<Integer> someBooks = [] as Set // a set of id's for books    
@Burt:我认为Grails域类已经这样做了,至少使得equals/compare在class/id而不是对象实例上完成.你的意思是hibernate代理的特殊比较器?
return (this.class == obj.class && this.id == obj.id) || 
       (obj.class  == someHibernateProxy && this.id == obj.id)
我最近一直忙于尝试理解ddd和Model层的概念.阅读大量的文章,例子,Q和A,花了很多时间.而且我仍然不确定我是否有正确的原则.
其中之一就是问题的答案:Domain Objects中应该存在多少业务逻辑?有些消息来源说Domain Objects应该附带整个业务逻辑,另一方面,我遇到了一些文章,我认为它应该尽可能小,只代表它的价值.这让我很困惑.
在我的理解中,域对象是表示域中实体的类.
因此,举例来说,请使用Invoice实体.每张发票都包含其项目.要计算发票金额,我们必须对所有项目值进行求和(这是非常简单的示例,在现实世界中会出现添加税,计算付费价值等情况)
class Invoice
{
    public $id;
    public $items = [];
    public $status;
    const STATUS_PAID = 'paid';
    const STATUS_NOT_PAID = 'not_paid';
    public function isPaid()
    {
        return $this->status == self::STATUS_PAID;
    }
    public function getInvoiceValue()
    {
        $sum = 0;
        foreach($this->items as $item) {
            $sum += $item->value;
        }
        return $sum;
    }
}
在我的理解中,方法isPaid()是在正确的位置.它指的是自己的数据.但我不确定getInvoiceValue().我们在这里运行其他域对象.
也许我们应该只使用域对象来表示数据,但是使用一些装饰器来执行更高级的任务?
提前致谢.
domain-object ×10
model ×3
php ×3
acl ×2
architecture ×2
java ×2
permissions ×2
symfony ×2
asp.net-mvc ×1
c# ×1
entity ×1
grails ×1
groovy ×1
html ×1
oop ×1
refactoring ×1