Załóżmy Mam następujący Doctrine 2 jednostki:Stałe w doktrynie 2 podmiotów
/**
* @ORM\Entity
* @ORM\Table(name="users")
*/
class User {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*
* @var int
*/
protected $id;
/**
* @ORM\Column(length=100)
*
* @var string
*/
protected $name;
/**
* @ORM\Column(type="integer")
*
* @var int
*/
protected $status;
}
Użytkownik może mieć kilka stanów, na przykład: W trakcie, aktywny, zawieszeniu. Stany te są potrzebne w całym kodzie (usługi, repozytorium itp.), A także w warstwie interfejsu użytkownika (formularz edycji użytkownika wyświetliłby je w rozwijanym menu).
Aby uniknąć definiowania ich w wielu miejscach, co zrobiłem do tej pory było użyć klasy do nich wszystkich (Wszystkie stałe w aplikacji) posiadają, i wygląda nieco jak poniżej:
class App_Constants extends Zrzr_Constants
{
protected static $_constants = array(
'users' => array(
'status' => array(
0 => 'Pending',
1 => 'Active',
2 => 'Suspended')));
}
Klasa bazowa (Zrzr_Constants) będzie oferować kilka metod, aby je odzyskać, a wygląda to tak:
class Zrzr_Constants
{
protected static $_constants = array();
public static function getConstantValues($key, $subkey)
{
// ...
}
public static function getConstantByName($name)
{
// ...
}
}
potocznym byłoby:
// example of retrieval by constant name ... it would return an integer
$pendingStatus = App_Constants::getConstantByName('USERS.STATUS.PENDING');
// example of retrieval for UI display purposes ... would return an array
$statuses = App_Constants::getConstantValues('users', 'status');
Oczywiście oznacza to, że istnieją pewne ograniczenia polegające na tym, że stałe etykiety nie mogą zawierać kropek, ale mogę z tym żyć.
Korzystanie z Doctrine 2 i przejście na DDD mówi mi jednak, że pole "status" powinno być w rzeczywistości "obiektem wartości" (ale Doctrine 2 jeszcze nie obsługuje obiektów wartości) lub przynajmniej powinno to być stałe zdefiniowane wewnątrz jednostki (przy użyciu const).
Moje pytanie brzmi: jak to zrobić, aby uniknąć ciągłej redefinicji warstwy UI? Muszę mieć dostęp do stałej według nazwy (w kodzie) i mieć wszystkie możliwe wartości dla takiego pola w przypadku listy rozwijanej interfejsu użytkownika (na przykład).
Twój widok jest jedynym miejscem, które potrzebuje nazw.Warstwa interfejsu użytkownika powinna wykonywać całą konwersję między nazwami i wartościami; wszędzie indziej powinien po prostu użyć wartości całkowitej. Może być użyteczne dodanie niektórych metod do twojego obiektu, takich jak 'isPending()' – rojoca
@rojoca - Kiedy mówisz "użyj wartości całkowitej" z pewnością nie masz na myśli czegoś takiego: 'if ($ user-> getStatus() = = 2) ... '. Interfejs użytkownika może nie być jedyną inną warstwą korzystającą z tych stałych. A co z tymi stałymi używanymi w zapytaniach, które nie przechodzą przez model domeny (przy zastosowaniu jakiegoś CQS)? – Ghola
Nie; w twoim przykładzie myślę, że 'if ($ user-> isPending())' jest lepsze, ponieważ mówi dokładnie, co to znaczy. Możesz tworzyć stałe takie jak 'User :: STATUS_PENDING' w swoim modelu domeny, a następnie używać ich w' App_Constants' np. 'User :: STATUS_PENDING => 'Pending''. App_Constants zależy od twojej domeny, czy kodujesz wartości (tak jak robisz to obecnie), czy używasz stałych klas; równie dobrze możesz używać stałych. – rojoca