封装集合

未匹配的标注

重构动机

使用面向对象的开发者常犯这样的一个错误:在封装集合时,只对集合变量的访问进行封装,但依然让取值函数返回集合本身,这使得集合的成员变量可以直接被修改,而封装它的类则全然不知。
为避免这种情况,通常在在类上提供一些修改集合的办法——通常是”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);
    }

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 查看所有版本


暂无话题~