การนำอินเทอร์เฟซไปใช้ในการเขียนโปรแกรมเชิงวัตถุใน PHP
สรุปแล้ว เราได้ทราบมาแล้วว่าอินเทอร์เฟซเป็นวิธีที่ดี ในการควบคุมให้มั่นใจว่าเมธอดที่จำเป็นทั้งหมดของคลาส ได้รับการนำไปใช้งาน
เรามาดูอีกตัวอย่างหนึ่งที่ใช้ได้จริงมากขึ้น สมมติว่าเรามีคลาสที่ใช้เก็บอาร์เรย์ของอ็อบเจกต์รูปทรง:
<?php
class FiguresCollection
{
private $figures = []; // อาร์เรย์สำหรับรูปทรง
}
?>
มาimplementเมธอด addFigure
ในคลาสของเราเพื่อเพิ่มอ็อบเจกต์ลงในคอลเลกชัน:
<?php
class FiguresCollection
{
private $figures = [];
// ส่งผ่านอ็อบเจกต์ของรูปทรงเป็นพารามิเตอร์:
public function addFigure($figure)
{
$this->figures[] = $figure;
}
}
?>
เห็นได้ชัดว่าเราคาดหวังว่าพารามิเตอร์ของเมธอด addFigure จะ
เป็นอ็อบเจกต์ของรูปทรงที่ถูกส่งผ่านเข้ามา แต่ว่า
ไม่มีอะไรควบคุมเรื่องนี้เลย!
มาใช้type hintและ
ระบุประเภทของอ็อบเจกต์อย่างชัดเจนว่าเป็น Figure:
<?php
class FiguresCollection
{
private $figures = [];
public function addFigure(Figure $figure)
{
$this->figures[] = $figure;
}
}
?>
มาทำความเข้าใจกับสิ่งที่เราได้ทำไป
ถ้า Figure เป็นคลาสที่มีอยู่จริง
เราก็จะสามารถส่งอ็อบเจกต์ของคลาสนี้และ
คลาสลูกของมันเข้าไปในพารามิเตอร์ของเมธอดได้
แต่สำหรับเรา Figure นั้นคืออินเทอร์เฟซ
ในกรณีนี้ type hint หมายความว่า
พารามิเตอร์ของเมธอดจะรับได้เฉพาะ
อ็อบเจกต์ของคลาสที่implementอินเทอร์เฟซของเรา
มาลองสร้างอ็อบเจกต์ของคลาสเรา และเพิ่มรูปทรงเข้าไป:
<?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); // จะเกิดข้อผิดพลาด
?>
การควบคุมแบบนี้ให้อะไรกับเราจริงๆ:
เนื่องจากรูปทรงทั้งหมดที่ถูกเพิ่มลงในคอลเลกชัน
ต่างimplementอินเทอร์เฟซ Figure เราสามารถ
มั่นใจได้ว่าแต่ละอันจะมีเมธอด
getSquare และเมธอด
getPerimeter
ในอนาคตอาจจะมีสามเหลี่ยมเพิ่มขึ้นมา
นอกเหนือจากสี่เหลี่ยมจัตุรัสและสี่เหลี่ยมผืนผ้า
ในกรณีนี้ สามเหลี่ยมก็จะมี
เมธอด getSquare และ
getPerimeter เช่นกัน
ในทางปฏิบัติสิ่งนี้ทำให้เกิดสิ่งต่อไปนี้: เราสามารถ
ในคลาส FiguresCollection สร้าง
เช่น เมธอด getTotalSquare เพื่อหา
พื้นที่ทั้งหมดของรูปทรงในคอลเลกชัน ในเมธอดนี้
เราจะวนลูปผ่านอาร์เรย์ของรูปทรงและ
เรียกใช้
เมธอด getSquare ในแต่ละรูปทรง
เนื่องจากแต่ละรูปทรงimplementอินเทอร์เฟซ
Figure เราจึงมั่นใจได้ถึง 100%
ว่าแต่ละรูปทรงจะมี
เมธอด getSquare นี้
สรุป นี่คือการimplementเมธอด:
<?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;
}
}
?>
โดยไม่แอบดูโค้ดของฉัน ลองimplement
คลาส FiguresCollection แบบเดียวกันดู
เพิ่มเมธอด getTotalPerimeter ลงในคลาส FiguresCollection
เพื่อหา
ความยาวรอบรูปรวมของรูปทรงทั้งหมด