Εφαρμογή Διακοινώνσεων στην Αντικειμενοστραφή Προγραμματισμό σε PHP
Λοιπόν, έχουμε ήδη διαπιστώσει ότι οι διακοινωνήσεις είναι ένας καλός τρόπος για να ελέγχουμε ότι όλες οι απαραίτητες μέθοδοι μιας κλάσης έχουν υλοποιηθεί.
Ας εξετάσουμε ένα ακόμη, πιο πρακτικό, παράδειγμα. Ας υποθέσουμε ότι έχουμε μια κλάση που θα αποθηκεύει έναν πίνακα αντικειμένων-σχημάτων:
<?php
class FiguresCollection
{
private $figures = []; // πίνακας για σχήματα
}
?>
Ας υλοποιήσουμε στην κλάση μας τη μέθοδο addFigure
για την προσθήκη αντικειμένων στη συλλογή:
<?php
class FiguresCollection
{
private $figures = [];
// Παράμετρος μεταδίδεται ένα αντικείμενο με σχήμα:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
Προφανώς, υπολογίζουμε ότι
η παράμετρος της μεθόδου addFigure θα
μεταδίδεται ένα αντικείμενο με σχήμα. Ωστόσο, δεν
υπάρχει κανένας έλεγχος για αυτό!
Ας χρησιμοποιήσουμε μια υπόδειξη για τύπους και
ας ορίσουμε ρητά τον τύπο των αντικειμένων ως Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
Ας δούμε τι κάναμε.
Αν το Figure ήταν μια πραγματικά υπάρχουσα
κλάση, τότε στην παράμετρο της μεθόδου θα μπορούσαμε
να μεταδώσουμε αντικείμενα αυτής της κλάσης, καθώς και
των κληρονομούμενων κλάσεών της.
Σε εμάς, ωστόσο, το Figure είναι μια διεπαφή.
Σε αυτήν την περίπτωση, η υπόδειξη σημαίνει ότι
ως παράμετρος της μεθόδου μπορούν να μεταδοθούν μόνο
αντικείμενα κλάσης που υλοποιούν τη διεπαφή μας.
Ας προσπαθήσουμε να δημιουργήσουμε ένα αντικείμενο της κλάσης μας και να προσθέσουμε σε αυτό σχήματα:
<?php
$figuresCollection = new FiguresCollection;
// Ας προσθέσουμε μερικά τετράγωνα:
$figuresCollection->add(new Quadrate(2));
$figuresCollection->add(new Quadrate(3));
// Ας προσθέσουμε μερικά ορθογώνια:
$figuresCollection->add(new Rectangle(2, 3));
$figuresCollection->add(new Rectangle(3, 4));
?>
Η προσπάθεια να προσθέσετε ένα αντικείμενο οποιασδήποτε άλλης κλάσης θα οδηγήσει σε σφάλμα:
<?php
$figuresCollection = new FiguresCollection;
class Test {}; // κάποια άλλη κλάση
$figuresCollection->add(new Test); // θα δώσει σφάλμα
?>
Τι μας δίνει στην πράξη αυτός ο έλεγχος:
εφόσον όλα τα σχήματα που προστίθενται στη συλλογή,
υλοποιούν τη διεπαφή Figure, μπορούμε
να είμαστε βέβαιοι ότι κάθε ένα από αυτά θα έχει τη μέθοδο
getSquare και τη μέθοδο
getPerimeter.
Πιθανόν στο μέλλον εκτός από το τετράγωνο και το ορθογώνιο
να εμφανιστεί, για παράδειγμα, και ένα τρίγωνο. Σε
αυτήν την περίπτωση και το τρίγωνο θα έχει
μεθόδους getSquare και
getPerimeter.
Στην πράξη αυτό μας δίνει το εξής: μπορούμε
στην κλάση FiguresCollection να φτιάξουμε,
για παράδειγμα, τη μέθοδο getTotalSquare, που βρίσκει
το συνολικό εμβαδόν των σχημάτων της συλλογής. Σε αυτή τη μέθοδο
θα διασχίζουμε με βρόχο τον πίνακα των σχημάτων και
για κάθε σχήμα να καλούμε τη
μέθοδο getSquare.
Εφόσον κάθε σχήμα υλοποιεί τη διεπαφή
Figure, μπορούμε να είμαστε 100%
βέβαιοι ότι κάθε σχήμα θα έχει
αυτή τη μέθοδο getSquare.
Λοιπόν, εδώ είναι η υλοποίηση της μεθόδου:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
// Ας βρούμε το συνολικό εμβαδόν:
public function getTotalSquare()
{
$sum = 0;
foreach ($this->figures as $figure) {
$sum += $figure->getSquare(); // χρησιμοποιούμε τη μέθοδο getSquare
}
return $sum;
}
}
?>
Χωρίς να κοιτάτε τον κώδικά μου, υλοποιήστε την ίδια
κλάση FiguresCollection.
Προσθέστε στην κλάση FiguresCollection
τη μέθοδο getTotalPerimeter για την εύρεση
της συνολικής περιμέτρου όλων των σχημάτων.