2017-03-12 15:33 GMT+05:00 Yasuo Ohgaki <yohg...@ohgaki.net>: > DbC allows this kind of validation at development time. > I suppose you would like to check requirement at runtime always.
Yes, DbC from here https://wiki.php.net/rfc/dbc2 describes similar things. This is good idea, but I tell more about checks which cannot be removed from code. Types which meet some requirements looks more closer to business logic terms than constructions like if-throw or require($order->isReadyForSomething()). 2017-03-12 15:35 GMT+05:00 Fleshgrinder <p...@fleshgrinder.com>: > `IncompleteOrder` is the one without date, address, and > probably even products. You directly named it as such. Then you have > `ProcessableOrder` where this is impossible Yes, this is Order and OrderForCheckout in my example. But they should not be descendants of base class or each other. Because allowed class states are not descendants of that class. > **BAM** all problems solved. Yeah, now we have: base Order IncompleteOrder extends Order ProcessableOrder extends Order PaidOrder extends Order // or ProcessableOrder? and later could get: WholesaleOrder extends Order with a question how to extend classes in new branch. Also the problem is how to use this tree in relations. There is class OrderItem with $order property. There is class Customer with $orders property. What classes should have these properties? Every time different? This is a part of another problem that we need to decide what exact class should be created here or there before calling a function which uses it. With type variants (hm, or invariants) it could be: Order ProcessableOrder variant of Order PaidOrder variant of Order WholesaleOrder variant of Order And everywhere we can create and use objects with class Order, and only in some functions they will be considered as processable or not.