PHP: Standards of class constructors preventing instantiation - php

Just a question on standards.
I've created a wrapper class for PHP session management, that helps automatically organize session data based on certain internal modules accessing it. It's designed as a singleton, using a getInstance() method to instantiate, since there will only be a single session at a given time. Also, this came as a benefit to me, as I am able to prevent instantiation of the session object in the (albeit probably limited) chance that session_start() fails. As for an example:
public static function getInstance(){
if(!self::$_instance || !session_id()){
if(session_start()){
self::$_instance = new self(session_id());
}else{
return;
}
}
return self::$_instance;
}
My question is; although the use of a gateway getInstance() method works naturally here for a few reasons, is it common/good practice to implement public static getInstance() or create() methods in classes to control object creation if the object is reliant on external conditions?
I just find myself sticking to a convention of providing getInstance() in the case of singletons, and create() in the case of multiple instance objects.
TL;DR: I keep using getInstance() and create() methods to control all object instantiation. Am I doing it wrong?
EDIT: Refining my question a bit; Aside from using getInstance() for singletons, is my constructor wrapping with create() methods serving less purpose and more leaning towards bad convention? Should I be throwing Exceptions from the true constructor, or continue returning false from a create()?

Singletons are generally considered "bad"; see this section here for a flame war on the topic.
That said, using factory methods or factory classes to create objects is generally considered good, so you're fine there :)
I personally use the symfony dependency injection component (can be installed in any project without using the symfony framework) to simplify dependency injection and avoid singletons where it seems appropriate.
I do still use some singletons, where it makes sense to me; loggers and factory objects, for example, seem to naturally be single to me, so I make them that way. The idea is that global functionality (e.g. a factory) is fine, but global state is bad, I believe.
With regards to your amended question on whether to throw an Exception or whether to return false from your create() call; it depends on whether your application can continue successfully without the created object if not. If, for example, you were creating a database connection that is necessary to create a page, then throw an Exception. If you're doing something less essential, return false and continue on your merry way :)

getInstance() is used ALL over the place in the Zend Framework, which is my goto for standards and conventions in code.
as for the create(), what about using the magic __construct method so that when you do new Blah() it calls the __construct method for that class?

You should user __construct method then using create method.
As __construct is called by itself you can do initialization and other things in constructor .
Another benefit is you can forget to call create() method and your object can be in inconsistent state

Related

why is it impossible to test a static method with mockery or anything else

I have read in laravel's facade documentation the following sentence:
Typically, it would not be possible to mock or stub a truly static
class method.
1) question 1: I'm trying to understand facade in laravel. As I guess, it's implemented because if we have classes, and they have big namespaces and big names and every time we want to use this class and we don't want to use new keyword and use statements, we use the facade which is an easier code and readable. I also think that laravel implemented facades because they wanted to write non-static functions in their classes so that they could be tested. After all of this, we use facades like static classes (because of readability and not using new and use), but in reality, it makes new instances.
Am I right?
2) If the above is right, can you provide me an example why it's not possible to test a static method as laravel docs said?
A facade does not solve the big namespaces problem you mentioned. Big namespaces are solved using aliases. You can declare them in your config/app.php and internally Laravel will use class_alias when you call them. This is how e.g. \Cache or \DB work.
A facade is basically a proxy class to a singleton object instance of another class (the facade itself ensures the instance is a singleton).
Typically to register a singleton in Laravel you:
Add app()->singleton(ABC::class) in your service provider
Access it via app()->make(ABC::class)->...
A facade basically takes care of that for you if you haven't already registered that class as a singleton.
Basically a facade is a way to proxy that singleton instance of another class.
Also it's generally not possible to mock or stub static methods however if you are using facades you can do \ABCFacade::swap($mockObject) and therefore your facades can be mocked.
It is also false that you cannot test a static method. You can absolutely test a static method. For example:
public testStaticMethod() {
$this->assertEquals(1, ABC::method()); // We tested a static method against a desired behaviour
}
What you usually can't do is mock a static method. Here's how you would typically mock something with PHPUnit:
public testWithDependency() {
$dependency = $this->getMockBuilder(Dependency::class)->getMock();
$dependency->expects($this->once())->method('dependantMethod')->willReturn(true);
$objectToTest = new ABC($dependency); //We're passing a fake dependency which behaves in an ideal way
$this->assertEquals(1, $objectToTest->methodToTest()); //Any calls to the dependency will call mock methods and not real ones
}
The problem arises when trying to mock a static method. As you can see mocking creates mock instances of a certain type. It can't mock the static members of that type because the mock object itself is not actually of that type.
However as I just found out the statement that it's not possible to mock or stub a static method is not entirely true. There's the AspectMock you can mock static methods or helper methods. This seems to work by intercepting all function calls via a custom autoloader.
This being said, just because you can doesn't mean it's good practice to use static methods, there's other issues to consider like e.g. you normally can't have static interfaces in most programming languages or you normally can't override static methods in most programming languages. Note the "in most programming languages" part here. In PHP it's entirely possible to override static methods with late static binding but that means you need to make a conscious decision about this when implementing the static method.
Another disadvantage is that a class of statics can't implement an interface because interfaces apply to object behaviours and not the static behaviour. Therefore you can't swap out one interface for another if you are using statics which is a major disadvantage.
In general the aversion to static methods is not because of testability but because if you are coding in OOP you are really limited if you are using statics.
Hopefully this will help clear up some confusion.

