Getters / setters وقضية التغليف في مشاريع symfony

في الآونة الأخيرة ، كنت أعمل مع Symfony (ما يزيد قليلاً عن عام) وفي جميع المشاريع التي أتيحت لي فرصة للعمل عليها - تم إنشاء الكيانات دائمًا بطريقة احتوت على حقول خاصة فقط و / أو مستوطنين / حراس لهم.

ستناقش المقالات وأمثلة لماذا هذا النهج خطير ، وهو: ينتهك التغليف القديم الجيد لدينا ، ويثير رمز الكتابة مع الأخطاء ويزيد من تعقيد النظام.
سوف تغفل المقالة موضوع المستوطنين في مختلف الصانعين وموضوع حقن التبعية من خلال المستوطنين (سأقول فقط أننا لا نوافق). لن يكون هناك شيء حول موضوعات معقدة مثل DDD و Rich Model وحول الاقتران / التماسك وكلمات ذكية أخرى - فقط تحدث عن التغليف. مرحبا بكم في القط.

اذهب إلى الكود دعنا نتجاهل لثانية واحدة تلميح الكتابة و إشارة إرجاع النوع وننظر في كيفية اختلاف التعليمات البرمجية التالية عن وجهة نظر نفعية عند العمل مع كائن:

$userName = $user->name;
$user->name = $newUserName;
:
$userName = $user->getName();
$user->setName($newUserName);

, , .

C . — , .


? , , . , , , .

«» , :

class Order
{
     private const STATUS_OPEN = 'open';
     private const STATUS_DELIVERED = 'delivered';

     private ProductCollection $products;
     private string $deliveryStatus;
     private ?DateTime $deliveryDate = null;

     public function deliver()
     {
          if ($this->isDelivered()) {
               throw new OrderDomainException('Order already delivered.');
          }

          $this->deliveryDate = new DateTime();
          $this->deliveryStatus = self::STATUS_DELIVERED;
     }

     private function isDelivered(): bool
     {
         return $this->deliveryStatus === self::STATUS_DELIVERED;
     }

     //  
}

« » - ? ? — ? . — , , . (cohesion).

:

class Order
{
    private const STATUS_OPEN = 'open';
    private const STATUS_DELIVERED = 'delivered';

    private ProductCollection $products;
    private string $deliveryStatus;
    private ?DateTime $deliveryDate = null;

    public function getDeliveryStatus(): string
    {
        return $this->deliveryStatus;
    }

    public function setDeliveryStatus(string $deliveryStatus): void
    {
        $this->deliveryStatus = $deliveryStatus;
    }

    public function getDeliveryDate(): ?DateTime
    {
        return $this->deliveryDate;
    }

    public function setDeliveryDate(?DateTime $deliveryDate): void
    {
        $this->deliveryDate = $deliveryDate;
    }

    public function getProducts(): ProductCollection
    {
        return $this->products;
    }

    public function setProducts(ProductCollection $products): void
    {
        $this->products = $products;
    }
}

? ( ). — , , , , ? , ? . — , — . . . , — ?


, . — , .

— , , , , , .

. :

/**
 * @ORM\Entity
 */
class Project
{
    /**
     * @var Id
     * @ORM\GeneratedValue()
     * @ORM\Id
     */
    private $id;
    /**
     * @var string
     * @ORM\Column(type="string")
     */
    private $name;
    /**
     * @var string
     * @ORM\Column(type="string", nullable=false)
     */
    private $status;
    /**
     * @var int
     * @ORM\Column(type="integer", nullable=true)
     */
    private $sort;
    /**
     * @var User
     * @ORM\Column(type="user_type", nullable=false)
     */
    private $user;
    /**
     * @var Department
     * @ORM\OneToMany(targetEntity="Department")
     */
    private $department;
    /**
     * @var string
     * @ORM\Column(type="string", nullable=true)
     */
    private $membership;
    
    public function getId(): Id
    {
        return $this->id;
    }
    
    public function getName(): string
    {
        return $this->name;
    }
    
    public function setName(string $name): Project
    {
        $this->name = $name;
        return $this;
    }
    
    public function getStatus(): string
    {
        return $this->status;
    }
    
    public function setStatus(string $status): Project
    {
        $this->status = $status;
        return $this;
    }
    
    public function getSort(): int
    {
        return $this->sort;
    }
    
    public function setSort(int $sort): Project
    {
        $this->sort = $sort;
        return $this;
    }
    
    public function getUser(): User
    {
        return $this->user;
    }
    
    public function setUser(User $user): Project
    {
        $this->user = $user;
        return $this;
    }
    
    public function getDepartment(): Department
    {
        return $this->department;
    }
    
    public function setDepartment(Department $department): Project
    {
        $this->department = $department;
        return $this;
    }
    
    public function getMembership(): string
    {
        return $this->membership;
    }
    
    public function setMembership(string $membership): Project
    {
        $this->membership = $membership;
        return $this;
    }
}

not nullable — ( false). , — not nullable , ? :)
, — ( ). .

, Doctrine ( ) , Reflection API. Marco Pivetta , : ocramius.imtqy.com/blog/doctrine-orm-optimization-hydration


. .
, , ( DTO, ..).

, , - «» . , , .

-. ID, — :

$order = $this->orderRepository->find($orderId);
if ($order === null) {
     throw new OrderException('Order not found.');
}

if ($order->getStatus() === Order::STATUS_ACTIVE 
    && $order->getDeliveryDate() <= $date
) {
    $this->orderDeliveryService->handle($order);
}

— , :

$order = $this->orderRepository->find($orderId);
$cityFreeLimit = $this->cityOrderService->getCityFreeLimit($cityName);

if ($order->getCity() === $cityName 
    && $order->getTotalPrice() > $cityFreeLimit
) {
     $delivery = 0;
     $this->orderDeliveryService->deliveryOrder($order, $delivery);
     
     return;
}

//         

, - .

, - . , , , . , , , . «» «».


/ , , , , « » , — , , .

— Symfony (DAO), /. — - ( , ).

, — :)

. — .

Source: https://habr.com/ru/post/ar469323/


All Articles