Encapsulation ในภาษา PHP
ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับ Encapsulation ในภาษา PHP ซึ่งเป็นคุณสมบัติที่สำคัญในการเขียนโปรแกรมเชิงวัตถุอย่างหนึ่ง และแนวคิดของการห่อหุ้มของข้อมูลในการประยุกต์ใช้จริงกับชีวิตประจำวัน
Encapsulation คืออะไร
Encapsulation คือคุณสมบัติในการปกปิดข้อมูลโดยเป็นกลไกลในการกำหนดการเข้าถึงข้อมูลในคลาสจากภายนอก เช่น ตัวแปรออบเจ็คที่สร้างจากคลาส ในการเขียนโปรแกรมเชิงวัตถุนั้น ตัวแปร เมธอดและโค้ดการทำงานภายในจะถูกห่อห้มไว้ในออบเจ็ค ในภาษาเขียนโปรแกรมเชิงวัตถุรวมทั้งภาษา PHP นั้นใช้ตัวกำหนดการเข้าถึง (Access specifier) ซึ่งเป็นคำสั่งในการกำหนดระดับการเข้าถึงข้อมูลภายในออบเจ็ค เช่น คำสั่ง public protected และ private
Encapsulation สามารถพบได้ในชีวิตประจำวัน ยกตัวอย่างเช่น Vending machine คุณต้องใส่จำนวนเงิน และเลือกเครื่องดื่มของคุณในการซื้อ แนวคิดของ Encapsulation คือขั้นตอนการทำงานนั้นถูกซ่อนไว้จากผู้ใช้ เช่น การนับเงินหรือทอนเงินของเครื่อง การควบคุมเพื่อที่จะให้ได้เครื่องดื่มที่คุณต้องการออกมา หรือจำนวนเครื่องดื่มทั้งหมดที่เหลืออยู่ ซึ่งข้อมูลและการทำงานนี้ถูกปกปิดสำหรับผู้ใช้ที่จะเห็น และในขณะเดียวกันก็มีการทำงานที่ผู้ใช้สามารถทำได้คือ การหยอดเหรียญและการเลือกเครื่องดื่ม ซึ่งเป็นช่องทางในการติดต่อและทำงานกับข้อมูลภายใน
Access specifiers
Access specifiers คือคำสั่งในการกำหนดการเข้าถึงที่เราใช้กับการประกาศตัวแปรภายในคลาสหรือเรียกอีกอย่างหนึงว่า Property Visibility ในภาษา PHP มี Access specifier อยู่ด้วยกัน 3 แบบดังนี้
- public - ตัวแปรหรือเมธอดสามารถเข้าถึงได้จากทุกที่ในโปรแกรม
- protected - ตัวแปรหรือเมธอดสามารถเข้าถึงได้จากในคลาสเดียวกันหรือคลาสที่ได้รับการสืบทอด (Inheritance)
- private - ตัวแปรหรือเมธอดสามารถเข้าถึงได้จากในคลาสเดียวเท่านั้น
ซึ่ง Access specifiers เหล่านี้เป็นสิ่งที่กำหนดสำหรับการเข้าถึงข้อมูลภายในออบเจ็ค คำสั่ง private
และ protected
เป็นคำสั่งในการปิดปิดข้อมูล เพราะว่าเราไม่สามารถเข้าถึงสมาชิกประเภทนี้จากภายนอกของออบเจ็คได้ และ public
เป็นตัวแทนในการติดต่อหรือการทำงานระหว่างภายในและภายนอกออบเจ็ค
ตัวอย่างของ Encapsulation กับ Vending machine
ต่อไปเราจะยกตัวอย่างการเขียนโปรแกรมด้วยแนวคิดของ Encapsulation ในภาษา PHP กับการทำงานของ Vending machine
<?php
class VendingMachine {
private $machineMoney = 0;
private $your_money = 0;
private $beverage = [
"A" => ["price" => 6, "name" => "Coke"],
"B" => ["price" => 6, "name" => "Pepsi"],
"C" => ["price" => 8, "name" => "Wine"],
"D" => ["price" => 10, "name" => "Beer"]
];
function __construct() {
$this->welcome();
}
private function welcome() {
echo "WELCOME TO VENDING MACHINE\n";
echo "What do you want to drink?\n";
echo "Code\tName\tPrice\n";
foreach ($this->beverage as $key => $value) {
echo "$key\t" . $value["name"] . "\t" . $value["price"] . " USD\n";
}
echo "\n";
}
public function insertCoin($coin) {
$this->yourMoney+= $coin;
echo "Inserted $coin USD, you have $this->yourMoneyUSD.\n";
}
public function getBeverage($code) {
if (array_key_exists($code, $this->beverage)) {
$bev = $this->beverage[$code];
if ($this->pay($bev["price"])) {
$this->sendBeverage($bev["name"],
$this->getChange());
} else {
echo "Not enough money, please insert more.\n";
}
} else
echo "You have entered invalid beverage code.\n";
}
private function pay($price) {
if ($this->yourMoney>= $price) {
$this->yourMoney-= $price;
$this->machineMoney += $price;
return true;
} else {
return false;
}
}
private function getChange() {
$change = $this->yourMoney;
$this->yourMoney= 0;
return $change;
}
private function sendBeverage($name, $change) {
echo "Please take your beverage ($name) and $changeUSD back.\n";
echo "Thank you.\n\n";
}
}
$vender = new VendingMachine();
$vender->insertCoin(5);
$vender->insertCoin(5);
$vender->getBeverage("C");
$vender->insertCoin(4);
$vender->getBeverage("A");
$vender->insertCoin(2);
$vender->getBeverage("A");
?>
ในตัวอย่าง เป็นโปรแกรมในการจำลองการทำงานของ Vending machine ในภาษา PHP โดยโปรแกรมจะมีการให้ผู้ใช้ใส่เงินเข้าไปในเครื่องและเลือกเครื่องดื่มที่ต้องการ ซึ่งการทำงานทั้งหมดถูกกำหนดไว้ในคลาส VendingMachine
นั่นหมายความว่าทุกๆ ภายในคลาสทั้งตัวแปรและเมธอดนั้นถูกปกปิดจากออบเจ็คภายนอก (Encapsulated)
private $machineMoney = 0;
private $yourMoney = 0;
private $beverage = [
"A" => ["price" => 6, "name" => "Coke"],
"B" => ["price" => 6, "name" => "Pepsi"],
"C" => ["price" => 8, "name" => "Wine"],
"D" => ["price" => 10, "name" => "Beer"]
];
ในคลาสมีตัวแปรสามตัวคือ $machineMoney
เป็นตัวแปรในการเก็บจำนวนของ Vending machine $yourMoney
เป็นตัวแปรในการเก็บจำนวนเงินที่ผู้ใช้ใส่เข้ามา และ $beverage
เป็นตัวแปรเก็บข้อมูลของเครื่องดื่ม โดยมีรหัสของเครื่องดื่มเป็น Key ของอาเรย์
ต่อมาเป็นการประกาศฟังก์ชันในการทำงานของ Vending machine
private function welcome() {
echo "WELCOME TO VENDING MACHINE\n";
echo "What do you want to drink?\n";
echo "Code\tName\tPrice\n";
foreach ($this->beverage as $key => $value) {
echo "$key\t" . $value["name"] . "\t" . $value["price"] . " USD\n";
}
echo "\n";
}
เมธอด welcome()
เป็นเมธอดในการแสดงข้อความต้นรับในตอนที่ออบเจ็คถูกสร้าง เมธอดนี้ถูกเรียกโดย Constructor และแสดงรายละเอียดของเครื่องดื่มที่สามารถชื้อได้
public function insertCoin($coin) {
$this->yourMoney+= $coin;
echo "Inserted $coin USD, you have $this->yourMoneyUSD.\n";
}
เมธอด insertCoin()
เป็นเมธอดในการใส่เหรียญเข้าไปในเครื่อง มันเป็นเมธอดในการติดต่อกับภายนอกของคลาส เราได้กำหนดระดบการเข้าถึงของเมธอดนี้เป็น public
public function getBeverage($code)
{
if (array_key_exists($code, $this->beverage)) {
$bev = $this->beverage[$code];
if ($this->pay($bev["price"])) {
$this->sendBeverage($bev["name"],
$this->getChange());
} else {
echo "Not enough money, please insert more.\n";
}
} else
echo "You have entered invalid beverage code.\n";
}
เมธอด getBeverage()
เป็นเมธอดในการติดต่อกับภายนอกคลาส (ผู้ใช้) เช่นเดียวกัน ซึงเราได้กำหนดระดับการเข้าถึงเป็น public
เมธอดทำการตรวจสอบเครื่องดื่มที่มีอยู่ ทำการจ่ายเงิน และทำการส่งเครื่องดื่มและเงินทอนกลับไปให้กับผู้ใช้
ทั้งเมธอด insertCoin()
และ getBeverage()
เป็นเมธอดในการติดต่อกับผู้ใช้จากภายนอก เช่น คุณไม่สามารถที่จะเข้าไปวางเงินหรือหยิบเครื่องดื่มออกมาโดยตรงได้ เพราะว่ามันไม่มองเห็นได้โดยคุณจากภายนอก สิ่งเดียวที่คุณทำได้คือการยอดเหรียญและเลือกเครื่องดื่มเพื่อที่จะได้มันมา และการทำงานต่างๆ จะเกิดขึ้นอัตโนมัติภายในคลาส ดังนั้นสองเมธอดนี้ถูกกำหนดเป็น public
เพราะมันใช้เชื่อมต่อกับผู้ใช้ (ภายนอกคลาส)
private function pay($price) {
if ($this->yourMoney>= $price) {
$this->yourMoney-= $price;
$this->machineMoney += $price;
return true;
} else {
return false;
}
}
เมธอด pay()
เป็นเมธอดในการจัดการเครื่องการจ่ายเงิน และคำนวณเงินที่เหลือของผู้ใช้ เมธอดนี้มีระดับการเข้าถึงเป็น private
เพราะว่ามันเป็นการทำงานเบื้องหลังที่ถูกเรียกภายในคลาส และไม่สามารถเข้าถึงได้จากภานนอก
เมธอด getChange()
เป็นเมธอดในการคำนวณเงินที่ต้องทอน และเมธอด sendBeverage()
เป็นเมธอดในการส่งเครื่องดื่มและเงินทอดกลับไปยังผู้ซื้อและการซื้อถือเป็นการสำเร็จ เมธอดเหล่านี้เป็นการทำงานภายใน ดังนั้นไม่มันสามารถเข้าถึงจากภายนอกได้
$vender = new VendingMachine();
$vender->insertCoin(5);
$vender->insertCoin(5);
$vender->getBeverage("C");
$vender->insertCoin(4);
$vender->getBeverage("A");
$vender->insertCoin(2);
$vender->getBeverage("A");
กลับมายังเรือง Encapsulation ของเรา เราได้สร้างตัวแปรออบเจ็ค $vender
ซึ่งออบเจ็คนี้หมายถึง Vending machine ที่ผู้ใช้สามารถมีปฏิสัมพันธ์ได้ ซึ่งในบริบทของผู้ใช้พวกเขาสามารถเข้าถึงได้เพียง เมธอด insertCoin()
และเมธอด getBeverage()
สำหรับสิ่งที่เขาต้องการ
ถึงแม้ว่าเมธอดหรือตัวแปรอื่นๆ นั้นไม่สามารถเข้าถึงได้ แต่มันก็ไม่สำคัญกับสิ่งที่เขาต้องการเพราะเมธอดเหล่านั้นทำงานอยู่เบื้องหลังเพื่อให้งานหลักสำเร็จ ดังนั้นสามาชิกที่เป็น private
นั้นจึงถูกซ่อนอย่างสมบูรณ์จากภายนอก ซึ่งมันจะถูกเรียกใช้จากเมธอดที่เป็น public
แทน
Inserted 5 USD, you have 5 USD.
Inserted 5 USD, you have 10 USD.
Please take your beverage (Wine) and 2 USD back.
Thank you.
Inserted 4 USD, you have 4 USD.
Money not enough, please insert more.
Inserted 2 USD, you have 6 USD.
Please take your beverage (Coke) and 0 USD back.
Thank you.
นี่เป็นการทำงานของโปรแกรม Vending machine
Encapsulation จึงเป็นการพัฒนาโปรแกรมกำหนดการเข้าถึงขึ้นกับความจำเป็นและวัตถุประสงค์การใช้งาน ยกตัวอย่างเช่น ในหน้าปัดแสดงผลของเครื่องบิน จะแสดงข้อมูลทีจำเป็นสำหรับนักบินที่ต้องใข้ในการบินเท่านั้น ซึ่งในความจริงนั้นมีข้อมูลและการทำงานมากมากมายที่ถูกซ่อนอยู่ เบื้องหลังของหน้าปัดนั้น
Encapsulation ถูกนำไปใช้กับทุกการพัฒนาของการเขียนโปรแกรมเชิงวัตถุ ฟังก์ชันและเมธอดเป็นสิ่งหนึ่งที่ถูกห่อหุ้มการทำงานเอาไว้ เช่น เมื่อเราเรียกใช้คำสั่ง echo
เราทราบว่าต้องใส่พารามิเตอร์เพื่อที่จะแสดงผล แต่โดยทั่วไปแล้วเราไม่ทราบถึงวิธีการทำงานในขั้นตอนการเชื่อมต่อกับฮาร์ดแวร์ Output buffer หรืออื่นๆ เพราะว่าทำงานเหล่านั้นถูกปกปิดและไม่จำเป็นสำหรับผู้ใช้งาน
ในบทนี้ คุณเรียนรู้เกี่ยวกับแนวคิดของ Encapsulation และตัวอย่างการใช้งานกับการเขียนโปรแกรมเชิงวัตถุเพื่อห่อหุ้มหรือปกปิดข้อมูลและการทำงาน ในภาษา PHP