When should I use static methods?

I have a class that is containing 10 methods. I always need to use one of those methods. Now I want to know, which approach is better?
class cls{
public function func1(){}
public function func2(){}
.
.
public function func10(){}
}
$obj = new cls;
$data = $obj->func3(); // it is random, it can be anything (func1, or func9 or ...)
OR
class cls{
public static function func1(){}
public static function func2(){}
.
.
public static function func10(){}
}
cls::func3(); // it is random, it can be anything (func1, or func9 or ...)
It is an interesting subject. I'm gonna give you a design oriented answer.
In my opinion, you should never use a static class/function in a good OOP architecture.
When you use static, this is to call a function without an instance of the class. The main reason is often to represent a service class which should not be instantiated many times.
I will give you 3 solutions (from the worst to the best) to achieve that:
Static
A static class (with only static functions) prevent you from using many OOP features like inheritance, interface implementation. If you really think of what is a static function, it is a function namespaced by the name of its class. You already have namespaces in PHP, so why add another layer?
Another big disadvantage is that you cannot define clear dependencies with your static class and the classes using it which is a bad thing for maintenability and scalability of your application.
Singleton
A singleton is a way to force a class to have only one instance:
<?php
class Singleton {
// Unique instance.
private static $instance = null;
// Private constructor prevent you from instancing the class with "new".
private function __construct() {
}
// Method to get the unique instance.
public static function getInstance() {
// Create the instance if it does not exist.
if (!isset(self::$instance)) {
self::$instance = new Singleton();
}
// Return the unique instance.
return self::$instance;
}
}
It is a better way because you can use inheritance, interfaces and your method will be called on an instanciated object. This means you can define contracts and use low coupling with the classes using it. However some people consider the singleton as an anti pattern especially because if you want to have 2 or more instances of your class with different input properties (like the classic example of the connection to 2 different databases) you cannot without a big refactoring of all your code using the singleton.
Service
A service is an instance of a standard class. It is a way to rationalize your code. This kind of architecture is called SOA (service oriented architecture). I give you an example:
If you want to add a method to sell a product in a store to a consumer and you have classes Product, Store and Consumer. Where should you instantiate this method? I can guarantee that if you think it is more logical in one of these three class today it could be anything else tomorrow. This leads to lots of duplications and a difficulty to find where is the code you are looking for. Instead, you can use a service class like a SaleHandler for example which will know how to manipulate your data classes.
It is a good idea to use a framework helping you to inject them into each others (dependency injection) in order to use them at their full potential. In the PHP community, you have a nice example of implementation of this in Symfony for instance.
To sum up:
If you do not have a framework, singletons are certainly an option even if I personally prefer a simple file where I make manual dependency injection.
If you have a framework, use its dependency injection feature to do that kind of thing.
You should not use static method (in OOP). If you need a static method in one of your class, this means you can create a new singleton/service containing this method and inject it to the instance of classes needing it.
The answer depends on what those methods do. If you're using them to mutate the state of the object at hand, you need to use the instance method calls. If they're independent functionality, then you can use the static versions, but then I'd question why they're part of a class at all.
So, there is a very basic difference in static methods.
To use static functions, you don't need to initialise the class as an object. For example, Math.pow(), here .pow() (in Java; but the explanation still holds) is a static method.
The general rule is to make the helper methods static.
So, for example, if you have a Math class, you wouldn't want to fill the garbage collector with classes which just help other, more important, classes.
You can use it as dynamic initializers, if you please!
Let's say you have a class RSAEncryptionHelper, now you can generally initialize it without any parameters and this will generate an object with a key size of (say) 512 bits; but you also have an overloaded object constructor which gets all of the properties from other classes:
$a = new RSAEncryptionHelper::fromPrimeSet(...);
Within a PHP class you can use class/methods/attributes: Abstract, Static, Private, Public, etc ...
The best way is to know how to mix them all within a class depending on the need, I will give you a basic example:
Within the Person class, you have private and public methods, but you have a method called "get_nationality" so this is a function that you need somewhere else but you do not have the Person class installed yet, so this method you put it as STATIC in this way you can invoke the "get_nationality" method without installing any Person class, this makes your business model more optimal and in turn now resources in the CPU.
Static functions are also very useful but
I usually make traits when I have to create functions that are independently related to a class.
I don't know if this approach is better or not but most times I found it useful.
Just sharing my approach here so that I can learn more about its pros and cons.
You can think a factory. You will give some materials, it will give you same output. Then you should use static function.
class ProductDetails
{
public static function getRow($id, PDO $pdo): SingleProduct
{
// this function will return an Object.
}
}
I am not defining the Object here. Just where you need a Single Product you can simply do that ProductDetails::getRow(10, $pdo);

