I'm trying to get my head around combining some techniques.
It seems good practice to never make it possible to create a ValueObject that is not valid. The ValueObject constructor therefor should fail whenever the provided content is not good enough to create a valid ValueObject. In the examples I have, an EmailAddress object can only be created when there is a value present. So far, so good.
Validating the value of the provided emailaddress, that's where I begin to doubt the principles. I have four examples, but I can't tell which one should be considered the best practice.
Example 1 is the easy one: simply a construct function, a required parameter "value", and a separate function validate to keep the code clean. All the validation code stays inside the class, and will never be available to the outside world. The class has only one purpose: store the emailaddress, and make sure it will never be an invalid one. But the code will never be reusable - I create an object with it, but that's all.
public function __construct ($value)
{
if ( $this->validate($value) )
{
throw new \ValidationException('This is not an emailaddress.');
}
$this->value = $value;
}
protected function validate ($value)
{
return is_string($value); // Wrong function, just an example
}
Example 2 makes the validate function a static function. The function will never change the state of the class, so it is a correct use of the static keyword, and the code in it will never be able to change anything to any instance created from the class embedding the static function. But if I want to reuse the code, I can call the static function. Still, this feels dirty to me.
public function __construct ($value)
{
if ( $self::validate($value) )
{
throw new \ValidationException('This is not an emailaddress.');
}
$this->value = $value;
}
public static function validate ($value)
{
return is_string($value); // Wrong function, just an example
}
Example 3 introduces another class, hardcoded inside the body of my object. The other class is a validation class, containing the validation code, and creates thus a class that can be used whenever and wherever I need a validation class. The class itself is hardcoded, which also means that I create a dependency on that validation class, which should be always nearby, and is not injected through dependency injection. One could say that having a validator hard coded is as bad as having the complete code embedded in the object, but on the other hand: DI is important, and this way one has to create a new class (extending, or simply rewriting) to simply change the dependency.
public function __construct ($value)
{
if ( $this->validate($value) )
{
throw new \ValidationException('This is not an emailaddress.');
}
$this->value = $value;
}
protected function validate ($value)
{
$validator = new \Validator();
return $validator->validate($value);
}
Example 4 uses the validator class again, but puts it in the constructor. My ValueObject thus needs a validator class already present and created, before creating the class, but it is possible to easily overwrite the validator. But how good is it for a simple ValueObject class to have such a dependency in the constructor, as the only thing really important is the value, it should not be my concern to know how and where to handle if the email is correct, and providing a correct validator.
public function __construct ($value, \Validator $validator)
{
if ( $validator->validate($value) )
{
throw new \ValidationException('This is not an emailaddress.');
}
$this->value = $value;
}
The last example I started thinking about, is providing a default validator, and meanwhile make it possible to inject through DI an overwrite for the validator in the constructor. But I started doubting how good a simple ValueObject is when you overwrite the most important part: the validation.
So, anyone has an answer which way one should best write this class, that is correct for something as easy as an emailaddress, or something more complex like a barcode or a visa card or whatever one may think about, and doesn't violate DDD, DI, OOP, DRY, wrong use of static, and so on...
The complete code:
class EmailAddress implements \ValueObject
{
protected $value = null;
// --- --- --- Example 1
public function __construct ($value)
{
if ( $this->validate($value) )
{
throw new \ValidationException('This is not an emailaddress.');
}
$this->value = $value;
}
protected function validate ($value)
{
return is_string($value); // Wrong function, just an example
}
// --- --- --- Example 2
public function __construct ($value)
{
if ( $self::validate($value) )
{
throw new \ValidationException('This is not an emailaddress.');
}
$this->value = $value;
}
public static function validate ($value)
{
return is_string($value); // Wrong function, just an example
}
// --- --- --- Example 3
public function __construct ($value)
{
if ( $this->validate($value) )
{
throw new \ValidationException('This is not an emailaddress.');
}
$this->value = $value;
}
protected function validate ($value)
{
$validator = new \Validator();
return $validator->validate($value);
}
// --- --- --- Example 4
public function __construct ($value, \Validator $validator)
{
if ( $validator->validate($value) )
{
throw new \ValidationException('This is not an emailaddress.');
}
$this->value = $value;
}
}
Example 4!
Why? Because it's testable, plain and simple.
Depending on what your validator actually does (in some circumstances your validator may rely on an API call or a call to a database) the injectable validator is completely testable via mocks. All of the other's are either impossible to test under the circumstances I just mentioned, or incredibly hard to test.
EDIT: For those wondering how the dependency injection method helps with testing then consider the CommentValidator class below that utilises a standard Akismet spam checking library.
class CommentValidator {
public function checkLength($text) {
// check for text greater than 140 chars
return (isset($text{140})) ? false : true;
}
public function checkSpam($author, $email, $text, $link) {
// Load array with comment data.
$comment = array(
'author' => $author,
'email' => $email,
'website' => 'http://www.example.com/',
'body' => $text,
'permalink' => $link
);
// Instantiate an instance of the class.
$akismet = new Akismet('http://www.your-domain.com/', 'API_KEY', $comment);
// Test for errors.
if($akismet->errorsExist()) { // Returns true if any errors exist.
if($akismet->isError('AKISMET_INVALID_KEY')) {
return true;
} elseif($akismet->isError('AKISMET_RESPONSE_FAILED')) {
return true;
} elseif($akismet->isError('AKISMET_SERVER_NOT_FOUND')) {
return true;
}
} else {
// No errors, check for spam.
if ($akismet->isSpam()) {
return true;
} else {
return false;
}
}
}
}
And now below, when you're setting up your unit tests we have a CommentValidatorMock class that we use instead, we have setters to manually change the 2 output bools we can have, and we have the 2 functions from above mock'd up to output whatever we want without having to go through the Akismet API.
class CommentValidatorMock {
public $lengthReturn = true;
public $spamReturn = false;
public function checkLength($text) {
return $this->lengthReturn;
}
public function checkSpam($author, $email, $text, $link) {
return $this->spamReturn;
}
public function setSpamReturn($val) {
$this->spamReturn = $val;
}
public function setLengthReturn($val) {
$this->lengthReturn = $val;
}
}
If you're serious about unit testing then you need to use DI.
The first instinct is usually the best. You should use the first option. EmailAddress is a value object. It can be reused in other value objects or entities. I don't understand why you think it's not reusable. You can have a "shared library" of these common value objects used in other bounded contexts. Just be careful what you put in there. They would need to be truly generic if that's even conceptually possible.
I think if you use separate validation methods or move the validators to separate class will be butter and prevent DRY
class EmailAddress{
protected $value;
public function __construct ($value)
{
$this->value = \validateEmailAddress($value);
}
}
function validateEmailaddress(string $value) : string
{
if(!is_string($value)){
throw new \ValidationException('This is not an emailaddress.');
} // Wrong function, just an example
return $value;
}
//OR for strict OOP people
final class VOValidator{
private function __construct(){}
public static function validateEmailaddress(string $input): string{...}
}
//I will prefer even go far and use Either from (FP monads)
interface ValueObejctError {}
class InvalidEmail implements ValueObjectError {}
function validateEmailaddress(string $input): Either {
// it will be better if php supported generic so using Either<InvalidaEmail, string> is more readable but unfortunately php has no generic types, maybe in future
return is_string($input)
? new Right($input)
: new Left(new InvalidEmail());
}
Related
This question already has answers here:
Is there a "nullsafe operator" in PHP?
(3 answers)
Closed 2 years ago.
I would like to combine 2 objects through composition with one optional object and keep a generic and clean API. To provide an example:
class Composition implements Object1Interface, Object2Interface
{
private $object1;
private $object2;
public function __construct($object1, $object2 = null)
{
$this->$object1 = $object1;
$this->$object2 = $object2;
}
// This will always work since the object is mandatory.
public function getId() {
return $this->object1->getId();
}
// This may fail because the object2 can be null.
public function getName() {
return $this->object2->getName();
}
}
You could see that this starts to fail pretty fast since I could be proxying on a null object here. What would be a good way to solve this?
If I were to make $object2 mandatory while I might not have all the constructor data at all times to fill out $object2, I need to make all arguments for the constructor optional. This seems like a big no-no since it would no longer have required arguments.
An option would be to create a method to return $object2 but this requires chaining by a user like so:
$composition->getObject2()->getName()
This could be acceptable but I am destroying the clean API that I have and am now chaining methods.
Is there anything that can be done here to fix this or should I simply go with the mentioned chaining of methods solution?
I guess you mean something like null-safe operator.
Unlike Hack, the PHP does not have this operator (the relevant RFC), so you need explicitly check the values for null. Also you can use something like Option Type. At least you can dynamically create "default" versions of dependent objects:
class Composition implements Object1Interface, Object2Interface
{
private $object1;
// ...
public function __construct(Object1Interface $object1 = null, Object2Interface $object2 = null)
{
if ($object1 !== null) {
$this->object1 = $object1;
} else {
$this->object1 = new class implements Object1Interface
{
public function getId()
{
return null;
}
};
}
// ...
}
public function getId() {
return $this->object1->getId(); // Always works.
}
}
You have two options: Either always check if the object is set before returning anything from it, or use a "dummy" object in place of a user-supplied one if one isn't supplied.
The former can become quite messy as you have to add guards around everything, so I'd personally prefer the latter.
One thing that will make implementing the latter a lot simpler is using an interface to specify the specifications of the expected object and having your constructor instantiate the dummy object if no real object is supplied.
interface AThingThatDoesSomething
{
public function getValue() : integer
}
class RealClass implements AThingThatDoesSomething
{
public function getValue() : integer
{
return mt_rand();
}
}
class DummyClass implements AThingThatDoesSomething
{
public function getValue() : integer
{
// You could return a dummy value here, or throw an exception, or whatever you deem to be the correct behaviour for the dummy class. This implementation just returns 0 for simplicity
return 0;
}
}
class ConsumingClass
{
private $requiredInstance = null;
private $optionalInstance = null;
public function __construct(AThingThatDoesSomething $requiredInstance, AThingThatDoesSomething $optionalInstance = null)
{
if (null === $optionalInstance)
{
$optionalInstance = new DummyClass();
}
$this->requiredInstance = $requiredInstance;
$this->optionalInstance = $optionalInstance;
}
public function getRequiredVal() : integer
{
return $this->requiredInstance->getValue();
}
// You don't need to worry if the user supplied an optional instance here because if they didn't then the dummy instance will have been instantiated instead
public function getOptionalVal() : integer
{
return $this->optionalInstance->getValue();
}
}
This might seem like a contrived example, and of course you'd be right, but it also demonstrates one of the benefits of a pattern called Design By Contract. As long as an object promises to meet certain criteria (in this case by implementing an interface) then you can substitute any object that meets those criteria, even if the object doesn't actually do anything.
In real life I use this for classes where I need logging. I use the psr\log package and set a new NullLogger in the constructor. If I need actual logging I then use setLogger() to pass a logger in, but if I don't then I don't need to worry about $this->logger failing because it's always set.
I have a class in php that works with the chainning method, but the problem is that I want to chain the methods in some order.
class Chain {
public function foo () {
return $this;
}
public function bar () {
return $this;
}
public function some () {
return $this;
}
}
So, if I use this class, then I can chain this methods in 9 different ways (all the possible combinations of 3 elements)
But what happen if I determine that the method some always must to be chained after foo or bar and not in other way?
$chain = new Chain();
$chain->foo->bar(); //works; i.e: the method some is optional
$chain->foo()->bar()->some(); //works
$chain->bar()->foo()->some(); //works
$chain->some()->bar()->foo(); //throws an exception
I think that I can do this setting boolean values, something like: when the method foo or bar are called, then I set the value to some var to true, and when the developer calls the some function, if that var is false, then throws an exception, otherwise is allowed to continue.
But I need something more elegant, such as pattern or a built-in solution.
There is another way to do it?
The very rough example I imagine will still have some lines of code in each method
<?php
class Chain {
private $_register = array();
public function foo () {
$this->register(__METHOD__);
return $this;
}
public function bar () {
$this->register(__METHOD__);
return $this;
}
public function some () {;
$this->verify('foo'); // foo() should be called before some();
$this->register(__METHOD__);
echo 'it\'s ok';
return $this;
}
public function verify($method) {
if(array_key_exists($method, $this->_register) && $this->_register[$method] == true) {
return true;
}
else {
throw new Exception('Some exception');
}
}
public function register($method) {
$method = str_replace(__CLASS__.'::', '', $method);
$this->_register[$method] = true;
}
}
What do we do here - we have a register() and verify() methods. (they can be helpers, but for the current purpose I added them in the class.
Each method should have before it's returning value a register to itself. Calling $this->register(__METHOD__) from foo() will add in the private array 'foo' => true.
The verify() method checks if foo exist as array key and if its value is true. If it is - the script will continue. Otherwise - throws exception.
In this case:
$chain = new Chain();
$chain->bar()->some()->foo(); //throws an exception
Fatal error: Uncaught exception 'Exception' with message 'Some
exception' in ...
$chain = new Chain();
$chain->foo()->some()->foo(); // ok
it's ok
The problem here is that we establish a "convention". You need to pass __METHOD__ to the register function so after it replace the classname it will add only the method name in the array. So later, in the function where you need to verify if one or more functions are called before this, you need to use the method name as string i.e. $this->verify('foo');
Ofcourse you can play different scenarios without stripping and testing with strpos() or adding () after the methodname for easier recognition if you are verifying a method or smth else.
But at least it will save you from making for each method, different variable to fill i.e.
function foo() {
$this->_foo = true;
return $this;
}
function bar() {
$this->_bar = true;
return $this;
}
Forcing the caller to stick to a certain order of calls just as an end to itself is hardly useful at all. Supposedly what you're really interested in is to make sure the state of the object is valid when you call some() and throw an exception if it's not. In that case, yes, you would check certain indicators of your object's state and throw an exception when this state does not fulfil the requirements that some() may be called. As a concrete example:
$api = new SomeAPI;
$api->setUserID($id);
$api->setSecretKey($secret);
$api->call('something');
Here call() would check that the user id and access key has been set, otherwise it can't do its job. Whether these calls are chained or not is irrelevant and just a syntactic detail.
Alternatively, you could return certain objects of other (sub) classes from your methods which physically make it impossible to call certain methods on them if certain conditions haven't been met:
public function bar() {
if ($this->foo) {
return new SubFoo($this->foo);
} else {
return new SubBar;
}
}
This may be overly complicated though.
I have a Display object that handles HTML output of the script. It has a mode property, which defines many aspects of how the output is generated. There are several modes, and I will probably add more later. Each mode implies it's own parameters. For example, an author mode would imply an authorID. A search mode would imply a Search object as a parameter, which would contain query information. A comment mode would imply a postID and commentID parameters.
So, a mode has a name and some number of parameters, depending on the name.
I decided to create a Display_Mode object, which has two properties: name and parameters. But how do I assign parameters to names? So that if I have a comment mode, it would neccessarily mean that there are postID and commentID parameters?
My current solution is this:
class display_mode{
public $name;
public $params;
public function __construct($name)
{
$this->name = $name;
switch ($this->name){
case 'comment':
$this->params = array('postID', `commentID`);
break;
case 'author':
$this->params = array('authorID');
}
//etc..
}
}
This seems a bit messy. Is there a better way?
UPD: given answers led me to ask another question, concerning the whole design, which also provides context for this one.
You're better off abstracting the common functionality of the Display_Mode class into an abstract base class or interface and then defining each individual mode as a class that inherits from the base class (or implements the interface).
These specialised mode classes would then explicitly define the parameters they require in their constructors and/or methods, and would be responsible for producing the output that each "mode" requires.
It's difficult to give more specific advice than this without knowing exactly what your Display_Mode class is supposed to do, however.
The idea here is that you should avoid do-it-all classes in OOP, preferring small, self-contained classes each with a single purpose. By giving each mode its own class that can independently render its content, you're making it easy to change the way display modes work or add new ones. All you have to do is add a new class.
This is known as loose coupling.
The description is kinda confusing, but I would create an adapter for each possible "parameter" of Display. This adapter could provide single interface, independently of the the resource that you want to display.
$parameter = new UnknownPrameter;
$adapterFactory = new AdapterFactory;
$parameter = $adapterFactory->build( $parameter );
$display->present( $parameter );
Where AdapterFactory::build() create a wrapper for the specific type of parameter, that you supplied. The returned instance is a container for that parameter.
This approach would also prevent the computation from accumulating in the constructor, which would make the code harder to test/expand.
#Will Vousden already gave you the answer. This is a quick example of how to approach your problem.
abstract class DisplayMode {
protected $_params = array();
public function __construct(array $params) {
$this->_params = $params;
}
public function hasParameter($key) {
if (array_key_exists($key, $this->_params)) {
return true;
}
return false;
}
public function setParameters(array $params) {
$this->_params = $params;
return $this;
}
public function getParameters() {
return $this->_params;
}
}
class CommentMode extends DisplayMode {
public function getCommentId() {
if ($this->hasParameter('comment_id')) {
return $this->_params['comment_id'];
}
return null;
}
public function getPostId() {
if ($this->hasParameter('post_id')) {
return $this->_params['post_id'];
}
return null;
}
}
class AuthorMode extends DisplayMode {
public function getAuthorId() {
if ($this->hasParameter('author_id')) {
return $this->_params['author_id'];
}
return null;
}
}
$comment = new CommentMode(array('post_id' => 4, 'comment_id' => 2));
$author = new AuthorMode(array('author_id' => 3));
// example
print $comment->getCommentId() . ' - ' . $comment->getPostId() . ' - ' . $author->getAuthorId();
Since PHP has no notion of properties like C# what is the best way to expose certain attributes of a class? Is it recommended to have separate get and set functions or should the member variable be made public?
I am designing a class whose objects will be contained in another class. There should be a way to set/get properties of the object.
On the whole I would recommend exposing public variables on your PHP class, except where you need to perform a more complex action, in which case you would use getter and setter functions.
So where you would use this in C#
public string MyProp { get; set; }
I would recommend this in PHP
public $MyProp;
Using public attribute or private with getter/setter will both do the trick.
I will proceed like this :
If the attribute is critical, use a getter and setter like this :
class myClass
{
private $myAttr;
public function getmyAttr()
{
return $this->myAttr;
}
public function setmyAttr($attr)
{
//Do some verification on $attr
$this->myAttr = $attr;
}
}
If the attribute is less critical , you could simply set is visibility to public.
Because of the lack of strong type in php i will always prefer the private attribute with getter and setter. it let you ensure that the attribute is always what it should be (not "1" instead of 1 for example).
It depends, it is not very rare to make attributes public which are not very security sensitive. But if you do want to keep them private you could create something like this:
class withAttributes{
private $property;
public function getPrivateProperty{
return $this->property;
}
}
In the other class:
$object = new withAttributes();
$attribute = $object->getPrivateProperty();
Hope this helps
There's no idiomatic way built in the language, however you could try using the magic __get and __set methods to emulate something simillar.
Consider this pretty dumb example:
Class Foo {
private $bar;
private $baz;
public function __get($name) {
if (property_exists($this, $name)) {
if ($name == 'bar') {
return strtoupper($this->{$name});
} else {
return $this->{$name};
}
}
return null; // this is what php would do, consider throwning an exception instead
}
public function __set($name, $value) {
if (property_exists($this, $name)) {
if ($name == 'bar') {
$this->{$name} = strtolower($value);
} else {
$this->{$name} = $value;
}
}
// we just ignore this call, consider throwing exceptions, or you could make the class open to property addition in runtime too
}
}
$f = new Foo;
$f->bar = 'tickle me elmo';
print $f->bar; // prints uppercase
This way later on, if you decide to implement some read/write logic, you can hook it in the magic methods. From performance standpoint, these magic methods are slower than ordinary method calls, also arguably more surprising for the users of these classes than explicit getter/setter methods.
If you want to create something more like the built-in StdObject or basic array consider implementing the ArrayAccess interface for the [] syntax.
If I want to create a new object that needs certain informations like a product id or something like that but the input is bad how can I elegant manage such a case?
class Product
{
function __construct($id)
{
if(is_invalid_id($id))
{ return false; }
}
}
If I initialize it this way I still get an object (since return inside a constructor doesn't return anything). Another way would be to use exceptions which I then can catch but that's kinda unelegant. 3rd option is to use a static function which then checks the input and then returns the object.
class Product
{
static function init($id)
{
if(is_invalid_id($id))
{ return false; }
return new self($id);
}
private function __construct($id)
{
$this->id = $id;
}
}
$product = Product::init($productId);
The problem here is when I try to extend the class. Either I have to create a init() method for every class I extend (even if it is the exact same code) or return new self() always returns an instance of the parent class.
Throw an exception. Not sure why you consider it unelegant. Man, things were unelegant before exceptions (FALSE, -1, null)
For the problem with self:: you might be able to use late static binding (PHP5.3+):
<?php
class Product
{
static function init($id)
{
if(false)
{ return false; }
$s = get_called_class();
return new $s($id);
}
private function __construct($id)
{
$this->id = $id;
}
function getId()
{
return "Product-$this->id";
}
}
class Headphones extends Product
{
function getId()
{
return "Headphones-$this->id";
}
}
$c1 = Product::init(1);
$c2 = Headphones::init(1);
printf("c1 is %s, c2 is %s\n", $c1->getId(), $c2->getId());
// Prints: c1 is Product-1, c2 is Headphones-1
?>
Your third option is the Factory Pattern.
As you've noticed, the downside is that each class that needs this kind of check generally needs it's own factory method.
I'll give you a non-standard workaround that's universally frowned upon by purists: the hybrid constructor
And it's even more evil than it sounds, because it's actually just a wrapper procedure:
function Product($i) {
$prod = new Product($i);
return $prod->valid() ? $prod : new InvalidProduct();
}
class Product {
function __construct() { ... }
}
class InvalidProduct extends Product implements Stub { }
$new_prod = Product("oops123"); // what will it be?
It simply verifies the object instantantly. If there is something wrong, and now here comes the trick, return a specific stub or NULL object. It might implement a few of the interfaces, but generally cause no side-effects or print an error message once it's inevitable. This concept basically hinges on the viability of carrying a stub object around. It's sometimes more sensible to the application logic to have such a specialized instance than to use decorative test logic.
And then there's the second alternative: just bail with an exception.