The document discusses object-oriented programming concepts including objects, classes, instances, attributes, methods, interfaces, inheritance, and SOLID principles.
It begins by defining objects, classes, and instances in OOP. It provides PHP code examples to demonstrate classes, instantiating objects, and using methods and attributes. It then covers interfaces, inheritance, and polymorphism with additional PHP examples.
Finally, it discusses best practices for OOP with SOLID principles - the single responsibility, open/closed, Liskov substitution, interface segregation and dependency inversion principles. For each principle it provides an example of poor design, explains the principle, and shows how to improve the design to follow that principle.
3. Object
In computer science, an object is a location in memory having
a value and possibly referenced by an identifier.An object can
be a variable, a data structure, or a function.
Source : http://en.wikipedia.org
5. Class
In object-oriented programming, a class is an extensible
program-code-template for creating objects, providing initial
values for state and implementations of behavior.
Source : http://en.wikipedia.org
6. Class - PHP exemple
class Character {
private $firstName;
private $lastName;
public function __construct($firstName, $lastName) {
$this->firstName = $firstName;
$this->lastName = $lastName;
}
}
7. Instance
In object-oriented programming (OOP), an instance is a
specific realization of any object.The creation of a realized
instance is called instantiation.
Source : http://en.wikipedia.org
8. Instance - PHP exemple
$nedStark = new Character('Eddard', 'Stark');
$robertBaratheon = new Character('Robert', 'Baratheon');
9. Attribute & method
A class contains data field descriptions (or properties, fields,
data members, or attributes).
Source : http://en.wikipedia.org
A method in object-oriented programming (OOP) is a
procedure associated with an object class.
Source : http://en.wikipedia.org
10. Attribute & method - PHP exemple
class Character {
private $firstName;
private $lastName;
private $nickname;
public function __construct($firstName, $lastName, $nickname) {
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->nickname = $nickname;
}
public function getFullName(){
return $this->firstName . ' ' . $this->lastName;
}
public function getNickname(){
return $this->nickname;
}
}
$nedStark = new Character('Eddard', 'Stark', 'Ned');
echo $nedStark->getFullName(); // Eddard Stark
echo $nedStark->getNickname(); // Ned
11. Interface
In object-oriented languages, the term interface is often used
to define an abstract type that contains no data or code, but
defines behaviors as method signatures.A class having code
and data for all the methods corresponding to that interface is
said to implement that interface.
Source : http://en.wikipedia.org
12. Interface - PHP exemple
interface CharacterInterface {
public function getFullName();
}
class Human implements CharacterInterface {
private $firstName;
private $lastName;
public function __construct($firstName, $lastName) {…}
public function getFullName(){
return $this->firstName . ' ' . $this->lastName;
}
}
class Animal implements CharacterInterface {
private $name;
public function __construct($name) {…}
public function getFullName(){
return $this->name;
}
}
$nedStark = new Human('Eddard', 'Stark', 'Ned');
$nymeria = new Animal('Nymeria');
echo $nedStark->getFullName(); // Eddard Stark
echo $nymeria->getFullName(); // Nymeria
13. Inheritance
In object-oriented programming (OOP), inheritance is when an
object or class is based on another object or class, using the
same implementation (inheriting from a class) specifying
implementation to maintain the same behavior.
Source : http://en.wikipedia.org
14. Inheritance - PHP exemple
class Human {
private $firstName;
private $lastName;
public function __construct($firstName, $lastName) {
$this->firstName = $firstName;
$this->lastName = $lastName;
}
public function getFullName(){
return $this->firstName . ' ' . $this->lastName;
}
}
class King extends Human {
private $reignStart;
private $reignEnd;
public function setReign($reignStart, $reignEnd){
$this->reignStart = $reignStart;
$this->reignEnd = $reignEnd;
}
public function getReign(){
return $this->reignStart . " - " . $this->reignEnd;
}
}
$robertBaratheon = new King('Robert', 'Baratheon');
$robertBaratheon->setReign(283, 298);
echo $robertBaratheon->getFullName() . ' ( '.$robertBaratheon->getReign().' )';
// Robert Baratheon ( 283 - 298 )
21. Coupling ?
In software engineering, coupling is the manner and degree of
interdependence between software modules; a measure of
how closely connected two routines or modules are; the
strength of the relationships between modules.
Source : http://en.wikipedia.org
22. Et en claire ?
If making a change in one module in your
application requires you to change another
module, then coupling exists.
23. Exemple de couplage fort
class Location {
private $name;
private $type;
}
class Character {
private $firstName;
private $lastName;
private $location;
public function __construct($firstName, $lastName, $locationName, $locationType) {
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->location = new Location($locationName, $locationType);
}
public function getFullName(){
return $this->firstName . ' ' . $this->lastName;
}
}
$nedStark = new Character('Eddard', 'Stark', 'Winterfell', 'Castle');
24. Exemple de couplage faible
class Location {
private $name;
private $type;
}
class Character {
private $firstName;
private $lastName;
private $location;
public function __construct($firstName, $lastName, $location) {
$this->firstName = $firstName;
$this->lastName = $lastName;
$this->location = $location;
}
public function getFullName(){
return $this->firstName . ' ' . $this->lastName;
}
}
$winterfell = new Location($locationName, $locationType);
$nedStark = new Character('Eddard', 'Stark', $winterfell);
27. In my opinion, testing should not be hard! No, really.Whenever
you don't write unit tests because you don't have time, the
real issue is that your code is bad, but that is another story.
Source : http://williamdurand.fr
Untested and Untestable
32. Give all entities mentioned in the code (DB tables, DB tables’
fields, variables, classes, functions, etc.) meaningful, descriptive
names that make the code easily understood.The names
should be so self-explanatory that it eliminates the need for
comments in most cases.
Source : Michael Zuskin
Self-explanatory
38. Copy-and-paste programming is the production of highly
repetitive computer programming code, as by copy and paste
operations. It is primarily a pejorative term; those who use the
term are often implying a lack of programming competence.
Source : http://en.wikipedia.org
Copy And Paste Programming
39. « Every piece of knowledge must have
a single, unambiguous, authoritative
representation within a system. »
Don’t Repeat Yourself
Andy Hunt & Dave Thomas
40. The KISS principle states that most systems work best if they
are kept simple rather than made complicated; therefore
simplicity should be a key goal in design and unnecessary
complexity should be avoided.
Keep it simple, stupid
Source : http://en.wikipedia.org
45. The problem
class DataImporter
{
public function import($file)
{
$records = $this->loadFile($file);
$this->importData($records);
}
private function loadFile($file)
{
$records = array();
// transform CSV in $records
return $records;
}
private function importData(array $records)
{
// insert records in DB
}
}
46. The solution
class DataImporter
{
private $loader;
private $importer;
public function __construct($loader, $gateway)
{
$this->loader = $loader;
$this->gateway = $gateway;
}
public function import($file)
{
$records = $this->loader->load($file);
foreach ($records as $record) {
$this->gateway->insert($record);
}
}
}
47. Kill the god class !
A "God Class" is an object that
controls way too many other objects
in the system and has grown beyond
all logic to become The Class That
Does Everything.
50. The problem
class Circle {
public $radius;
// Constructor function
}
class Square {
public $length;
// Constructor function
}
class AreaCalculator {
protected $shapes;
// Constructor function
public function sum() {
foreach($this->shapes as $shape) {
if(is_a($shape, 'Square')) {
$area[] = pow($shape->length, 2);
} else if(is_a($shape, 'Circle')) {
$area[] = pi() * pow($shape->radius, 2);
}
}
return array_sum($area);
}
}
$shapes = array(
new Circle(2),
new Square(5),
new Square(6)
);
$areas = new AreaCalculator($shapes);
echo $areas->sum();
Source : https://scotch.io
51. The solution (1)
class Circle {
public $radius;
// Constructor function
public function area() {
return pi() * pow($this->radius, 2);
}
}
class Square {
public $length;
// Constructor function
public function area() {
return pow($this->length, 2);
}
}
class AreaCalculator {
protected $shapes;
// Constructor function
public function sum() {
foreach($this->shapes as $shape) {
$area[] = $shape->area();
}
return array_sum($area);
}
}
$shapes = array(
new Circle(2),
new Square(5),
new Square(6)
);
$areas = new AreaCalculator($shapes);
echo $areas->sum();
Source : https://scotch.io
52. The solution (2)
class AreaCalculator {
protected $shapes;
// Constructor function
public function sum() {
foreach($this->shapes as $shape) {
$area[] = $shape->area();
}
return array_sum($area);
}
}
$shapes = array(
new Circle(2),
new Square(5),
new Square(6)
);
$areas = new AreaCalculator($shapes);
echo $areas->sum();
interface ShapeInterface {
public function area();
}
class Circle implements ShapeInterface {
public $radius;
// Constructor function
public function area() {
return pi() * pow($this->radius, 2);
}
}
class Square implements ShapeInterface {
public $length;
// Constructor function
public function area() {
return pow($this->length, 2);
}
}
Source : https://scotch.io
55. Exemple
abstract class AbstractLoader implements FileLoader
{
public function load($file)
{
if (!file_exists($file)) {
throw new InvalidArgumentException(sprintf('%s does not exist.', $file));
}
return [];
}
}
class CsvFileLoader extends AbstractLoader
{
public function load($file)
{
$records = parent::load($file);
// Get records from file
return $records;
}
}
Source : http://afsy.fr
57. Interface Segregation
A client should never be forced to
implement an interface that it doesn’t
use or clients shouldn’t be forced to
depend on methods they do not use.
Robert C. Martin
58. Exemple
interface UrlGeneratorInterface
{
public function generate($name, $parameters = array());
}
interface UrlMatcherInterface
{
public function match($pathinfo);
}
interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface
{
public function getRouteCollection();
}
Source : http://afsy.fr
60. Dependency Inversion
Entities must depend on abstractions not
on concretions. It states that the high
level module must not depend on the
low level module, but they should
depend on abstractions.
Robert C. Martin
61. The problem
class DataImporter
{
private $loader;
private $gateway;
public function __construct(CsvFileLoader $loader, DataGateway $gateway)
{
$this->loader = $loader;
$this->gateway = $gateway;
}
}
Source : http://afsy.fr
Classes
62. The solution
Source : http://afsy.fr
class DataImporter
{
private $loader;
private $gateway;
public function __construct(FileLoader $loader, Gateway $gateway)
{
$this->loader = $loader;
$this->gateway = $gateway;
}
}
Interfaces