面向对象七大设计原则:
单一原则:一个类只用来负责一个功能模块,比如支付类,只允许有支付类存储
<?php
# 单一职责原则 即一个类只用来做当前项目中惟一的方法
class SingleResponsibility
{
public function __construct()
{
echo "我是支付类,我只负责支付";
}
public function Play()
{
echo "开始支付";
}
public function Checkplay()
{
echo "检测是否支付成功";
}
}
$singlie = new SingleResponsibility();
echo "<br>";
echo $singlie->play();
?>
个人理解:在编写代码的时候,最好是一个类只负责一个功能模块,但如果有一些例外的,比如上传照片类,我们可以将它整合,变成上传文件类,文件 包括图片,视频,音频等,所以最优,最少的解决问题的办法是最有效的。
开闭原则:即一个类应该对修改关闭,对扩展开启。
<?php
# 定义课程名称类
interface Icource
{
# 获取课程名称
public function getName();
# 获取课程价格
public function getPrice();
# 获取老师名称
public function getTeacher();
# 打折接口
public function discount();
}
# 实现英语类
class English implements Icource
{
public $name;
public $price;
public $teacher;
public $discount;
public function __construct(string $name,float $price,string $teacher,float $discount)
{
$this->name = $name;
$this->price = $price;
$this->teacher = $teacher;
$this->discount = $discount;
}
# 获取课程名称
public function getName():string
{
return $this->name;
}
# 获取课程价格
public function getPrice():float
{
return $this->price * $this->discount();
}
# 获取老师名称
public function getTeacher():string
{
return $this->teacher;
}
# 如果类需要打折的话
public function discount():float
{
return $this->discount;
}
}
$english = new English("英语",36.5,"陌生老师",0.36);
echo $english->getPrice();
?>
个人理解,开闭原则,定义好接口,如果有需要更改的方法,那么最好不要在改接口的方法,而是在继承他的类进行修改。
依赖倒置原则:高层模块不应该依赖底层模块,二者都应该依赖抽象,抽象不应该依赖细节,细节应该依赖抽象。
<?php
# 定义共同接口类
interface Icource
{
# 定义公共方法
public function content();
}
# 定义中文类继承父类,并且完成content方法
class Chinese implements Icource
{
public function content()
{
echo "开始学习中文课程";
}
}
class English implements Icource
{
public function content()
{
echo "开始学习英语课程";
}
}
# 实现类
class Mosheng
{
# 定义变量接受该类的信息
public function study(Icource $icource)
{
$icource->content();
}
}
$mosheng = new Mosheng();
$mosheng->study(new Chinese());
echo "\n";
$mosheng->study(new English());
?>
个人理解:当方法编写完成后,尽量少修改方法,将方法提供到Mosheng类中,只需要将对象传递到该类中,由于都继承了Icource类,所以可以都具有content方法,低耦合,高内聚。
接口隔离原则: 一个类对另一个类的依赖应该建立在最小的接口上,通俗的讲就是需要什么提供什么,不需要什么不提供。
<?php
# 接口隔离原则
interface Ieat
{
public function eat();
}
interface Ispreak
{
public function spreak();
}
interface Isky
{
public function sky();
}
# 定义鸟类
class brild implements Ieat,Ispreak,Isky
{
public function eat()
{
echo "小鸟会吃东西";
}
public function spreak()
{
echo "小鸟会叫";
}
public function sky()
{
echo "小鸟会飞";
}
}
class Dogs implements Ieat,Ispreak
{
public function eat()
{
echo "小狗要吃饭";
}
public function spreak()
{
echo "小狗:汪汪汪";
}
}
$brild = new brild();
echo $brild->eat();
echo "\n";
$dogs = new Dogs();
echo $dogs->eat();
?>
个人理解:一个接口有一个对应的自己所需要的信息,比如小鸟会飞,小狗不会,但是可以吧eat和spreak共同定义一个接口,也就是说接口定义一定要是大家都具备的,负责就设置成多个接口,避免,因为图省事,然后继承这类之后,并不实行。
迪米特法则:一个对象应该对其他对象保持最少的理解。
<?php
# 迪米特法则
class Student
{
public $id;
public $name;
public function Stu(int $id,string $name)
{
$this->id = $id;
$this->name = $name;
}
}
class Teacher
{
public function call(Monitor $monitor)
{
return $monitor->getsize();
}
}
class Monitor
{
public function getsize()
{
$arr = [];
$stundent = new Student();
for($i = 0;$i < 10;$i++){
$arr[] = [$stundent->Stu($i + 1,"name".$i)];
}
return "班级人数".count($arr);
}
}
$teacher = new Teacher();
echo $teacher->call(new Monitor());
?>
个人理解:迪米特法则,一个类尽可能的不要和其他类有关联,其中成员变量,成员方法,都是类的直接朋友,但是类中的局部变量,不是类的直接朋友,所以如果需要实现迪米特法则,应该需要将类中的方法提取到零一个类中,而不再当前类完成方法的处理
合成/聚合复用原则:如果新对象的某些功能在别的已经创建好的对象中已经存在,那么应该尽量使用别的对象提供的功能,使之成为新对象的一部分,而不要在重新创建。
<?php
// 合成/聚合复用原则
class Person
{
public function talk(string $name):string
{
return $name . "说的话 \n";
}
public function walk(string $name):string
{
return $name . "move \n";
}
}
class Teacher extends Person
{
}
$teacher = new Teacher();
echo $teacher->talk('老师');
echo $teacher->walk('老师');
class Strdent extends Person
{
}
$strdent = new Strdent();
echo $strdent->talk('学生');
echo $strdent->walk('学生');
?>
个人理解:父类如果有这个方法那么就尽量使用公共的方法,不要再去重写相同的方法
里氏代换原则:所有引用基类的地方必须能透明地使用其子类对象。强调的是设计和实现要依赖于抽象而非具体,子类只能去扩展基类,而不是隐藏或者覆盖基类。
包函4层含义:
- 子类可以实现父类的抽象方法,但是不能重写父类非抽象的方法。
- 子类中可以增加自己特有的方法。
- 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更加宽松。
- 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类方法更严格。
<?php
class Calculate
{
public function func1(int $a,int $b):int
{
return $a - $b;
}
}
class Other extends Calculate
{
public function func1(int $a,int $b):int
{
return $a + $b;
}
public function func2(int $a,int $b):int
{
return $this->func1($a,$b) + 100;
}
}
$o = new Other();
echo "\n 100-50=" . $o->func1(100, 50); //100-50=150
echo "\n 100-80=" . $o->func1(100, 80); //100-80=180
echo "\n 100+20+100=" . $o->func2(100, 20); //100+20+100=220
?>
个人理解:尽量不要修改该父类的重名方法,这样会导致方法定义的不明确性。
参考网址:https://www.jianshu.com/p/d7ded306787c?tdsourcetag=s_pctim_aiomsg