不变性是构建稳定应用程序的最重要的设计概念之一。基本原则规定,一旦写下一个状态,以后只能读取,没有修改的可能。如果我们需要改变状态,我们必须创建一个新的实例,用另一个对象替换整个对象。
因此,数据类型可以非常粗略地分为两大类。
可变的对象可以在内部改变。也就是说,它们提供的操作,当以不同的组合调用时,会使我们得到不同的结果。不变性试图阻止这种行为。
一个类是不可变的,恰恰是在实例创建后,实例数据不能以任何方式改变。
所以所有的数据都固定在构造函数中。所有标量数据类型也是自动不可变的。
用不可变的状态来设计应用程序,在执行操作的安全性方面提供了根本的优势。如果我们知道数据一旦写入,以后就不能被改变(突变),那么我们就可以,例如,非常可靠地进行调试,或者将应用程序分割成子函数,而不会有忘记任何中间状态的风险。
不变性的概念通常反对在对象/实体的属性中存储状态的原则,而是描述一种功能方法,即数据只是 "流 "过应用程序,例如像javascript那样。
从性能的角度来看,我们可以自动地说,不可变的对象可以无限期地被缓存,因为它们永远不会过时。
到目前为止,PHP中最常用的不可变对象是DateTimeImmutable
对象,它一旦创建就只能被格式化的方法调用。如果我们修改内部设置,该方法将返回一个新的实例。当使用一个使用所谓身份模式的ORM时,这个功能是至关重要的--例如,它允许我们保证当我们读取一个订单的创建日期时,它在应用程序中的所有地方都是一样的,参考的完整性不会被破坏。
一个可改变对象的具体例子。
$date = new DateTime('2021-05-14');$tomorrow = $date->modify('+1天');echo $date->format('Y-m-d'); // 2021-05-15echo $tomorrow->format('Y-m-d'); // 2021-05-15
因为modify()
方法只改变了DateTime
对象的内部状态,并返回了相同的实例,所以打印的是同一个日期。因此,不存在所谓的内部状态的**变异,这是面向对象编程的基本行为。更新变量也改变了原来的变量。
现在是一个不可改变的对象的例子。
$date = new DateTimeImmutable('2021-05-14');$tomorrow = $date->modify('+1天');echo $date->format('Y-m-d'); // 2021-05-14echo $tomorrow->format('Y-m-d'); // 2021-05-15
DateTimeImmutable
对象是不可变的,这意味着它的内部状态永远不会改变。在调用modify()
方法后,一个新的修改过的实例(也是不可变的)被存储在变量中。如果我们不把新值储存在变量中,以后就无法使用了。
原始价值从未被触及,并保持安全储存。
除非你有很好的理由让它变得可变,否则总是把一个类或函数写成不可变的。这将简化你未来的设计。
可变的类应该尽可能少的改变。我总是建议将不可变性的行为记录下来。
也许不变性的唯一缺点是,每次属性变化都必须创建一个新的实例,这对性能有轻微的影响。如果你的应用程序(像大多数应用程序一样)倾向于显示数据,而且改变数据的频率较低,那么以今天计算机的性能来说,这个缺点是相当不明显的。
什么不应该是不可改变的。
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | zh