Encapsulation ในภาษา PHP

ในบทนี้ คุณจะได้เรียนรู้เกี่ยวกับ Encapsulation ในภาษา PHP ซึ่งเป็นคุณสมบัติที่สำคัญในการเขียนโปรแกรมเชิงวัตถุอย่างหนึ่ง และแนวคิดของการห่อหุ้มของข้อมูลในการประยุกต์ใช้จริงกับชีวิตประจำวัน

Encapsulation คืออะไร

Encapsulation คือคุณสมบัติในการปกปิดข้อมูลโดยเป็นกลไกลในการกำหนดการเข้าถึงข้อมูลในคลาสจากภายนอก เช่น ตัวแปรออบเจ็คที่สร้างจากคลาส ในการเขียนโปรแกรมเชิงวัตถุนั้น ตัวแปร เมธอดและโค้ดการทำงานภายในจะถูกห่อห้มไว้ในออบเจ็ค ในภาษาเขียนโปรแกรมเชิงวัตถุรวมทั้งภาษา PHP นั้นใช้ตัวกำหนดการเข้าถึง (Access specifier) ซึ่งเป็นคำสั่งในการกำหนดระดับการเข้าถึงข้อมูลภายในออบเจ็ค เช่น คำสั่ง public protected และ private

OOP Encapsulation การห่อหุ้มข้อมูล

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

Vending machine in OOP

Encapsulation จึงเป็นการพัฒนาโปรแกรมกำหนดการเข้าถึงขึ้นกับความจำเป็นและวัตถุประสงค์การใช้งาน ยกตัวอย่างเช่น ในหน้าปัดแสดงผลของเครื่องบิน จะแสดงข้อมูลทีจำเป็นสำหรับนักบินที่ต้องใข้ในการบินเท่านั้น ซึ่งในความจริงนั้นมีข้อมูลและการทำงานมากมากมายที่ถูกซ่อนอยู่ เบื้องหลังของหน้าปัดนั้น

Encapsulation ถูกนำไปใช้กับทุกการพัฒนาของการเขียนโปรแกรมเชิงวัตถุ ฟังก์ชันและเมธอดเป็นสิ่งหนึ่งที่ถูกห่อหุ้มการทำงานเอาไว้ เช่น เมื่อเราเรียกใช้คำสั่ง echo เราทราบว่าต้องใส่พารามิเตอร์เพื่อที่จะแสดงผล แต่โดยทั่วไปแล้วเราไม่ทราบถึงวิธีการทำงานในขั้นตอนการเชื่อมต่อกับฮาร์ดแวร์ Output buffer หรืออื่นๆ เพราะว่าทำงานเหล่านั้นถูกปกปิดและไม่จำเป็นสำหรับผู้ใช้งาน

ในบทนี้ คุณเรียนรู้เกี่ยวกับแนวคิดของ Encapsulation และตัวอย่างการใช้งานกับการเขียนโปรแกรมเชิงวัตถุเพื่อห่อหุ้มหรือปกปิดข้อมูลและการทำงาน ในภาษา PHP


บทความเกี่ยวกับ Encapsulation

Encapsulation ในภาษา C#

Encapsulation (คุณสมบัติการห่อหุ้ม) เป็นคุณสมบัติหนึ่งของการเขียนโปรแกรมเชิงวัตถุ ซึ่งเป็นการกำหนดความสามารถในการเข้าถึงสมาชิกภายในคลาส ไม่ว่าทั้งจากภายนอกและภ...

Encapsulation ในภาษา Java

ในบทเรียนนี้ เราจะพูดเกี่ยวกับ encapsulation (คุณสมบัติการห่อหุ้ม) ในภาษา Java และอธิบายแนวคิดในการนำไปใช้งานและพัฒนาโปรแกรม ในการเขียนโปรแกรมเชิงวัตถุ encapsul...

Encapsulation ในภาษา Visual Basic

ในบทนี้ คุณจะได้เรียนเกี่ยวกับคุณสมบัติการห่อหุ้มข้อมูลหรือ encapsulation ในภาษา Visual BasicEncapsulation คือคุณสมบัติในการห่อหุ้มข้อมูลในการเขียนโปรแกรมเชิงวั...