封装集合
重构动机
使用面向对象的开发者常犯这样的一个错误:在封装集合时,只对集合变量的访问进行封装,但依然让取值函数返回集合本身,这使得集合的成员变量可以直接被修改,而封装它的类则全然不知。
为避免这种情况,通常在在类上提供一些修改集合的办法——通常是”add()”和”remove()”。
重构前
setStudents()对整个学生集合操作。
<?php
namespace app\controller;
class Student
{
/**
* 存放学生座位号和姓名的集合
*/
private $students = [];
/**
* @return null
*/
public function getStudents ()
{
return $this->students;
}
/**
* @param null $students
*/
public function setStudents ($students): void
{
$this->students = $students;
}
}
重构后
重构后,添加和移除学生信息只针对集合中的某些数据,不操作整个集合。
<?php
namespace app\controller;
class Student
{
/**
* 存放学生座位号和姓名的集合
*/
private $students = [];
/**
* 获取学生姓名
*
* @param $seatNumber int 座位号
* @return bool|string
*/
public function getStudent ($seatNumber)
{
return isset($this->students[$seatNumber]) ?? "";
}
/**
* 获取整个集合
*
* @return array
*/
public function getAllStudents ()
{
return $this->students;
}
/**
* 添加学生
*
* @param $students array 学生和座位
*/
public function addStudents ($students): void
{
$this->students += $students;
}
/**
* 移除学生
*
* @param $students array 学生座位号
*/
public function removeStudents ($students)
{
foreach ($students as $k) {
unset($this->students[$k]);
}
}
}
测试:
public function test ()
{
$student = new Student();
$studentList = [
1 => "Tom",
2 => "Jam"
];
// 外部直接操作整个集合
$student->addStudents($studentList);
$list1 = $student->getAllStudents();
print_r($list1);
$student->addStudents([3 => "Mark"]);
$list2 = $student->getAllStudents();
print_r($list2);
$student->removeStudents([2, 3]);
$list3 = $student->getAllStudents();
print_r($list3);
}