Symfony2 DTO,实体转换

时间:2014-05-30 11:16:07

标签: php symfony architecture doctrine-orm dto

我正在使用doctrine2创建symfony2应用程序,我想就DTO-Entity,Entity-DTO转换的常见/良好实践提出建议。我找到了所有语言和框架的一些信息,但SF2没有。

我想隔离实体,因此它们仅用于服务和DAO(管理器,SF2术语中的存储库)。控制器永远不会看到DAO或实体,只能通过服务与业务逻辑交互。服务和控制器之间的所有通信都应该通过原始类型,标量,DTO来完成。

示例:

控制器

class RegistrationController extends Controller
{
    public function registerAction($name)
    {
        $userDTO = new UserDTO();
        $form = $this->createForm(new UserType(), $userDTO);

        $form->handleRequest($request);

        if ($form->isValid()) {
            $userService = $this->get('userService');

            $userService->createUser($userDTO);

            return $this->redirect($this->generateUrl('success'));
        }

    --//--
    }
}

服务

class UserServiceImpl implements UserService
{

    private $userDao;

    public function __construct(UserDao $userDao)
    {
        $this->userDao = $userDao;
    }

    public function createUser(UserDTO $user)
    {
        $user = new User(); #doctrine entity
        $user->setFirstName($userDTO->getFirstName());
        $user->setLastName($userDTO->getLastName());

        $this->userDao->persist($user);
        $this->userDao->flush();

        --//--
    }
}

随着User对象中属性数量的增加,问题很快出现。在我的应用程序中,用户有13个字段是否有任何SF2工具(类)来简化此过程?你自己编写转换器/变压器吗?你能举例说明它应该是什么样的吗? Maby PHP魔术方法可以帮忙吗?反思怎么样?

感谢您的意见和建议。

2 个答案:

答案 0 :(得分:8)

首先在你的dto上使用公共属性。这消除了一堆getter / setter方法,这些方法实际上不应该为dto做任何事情。您可以随时为特殊情况添加一些majic方法。

接下来,重新考虑DoctrineUserEntity又名Domain对象的设计。你真的需要每个属性的getter / setter吗?如果是这样,那么重点是什么?

而是尝试将属性分组为值对象:

$userNameValueObject = new UserNameValueObject($userDto->firstName, $userDto->lastName);

$userEntity = new UserEntity($userDTO->username,$userDTO->password, $userNameValueObject);

// And maybe this for updates
$userEntity->updateName($userNameValueObject);

但同样,请确保您确实为您的工作获得了一些价值。一堆一对一的映射可能在域对象可以在请求之间保持活动的其他平台上有意义。在PHP中,一切都从零开始。

答案 1 :(得分:0)

我最近发现的一个选项是https://github.com/jasonrobertfox/DTOx,它是DTO和测试的生成器。它为你做了烦人的锅炉板生成工作。