Monday, October 28, 2019
Friday, October 25, 2019
Javascript : basic
getData(a => {
getMoreData(a,b => {
getMoreData(b,c => {
getMoreData(c,d => {
getMoreData(d,e => {
console.log(e);
});
});
});
});
});
getData()
.then(a => getMoreData(a))
.then(b => getMoreData(b))
.then(c => getMoreData(c))
.then(d => getMoreData(d))
.then(e => getMoreData(e));
getData()
.then(getMoreData)
.then(getMoreData)
.then(getMoreData)
.then(getMoreData)
.then(console.log());
(
async () => {
const a = await getData();
const b = await getMoreData(b)
const c = await getMoreData(c)
const d = await getMoreData(d)
const e = await getMoreData(e)
console.log(e);
})();
(
async () => {
try{
const a = await getData();
const b = await getMoreData(b)
const c = await getMoreData(c)
const d = await getMoreData(d)
const e = await getMoreData(e)
console.log(e);
}
catch(me){
//if you can
}
})();
Tuesday, October 1, 2019
OOP : Dependency Injection in PHP
This is what Wikipedia has to say about Dependency Injection:
In software engineering, dependency injection is a software design pattern that implements inversion of control for software libraries. Caller delegates to an external framework the control flow of discovering and importing a service or software module specified or "injected" by the caller.
In simple terms, Dependency Injection is a design pattern that helps avoid hard-coded dependencies for some piece of code or software.
The dependencies can be changed at run time as well as compile time. We can use Dependency Injection to write modular, testable and maintainable code:
- Modular: The Dependency Injection helps create completely self-sufficient classes or modules
- Testable: It helps write testable code easily eg unit tests for example
- Maintainable: Since each class becomes modular, it becomes easier to manage it
The Problem
We have dependencies almost always in our code. Consider the following procedural example which is pretty common:
function getUsers() {
global $database;
return $database->getAll('users');
}
Here the function
getUsers
has dependency on the $database
variable (tight coupling). It has some of these problems:- The function
getUsers
needs a working connection to some database . Whether there is successful connection to database or not is the fate ofgetUsers
function - The
$database
comes from outer scope so chances are it might be overwritten by some other library or code in the same scope in which case function may fail
Of course you could have used the
try-catch
constructs but it still doesn't solve the second problem.
Let's consider another example for a class:
class User
{
private $database = null;
public function __construct() {
$this->database = new database('host', 'user', 'pass', 'dbname');
}
public function getUsers() {
return $this->database->getAll('users');
}
}
$user = new User();
$user->getUsers();
This code again has these problems:
- The class
User
has implicit dependency on the specificdatabase
. All dependencies should always be explicit not implicit. This defeats Dependency inversion principle - If we wanted to change database credentials, we need to edit the
User
class which is not good; every class should be completely modular or black box. If we need to operate further on it, we should actually use its public properties and methods instead of editing it again and again. This defeats Open/closed principle - Let's assume right now class is using MySQL as database. What if we wanted to use some other type of database ? You will have to modify it.
- The
User
class does not necessarily need to know about database connection, it should be confined to its own functionality only. So writing database connection code inUser
class doesn't make it modular. This defeats the Single responsibility principle. Think of this analogy: A cat knows how tomeow
and a dog knows how towoof
; you cannot mix them or expect dog to saymeow
. Just like real world, each object of a class should be responsible for its own specific task. - It would become harder to write unit tests for the
User
class because we are instantiating the database class inside its constructor so it would be impossible to write unit tests for theUser
class without also testing the database class.
Enter Dependency Injection!
Let's see how we can easily take care of above issues by using Dependency Injection. The Dependency Injection is nothing but injecting a dependency explicitly. Let's re-write above class:
class User
{
private $database = null;
public function __construct(Database $database) {
$this->database = $database;
}
public function getUsers() {
return $this->database->getAll('users');
}
}
$database = new Database('host', 'user', 'pass', 'dbname');
$user = new User($database);
$user->getUsers();
And there you have much better code, thanks to Dependency Injection principle. Notice that instead of hard-coding database dependency:
$this->database = new database('host', 'user', 'pass', 'dbname');
We are now injecting it into the constructor, that's it:
public function __construct(Database $database)
Notice also how we are passing database instance now:
$database = new Database('host', 'user', 'pass', 'dbname');
$user = new User($database);
$user->getUsers();
It follows Hollywood Principle, which states: "Don’t call us, we’ll call you."
Let's see if this explicit dependency injection now solves problems we mentioned above.
The class User has implicit dependency on the specific database . All dependencies should always be explicit not implicit. This defeats Dependency inversion principle
We have already made database dependency explicit by requiring it into the constructor of the
User
class:public function __construct(Database $database)
Here we are taking advantage of type hinting by specifying type of object we are expecting which is
Database
although it wasn't necessary but it is always a good idea to type hint when you can.If we wanted to change database credentials, we need to edit the User class which is not good; every class should be completely modular or black box. If we need to operate further on it, we should actually use its public properties and methods instead of editing it again and again. This defeats Open/closed principle
The
User
class now does not need to worry about how database is connected. All it expects is Database
instance. We no more need to edit User
class for it's dependency, we have just provided it with what it needed.Let's assume right now class is using MySQL as database. What if we wanted to use some other type of database ? You will have to modify it.
Again, the
User
class doesn't need to know which type of database is used. For the Database
, we could now create different adapters for different types of database and pass to User
class. For example, we could create an interface
that would enforce common methods for all different types of database classes that must be implement by them. For our example, we pretend that interface would enforce to have a getUser()
method requirement in different types of database classes.The User class does not necessarily need to know about database connection, it should be confined to its own functionality only. So writing database connection code in User class doesn't make it modular. This defeats the Single responsibility principle.
Of course
User
class now doesn't know how database was connected. It just needs a valid connected Database
instance.It would become harder to write unit tests for the User class because we are instantiating the database class inside its constructor so it would be impossible to write unit tests for the User class without also testing the database class.
If you have wrote unit tests, you know now it will be a breeze to write tests for the
User
class using something like Mockery or similar to create mock object for the Database
.Different Ways of Injecting Dependencies
Now that we have seen how useful Dependency Injection is, let's see different ways of injecting dependencies. There are three ways you can inject dependencies:
- Constructor Injection
- Setter Injection
- Interface Injection
Constructor Injection
We have already seen example of Constructor Injection in above example. Constructor injection is useful when:
- A dependency is required and class can't work without it. By using constructor injection. we make sure all its required dependencies are passed.
- Since constructor is called only at the time of instantiating a class, we can make sure that its dependencies cant be changed during the life time of the object.
Constructor injection suffer from one problem though:
- Since constructor has dependencies, it becomes rather difficult to extend/override it in child classes.
Setter Injection
Unlike Constructor injection which makes it required to have its dependencies passed, setter injection can be used to have optional dependencies. Let's pretend that our
User
class doesn't require Database
instance but uses optionally for certain tasks. In this case, you would use a setter method to inject the Database
into the User
class something like:class User
{
private $database = null;
public function setDatabase(Database $database) {
$this->database = $database;
}
public function getUsers() {
return $this->database->getAll('users');
}
}
$database = new Database('host', 'user', 'pass', 'dbname');
$user = new User();
$user->setDatabase($database);
$user->getUsers();
As you can see, here we have used
setDatabase()
setter function to inject Database
dependency into the User
class. If we needed some other dependency, we could have created one more setter method and injected in the similar fashion.
So Setter Injection is useful when:
- A class needs optional dependencies so it can set itself up with default values or add additional functionality it needs.
Notice that you could also inject dependency via public property for a class. So instead of using setter function$user->setDatabase($database);
, you could also do$user->database = new Database(...);
Interface Injection
In this type of injection, an interface enforces the dependencies for any classes that implement it, for example:
interface someInterface {
function getUsers(Database $database);
}
Now any class that needs to implement
someInterface
must provide Database
dependency in their getUsers()
methods.The Problem Again
So for we have seen very contrived example of injecting dependency into a simple class but in real world applications, a class might have many dependencies. It isn't all that easy to manage all those dependencies because you need to KNOW which dependencies are required by a certain class and HOW they need to be instantiated. Let's take example of setter injection:
class User
{
private $database = null;
public function setDatabase(Database $database) {
$this->database = $database;
}
public function getUsers() {
return $this->database->getAll('users');
}
}
Since dependencies in this case are optional, we could have mistakenly written this code to get users:
$user = new User();
$user->getUsers();
Since we didn't know
getUsers()
method is actually dependent on Database
class, this would have given error. You could have found that out only by going to code of User
class and then realizing there is setDatabase()
method that must be called before using the getUsers()
method. Or let's assume further that before using database, we needed to set some type of configuration for the User
class like:$user = new User();
$user->setConfig($configArray);
Then again we needed to remember specific order of method calls:
$user = new User();
$user->setConfig($configArray);
$user->setDatabase($database);
So you must remember order of method calls, you can't use database if you don't setup configuration first, so you can't do:
$user = new User();
$user->setDatabase($database);
$user->setConfig($configArray);
This is example for setter injection but even with constructor injection if there are many dependencies, it becomes harder to manage all of those manually and you could easily and mistakenly create more than one instances of dependencies throughout your code which would result in high memory usage.
You might wonder dependency injection sounded like good thing to have but these problems are not worth it. Well that's not true because there is solution to all of these problems discussed next :)
Solution - Dependency Injection Container
Of course it would be difficult to manage dependencies manually; this is why you need a Dependency Injection Container. A Dependency Injection Container is something that handles dependencies for your class(es) automatically. If you have worked with Laravel or Symfony, you know that their components have dependencies on on other classes. How do they manage all of those dependencies ? Yes they use some sort of Dependency Injection Container.
There are quite some dependency injection containers out there for PHP that can be used for this purpose or you can also write your own. Each container might have bit of different syntax but they perform the same thing under the hood.
So in conclusion, you must always remove hard-coded dependencies from your code and inject them using Dependency Injection instead for its benefits and then have all the injected dependencies managed automatically for you by using some dependency injection container
OOP : Abstract Class vs Interface
I found this picture that tells the difference between
abstract class
and interface
:
Let's see each comparison practically so we know what it means.
Interface support multiple inheritance | Abstract class does not support multiple inheritance
It means you can extend an
interface
with one or more (hence multiple inheritance) interfaces like:interface Interface_A { }
interface Interface_B { }
interface Interface_C { }
interface MyInterface extends Interface_A, Interface_B, Interface_C { }
As can be seen, we are extending
MyInterface
with three other interfaces Interface_A
, Interface_A
and Interface_C
.
Let's now try to extend an
abstract class
:class Class_A { }
abstract class MyAbstractClass extends Class_A { }
No problem there, you CAN extend an abstract class with exactly one class but if you try to add one more:
class Class_A { }
class Class_B { }
abstract class MyAbstractClass extends Class_A, Class_B { }
This time PHP would give you strange error without telling you what you are doing wrong:
Parse error: syntax error, unexpected ',', expecting '{'
I wish PHP would have given message somewhat like (hope PHP gives smarter error messages in future versions):
Fatal Error: You cannot extend an abstract class with more than one classes
Interface does'n Contains Data Member | Abstract class contains Data Member
By data members, it means class properties or variables. So you cannot add data members to an interface:
interface MyInterface {
public $foo = null;
}
So in an interface, only method stubs can be provided.
You can add data members to an abstract class though, this is valid code of course:
abstract class MyAbstractClass {
public $foo = null;
}
Interface does'n contains Constructors | Abstract class contains Constructors
It sounds like this point applies to may be other languages but in PHP an interface CAN have an empty constructor shell:
interface MyInterface {
public function __construct();
}
Like other languages, PHP shouldn't have allowed having a constructor inside an interface. But anyways, it doesn't make much sense here and should be avoided anyway.
On the other hand, an abstract class can contain constructor method:
abstract class MyAbstractClass {
abstract public function __construct();
}
Here constructor is said to be
abstract
and therefore expends child classes to complement for it. However, you can also have common initialization code in constructor of an abstract class too in which case, you would need to remove the abstract
keyword and provide the body for it:abstract class MyAbstractClass {
public function __construct() {
// initialization code
};
}
An interface Contains only incomplete member (signature of member) | An abstract class Contains both incomplete (abstract) and complete member
This simply means an interface can only contain method stubs not their implementation. This is pretty same as second point in the image above. This is why in methods of an interface, they don't have bodies marked with
{ }
braces. So an interface is completely empty shell that enforces some rules that child classes must implement and that's it.
Abstract classes can have both; empty method definitions as well as full method implementation. Generally empty method stubs are prefixed with
abstract
keyword so that child classes must provide their implementation details. But an abstract class can also contain full method implementation inside it which are generally used for common piece of functionality that each child class may need. For example:abstract class Animal {
// child classes must implement this
abstract function prey();
public function run() {
echo 'I am running!';
}
}
class Dog extends Animal {
public function prey() {
echo 'I killed the cat !';
}
}
class Cat extends Animal {
public function prey() {
echo 'I killed the rat !';
}
}
$dog = new Dog();
$cat = new Cat();
$dog->prey(); // I killed the cat !
$cat->prey(); // I killed the rat !
$dog->run(); // I am running!
$cat->run(); // I am running!
In above code, we can see that
Animal
class has one abstract
method called prey
because each child class (animal) have their own ways of finding prey and a full implemented method called run
because all animals can run, this doesn't need to be defined in each of child classes. So here run
method is fully implemented and represents common data that needs to be shared across child classes.
Notice that other than common fully implemented methods inside an abstract class, you can also have common data members eg variables that need to be shared across child classes.
An interface cannot have access modifiers by default everything is assumed as public | An abstract class can contain access modifiers for the subs, functions, properties
By access modifiers, we mean ability to change scoping by using keywords like
public
, private
and protected
. We cannot use these for interfaces but we can use them for everything in abstract classes.Members of interface can not be Static | Only Complete Member of abstract class can be Static
This is again possible in PHP (as of now with PHP 5.4) unlike other languages, so you CAN do:
interface MyInterface {
static function foo();
}
Notice the addition of keyword
static
to mark it as static method.
For abstract class, you can have static members as well as those methods that are implemented in the abstract class:
abstract class MyAbstractClass {
public static $foo = null;
public static function foo() {}
}
But you cannot have a method to be both
static
and abstract
, so you cannot do this, which is common across the languages:abstract class MyAbstractClass {
public static $foo = null;
abstract static function foo() {} // error
}
In conclusion, interface and abstract classes are completely different from each other, you cannot interchange them or use one as alternative over the other. Interfaces are completely empty shells that expect child classes to implement everything for them. On the other hand, abstract class can not only contain common piece of information by implementing inside them but also expect child classes to fill in the remaining gaps.
Subscribe to:
Posts (Atom)
-
Composer is a major part of the Laravel MVC Framework, but it also exists without Laravel. In fact you could use it in any project. This a...
-
How to Answer Technical Questions Like a Pro Answering technical interview questions is all about showing off your problem-solving skills an...
-
Vuetify is a popular UI framework for Vue apps. In this article, we’ll look at how to work with the Vuetify framework. Color Picker Inputs W...