2017-08-13 1 views
0

Les objets de mes sociétés ont besoin d'être sécurisés par les programmeurs, ce qui oblige à mettre un nom d'utilisateur sur chaque objet. Nous aimerions toujours refactoriser et nettoyer le code existant et avoir une structure autour de cela. Notre sur l'argument aller est certains croient les CRUD comme des actions sur un objet doit être appelé par un utilisateur dans l'exempledans l'application web oop l'objet utilisateur géant doit-il avoir des actions ou des classes d'action pour recevoir un utilisateur?

$user = new User('usernameExample'); 
$profileData = $user->getProfile(12313); 
echo json_encode($profileData); 
$ID = $user->createProfile($_POST); 
$user->updateProfile($_POST); 
$user->refreshProfile(12321394); 
$user->deleteProfile(234242); 

$user = new User('usernameExample'); 
$batches = $user->getGroupList(); 
$user->updateGroup($_POST); 
$user->deleteGroup(23242); 
$newBatchID = $user->createGroup(); 

$user = new User('usernameExample'); 
$user->addSubuser($_POST); 
$user->deleteSubuser('usernameExample'); 
$user->updateSubuser($_POST); 
$user->getSubusers(); 

$user new User('usernameExample'); 
$user->updateSetting($_POST); 

est de lancer dans 50 méthodes ou plus pour objet utilisateur à bien ou si les choses se rompu par base et transmettre un nom d'utilisateur ou un objet utilisateur immuable? Exemple ci-dessous

$userProfiles = new UserProfile('usernameExample'); 
$profileData = $userProfile->getProfile(12313); 
+0

aller avec le modèle entity & datamapper. voir: https://stackoverflow.com/questions/11942842/who-should-handle-the-conditions-in-complex-queries-the-data-mapper-or-the-serv/11943107#11943107 – jeremy

+0

qu'est-ce que [domaine -drive-design] a à voir avec ça? – jeremy

+0

J'espérais que quelqu'un avec l'expérience ddd donnerait leur approche. – prettyHomePages

Répondre

1

Farce beaucoup de fonctionnalités dans vos objets métier pour gérer l'interaction avec d'autres objets peuvent devenir laid rapidement, surtout si vous avez affaire à des relations complexes et la logique.

La première étape au-delà de ce type d'architecture consiste généralement à implémenter des classes de service pour faciliter l'interaction entre vos objets.

Considérez ce qui suit:

<?php 
/** 
* Class UserBasedServiceAbstract 
* Base class for our user based services. All services must be instantiated 
* with a valid user 
*/ 
abstract class UserBasedServiceAbstract 
{ 
    protected $user; 

    /** 
    * UserBasedServiceAbstract constructor. 
    * @param User $user 
    * @throws Exception 
    */ 
    public function __construct(User $user) 
    { 
     if($user->isNew()) 
     { 
      throw new Exception('User must be persisted before doing anything useful with it'); 
     } 

     $this->user = $user; 
    } 

    /** 
    * @param $message 
    */ 
    protected function logAction($message) 
    { 
     $formattedMessage = (is_array($message)) ? json_encode($message):$message; 
     echo 'User action for '.$this->user->getUsername().': '.$formattedMessage; 
    } 
} 

class GroupService extends UserBasedServiceAbstract 
{ 
    /** 
    * Get a list of groups that the current user belongs to 
    * @return array 
    */ 
    public function getGroupList() 
    { 
     // We always have a reference to our user 
     $userId = $this->user->getId(); 

     $this->logAction('Getting group list'); 

     //Fetch groups for user 
     $groupList = []; 

     return $groupList; 
    } 

    /** 
    * Update the specified group if the current user has permission to do so 
    * @param Group $group 
    * @param array $params 
    * @throws Exception 
    */ 
    public function updateGroup(Group $group, array $params) 
    { 
     if(!$this->_userCanUpdateGroup()) 
     { 
      throw new Exception('User does not have permission to update this group'); 
     } 

     $this->logAction('Updating group'); 

     //update group 
    } 

    /** 
    * Delete the specified group if the current user has permission to do so 
    * @param Group $group 
    * @throws Exception 
    */ 
    public function deleteGroup(Group $group) 
    { 
     if(!$this->_userCanDeleteGroup($group)) 
     { 
      throw new Exception('User does not have permission to delete this group'); 
     } 

     $this->logAction('Deleting group'); 

     //delete group 
    } 

    /** 
    * Determine whether or not the current user can delete the specified group 
    * @param Group $group 
    * @return bool 
    * @throws Exception 
    */ 
    private function _userCanDeleteGroup(Group $group) 
    { 
     //Maybe there is some logic we need to check on the group before we go further 
     if(!$group->isDeletable()) 
     { 
      throw new Exception('This group cannot be deleted'); 
     } 

     // Implement some user-specific logic 
     return ($this->user->hasPermission('group_admin') && $this->user->getKarma()>100); 
    } 

    /** 
    * Determine whether or not the current user can update the specified group 
    * @return bool 
    */ 
    private function _userCanUpdateGroup() 
    { 
     // Implement some user-specific logic 
     return ($this->user->hasPermission('group_moderator') && $this->user->getKarma()>50); 
    } 
} 

Vous créez une classe abstraite avec les fonctions communes dont vous avez besoin, et de vérifier et de tenir une référence à votre utilisateur. Tous vos services qui doivent être basés autour d'une instance d'utilisateur étendent cette classe et facilitent l'interaction entre l'objet utilisateur et les objets associés. Toute votre logique autour des autorisations va dans ces classes de service. C'est beaucoup plus facile à gérer que de bourrer tout cela dans les objets métier.

Cette approche peut vous emmener loin. Les astronautes d'OO peuvent vous dire d'aller voir les modèles de conception comme le modèle de médiateur pour ce genre de chose, et cela peut certainement bien fonctionner, mais il y a toujours un compromis entre la complexité et la facilité d'utilisation. Pour la plupart des applications lourdes de CRUD, je trouve cette approche basée sur le service pour être le point idéal.