unit testing and Static methods

Reading up and picking up on unit testing, trying to make sense of the following post on that explains the hardships of static function calls.
I don't clearly understand this issue. I have always assumed static functions were a nice way of rounding up utility functions in a class. For example, I often use static functions calls to initialise, ie:
Init::loadConfig('settings.php');
Init::setErrorHandler(APP_MODE);
Init::loggingMode(APP_MODE);
// start loading app related objects ..
$app = new App();
// After reading the post, I now aim for this instead ...
$init = new Init();
$init->loadConfig('settings.php');
$init->loggingMode(APP_MODE);
// etc ...
But, the few dozen tests I had written for this class are the same. I changed nothing and they still all pass. Am I doing something wrong?
The author of the post states the following:
The basic issue with static methods is they are procedural code. I have no idea how to unit-test procedural code. Unit-testing assumes that I can instantiate a piece of my application in isolation. During the instantiation I wire the dependencies with mocks/friendlies which replace the real dependencies. With procedural programing there is nothing to “wire” since there are no objects, the code and data are separate.
Now, I understand from the post that static methods create dependencies, but don't grasp intuitively why one cannot test the return value of a static method just as easily as a regular method?
I will be avoiding static methods, but I would of liked having an idea of WHEN static methods are useful, if at all. It seems from this post static methods are just about as evil as global variables and should be avoided as much as possible.
Any additional information or links on the subject would be greatly appreciated.
Static methods themselves aren't harder to test than instance methods. The trouble arises when a method--static or otherwise--calls other static methods because you cannot isolate the method being tested. Here is a typical example method that can be difficult to test:
public function findUser($id) {
Assert::validIdentifier($id);
Log::debug("Looking for user $id"); // writes to a file
Database::connect(); // needs user, password, database info and a database
return Database::query(...); // needs a user table with data
}
What might you want to test with this method?
Passing anything other than a positive integer throws InvalidIdentifierException.
Database::query() receives the correct identifier.
A matching User is returned when found, null when not.
These requirements are simple, but you must also setup logging, connect to a database, load it with data, etc. The Database class should be solely responsible for testing that it can connect and query. The Log class should do the same for logging. findUser() should not have to deal with any of this, but it must because it depends on them.
If instead the method above made calls to instance methods on Database and Log instances, the test could pass in mock objects with scripted return values specific to the test at hand.
function testFindUserReturnsNullWhenNotFound() {
$log = $this->getMock('Log'); // ignore all logging calls
$database = $this->getMock('Database', array('connect', 'query');
$database->expects($this->once())->method('connect');
$database->expects($this->once())->method('query')
->with('<query string>', 5)
->will($this->returnValue(null));
$dao = new UserDao($log, $database);
self::assertNull($dao->findUser(5));
}
The above test will fail if findUser() neglects to call connect(), passes the wrong value for $id (5 above), or returns anything other than null. The beauty is that no database is involved, making the test quick and robust, meaning it won't fail for reasons unrelated to the test like network failure or bad sample data. It allows you to focus on what really matters: the functionality contained within findUser().
Sebastian Bergmann agrees with Misko Hevery and quotes him frequently:
Stubbing and Mocking Static Methods
Unit-Testing needs seams, seams is where we prevent the execution of normal code path and is how we achieve isolation of the class under test. Seams work through polymorphism, we override/implement class/interface and then wire the class under test differently in order to take control of the execution flow. With static methods there is nothing to override. Yes, static methods are easy to call, but if the static method calls another static method there is no way to override the called method dependency.
The main issue with static methods is that they introduce coupling, usually by hardcoding the dependency into your consuming code, making it difficult to replace them with stubs or mocks in your Unit-Tests. This violates the Open/Closed Principle and the Dependency Inversion Principle, two of the SOLID principles.
You are absolutely right that statics are considered harmful. Avoid them.
Check the links for additional information please.
Update: note that while statics are still considered harmful, the capability to stub and mock static methods has been removed as of PHPUnit 4.0
I do not see any problem when testing static methods (at least none that doesn't exists in non-static methods).
Mock objects are passed to classes under test using dependency injection.
Mock static methods can be passed to classes under test using a suitable autoloader or manipulating the include_path.
Late static binding deals with methods calling static methods in the same class.

Having issues understanding Dependency Injection

I'm building out a small project to try to teach myself as much of the fundamentals as possible, which for me means not using a prefabricated framework (As Jeff once put it, "Don't reinvent the wheel, unless you plan on learning more about wheels" [emphasis mine]) and following the principles of Test Driven Development.
In my quest, I recently ran into the concept of Dependency Injection, which appears essential to TDD. My problem is that I can't quite wrap my head around it. My understanding so far is that it more or less amounts to "have the caller pass the class/method any other classes it may need, rather than letting them create them themselves."
I have two example issues that I'm trying to resolve with DI. Am I on the right track with these refactorings?
Database Connection
I'm planning to just use a singleton to handle the database, as I'm currently not expecting to use multiple databases. Initially, my models were going to look something like this:
class Post {
private $id;
private $body;
public static function getPostById($id) {
$db = Database::getDB();
$db->query("SELECT...");
//etc.
return new Post($id, $body);
}
public function edit($newBody) {
$db = Database::getDB();
$db->query("UPDATE...");
//etc.
}
}
With DI, I think it would look more like this:
class Post {
private $db; // new member
private $id;
private $body;
public static function getPostById($id, $db) { // new parameter
$db->query("SELECT..."); // uses parameter
//etc.
return new Post($db, $id, $body);
}
public function edit($id, $newBody) {
$this->db->query("UPDATE..."); // uses member
//etc.
}
}
I can still use the singleton, with credentials specified in the application setup, but I just have to pass it from the controller (controllers being un-unit-testable anyway):
Post::getPostById(123, Database::getDB);
Models calling models
Take, for example, a post which has a view count. Since the logic to determine if a view is new isn't specific to the Post object, it was just going to be a static method on its own object. The Post object would then call it:
class Post {
//...
public function addView() {
if (PageView::registerView("post", $this->id) {
$db = Database::getDB();
$db->query("UPDATE..");
$this->viewCount++;
}
}
With DI, I think it looks more like this:
class Post {
private $db;
//...
public function addView($viewRegistry) {
if ($viewRegistry->registerView("post", $this->id, $this->db) {
$this->db->query("UPDATE..");
$this->viewCount++;
}
}
This changes the call from the controller to this:
$post->addView(new PageView());
Which means instantiating a new instance of a class that only has static methods, which smells bad to me (and I think is impossible in some languages, but doable here because PHP doesn't allow classes themselves to be static).
In this case we're only going one level deep, so having the controller instantiate everything seems workable (although the PageView class is getting its DB connection indirectly by way of the Post's member variable), but it seems like it could get unwieldy if you had to call a method that needed a class that needed the class that needed a class. I suppose that could just mean that's a code smell too though.
Am I on the right track with this, or have I completely misunderstood DI? Any criticisms and suggestions are greatly appreciated.
Yes. It looks like you have the right idea. You'll see that as you implement DI all your dependencies will float to the "top". Having everything at the top will make it easy to mock the necessary objects for testing.
Having a class that needs a class that needs a class is not a bad thing. What your describing there is your object graph. This is normal for DI. Lets take a House object as an example. It has a dependency on a Kitchen; the Kitchen has a dependency on a Sink; the Sink has a dependency on a Faucet and so on. The House's instantiation would look something like new House(new Kitchen(new Sink(new Faucet()))). This helps to enforce the Single Responsibility Principle. (As an aside you should do this instantiation work in something like a factory or builder to further enforce the Single Responsibility Principle.)
Misko Hevery has written extensively about DI. His blog is a great resource. He's also pointed out some of the common flaws (constructor does real work, digging into collaborators, brittle global state and singletons, and class does too much) with warning signs to spot them and ways to fix them. It's worth checking out sometime.
Dependency injection is about injecting. You need some solution to inject the external object.
The traditional approaches are:
constructor injection __construnctor($dependecy) {$this->_object = $dependency}
setter injection setObject($dependency) {$this->_object = $dependency}
gettter injection getObject() {return $this->_dependency} and oveloading this method eg. from stub or mock in the tests.
You may also mix all the above, depends what you need.
Avoid static calls. My personal rule is use static only when you call some functions, e.g. My::strpos() or when dealing with singletons or registry (which should be limited to minimum, because global state is evil).
You will rarely need static methods when your app has a good dependency container.
Take a look at the other dependency injection + [php] topics on SO.
Edit after comment:
The container
Different frameworks handle the container in different way. Generally this is an object, which holds the instances of objects you need, so you don't have to instantiate new object each time. You may register any object with such a container, and then access it anytime you need.
The container may instantiate all the resources you need at boot time, or lazy load the resource when accessed (better solution).
As an example, consider:
Zend Application Resource Plugins
Symfony Dependency Injection Container
Another great reference:
http://martinfowler.com/articles/injection.html
It's certainly going into the right direction but you should not stop there.
The point of DI is to remove strong couplings between classes to allow for easier substitution of single components. This will allow for better testability because you can substitute dependencies more easily with Mocks and Stubs. And once your code is tested, it is much easiert to change and maintain.
Consequently, you should also remove those other aspects in your code that create strong coupling smells as well, e.g. remove the static methods and the singleton and any other globals.
For some more information on that, please see
How is testing the registry pattern or singleton hard in PHP?
http://gooh.posterous.com/singletons-in-php
http://kore-nordmann.de/blog/0103_static_considered_harmful.html
http://fabien.potencier.org/article/11/what-is-dependency-injection
EDIT: with a couple of others answers suggesting to use a DI container, I feel it's necessary to stress that you do not need a DI container to do DI. The second blog post in the last link given above discusses this.
To answer your questions: yes, you are on the right track. To give you more details: this is one of the best posts I found related to DI:
http://www.potstuck.com/2009/01/08/php-dependency-injection
You will understand what a container is:
$book = Container::makeBook();
Regarding the second example: in your method addView I would try to avoid passing the object $viewRegistry, I would check the condition outside in the controller.

Refactoring a method having dependencies within the same object into something more testable (PHP)

I currently have a method within my class that has to call other methods, some in the same object and others from other objects.
class MyClass
{
public function myMethod()
{
$var1 = $this->otherMethod1();
$var2 = $this->otherMethod2();
$var3 = $this->otherMethod3();
$otherObject = new OtherClass();
$var4 = $otherObject->someMethod();
# some processing goes on with these 4 variables
# then the method returns something else
return $var5;
}
}
I'm new to the whole TDD game, but some of what I think I understood to be key premises to more testable code are composition, loose coupling, with some strategy for Dependency Injection/Inversion of Control.
How do I go about refactoring a method into something more testable in this particular situation?
Do I pass the $this object reference to the method as a parameter, so that I can easily mock/stub the collaborating methods? Is this recommended or is it going overboard?
class MyClass
{
public function myMethod($self, $other)
{
# $self == $this
$var1 = $self->otherMethod1();
$var2 = $self->otherMethod2();
$var3 = $self->otherMethod3();
$var4 = $other->someMethod();
# ...
return $var5;
}
}
Also, it is obvious to me that dependencies are a pretty big deal with TDD, as one has to think about how to inject a stub/mock to the said method for tests. Do most TDDers use DI/IoC as a primary strategy for public dependencies? at which point does it become exaggerated? can you give some pointers to do this efficiently?
These are some good questions... let me first say that I do not really know JS at all, but I am a unit tester and have dealt with these issues. I first want to point out that JsUnit exists if you are not using it.
I wouldn't worry too much about your method calling other methods within the same class... this is bound to happen. What worries me more is the creation of the other object, depending on how complicated it is.
For example, if you are instantiating a class that does all kinds of operations over the network, that is too heavy for a simple unit test. What you would prefer to do is mock out the dependency on that class so that you can have the object produce the result you would expect to receive from its operations on the network, without incurring the overhead of going on the network: network failures, time, etc...
Passing in the other object is a bit messy. What people typically do is have a factory method to instantiate the other object. The factory method can decide, based on whether or not you are testing (typically via a flag) whether or not to instantiate the real object or the mock. In fact, you may want to make the other object a member of you class, and within the constructor, call the factory, or make the decision right there whether or not to instantiate the mock or the real thing. Within the setup function or within your test cases you can set special conditions on the mock object so that it will return the proper value.
Also, just make sure you have tests for your other functions in the same class... I hope this helps!
Looks like the whole idea of this class is not quite correct. In TDD your are testing classes, but not methods. If a method has it own responsibility and provides it's own (separate testable) functionality it should be moved to a separate class. Otherwise it just breaks the whole OOP encapsulation thing. Particularly it breaks the Single Responsibility Principle.
In your case, I would extract the tested method into another class and injected $var1, $var2, $var3 and $other as dependencies. The $other should be mocked, as well any object which tested class depends on.
class TestMyClass extends MyTestFrameworkUnitTestBase{
function testMyClass()
{
$myClass = new MyClass();
$myClass->setVar1('asdf');
$myClass->setVar2(23);
$myClass->setVar3(78);
$otherMock = getMockForClassOther();
$myClass->setOther($otherMock);
$this->assertEquals('result', $myClass->myMethod());
}
}
Basic rule I use is: If I want to test something, I should make it a class. This is not always true in PHP though. But it works in PHP in 90% of cases. (Based on my experience)
I might be wrong, but I am under the impression that objects/classes should be black boxes to their clients, and so to their testing clients (encapsulating I think is the term I am looking for).
There's a few things you can do:
The best thing to do is mock, here's one such library: http://code.google.com/p/php-mock-function
It should let you mock out only the specific functions you want.
If that doesn't work, the next best thing is to provide the implementation of method2 as a method of an object within the MyClass class. I find this one of the easier methods if you can't mock methods directly:
class MyClass {
function __construct($method2Impl) {
$this->method2Impl = $method2Impl;
}
function method2() {
return $this->method2Imple->call();
}
}
Another option is to add an "under test" flag, so that the method behaves different. I don't recommend this either - eventually you'll have differing code paths and with their own bugs.
Another option would be to subclass and override the behaviors you need. I -really- don't suggest this since you'll end up customizing your overridden mock to the point that it'll have bugs itself :).
Finally, if you need to mock out a method because its too complicated, that can be a good sign to move it into its own object and use composition (essentially using the method2Impl technique i mentioned above).
Possibly, this is more a matter of single responsibility principle being violated, which is feeding into TDD issues.
That's a GOOD thing, that means TDD is exposing design flaws. Or so the story goes.
If those methods are not public, and are just you breaking apart you code into more digestable chunks, honestly, I wouldn't care.
If those methods are public, then you've got an issue. Following the rule, 'any public method of a class instance must be callable at any point'. That is to say, if you're requiring some sort of ordering of method calls, then it's time to break that class up.

Categories