gpt4 book ai didi

PHP/OOP 方法覆盖 DRY 方式

转载 作者:可可西里 更新时间:2023-11-01 00:10:44 26 4
gpt4 key购买 nike

我很好奇是否有针对以下行为的“更好”设计:

<?php
class Foo {
public function foo() {
// Foo-specific foo stuff.
}
}

class Bar extends Foo {
public function foo() {
// Bar-specific foo stuff.
parent::foo();
}
}

class Baz extends Bar {
public function foo() {
// Baz-specific foo stuff.
parent::foo();
}
}

$boz = new Foo();
$boz->foo(); // should do the stuff in Foo::foo()

$biz = new Bar();
$biz->foo(); // should do the stuff in Bar::foo() and Foo::foo()

$buz = new Baz();
$buz->foo(); // should do the stuff in Baz::foo(), Bar::foo(), and Foo::foo()

// etc...

本质上,我有一个基类 Foo,它有一个方法 Foo::foo(),其中包含一些应该始终运行的通用代码。我还有各种继承自 Foo 的子类,每个子类都有自己的特定代码,这些代码也应该始终运行。

我在这里使用的设计使用 DRY 原则来确保 Foo::foo() 中的代码不会在 Bar::foo() 中重复> 和 Baz::foo()Bar::foo() 中的代码在 Baz::foo() 中没有重复> 等等。

这种设计的问题(?)是我依赖于子类在每种情况下总是显式调用 parent::foo(),以及扩展这些类的类来执行同理,以此类推。但是,(据我所知)没有办法实际执行此操作。

所以我的问题是 - 是否有更好的设计来实现相同的行为,或者是否有某种方式在父类/子类之间强制执行这种“契约”?

更新

有些人要求提供用例。多年来我在几个项目中遇到过这种范例,但由于 NDA 等原因无法给出真实世界的例子,所以这里有一个 super 基本的例子,可能有助于更好地说明这个问题:

<?php
// Vehicle
class Vehicle {
public function start() {
// Vehicle engines are on when you start them.
// Unless they belong to me, that is :-(
$this->setEngineStatus(Vehicle::ENGINE_ON);
}
}

// Vehicle > Automobile
class Automobile extends Vehicle {
public function start() {
// Automobile engines are on when you start them.
parent::start();

// Automobiles idle when you start them.
$this->setEngineRpm(Automobile::RPM_IDLE);
}
}

// Vehicle > Airplane
class Airplane extends Vehicle {
public function start() {
// Airplane engines are on when you start them.
parent::start();

// Airplanes also have radios that need to be turned on when started.
$this->setRadioStatus(Airplane::RADIO_ON);
}
}

// Vehicle > Automobile > Car
class Car extends Automobile {
public function start() {
// Cars engines are on and idle when you start them.
parent::start();

// Cars also have dashboard lights that turn on when started.
$this->setDashLightsStatus(Car::DASH_LIGHTS_ON);
}
}

// Vehicle > Airplane > Jet
class Jet extends Airplane {
public function start() {
// Jet engines and radios are on when you start them.
parent::start();

// Jets also arm their weapons when started.
$this->setWeaponsHot(true);
}
}

// Vehicle > Automobile > BobsSuperAwesomeCustomTruck
class BobsSuperAwesomeCustomTruck extends Automobile {
public function start() {
// Uh-oh... Bob didn't call parent::start() in his class, so his trucks
// don't work, with no errors or exceptions to help him figure out why.

// Bob's trucks also need to reset their pinball machine highscores when started.
$this->resetPinballScores();
}
}

最佳答案

我不认为这更好,但这是一种可能的方式。

class abstract Foo {
public function foo() {
// Foo-specific foo stuff.
$this->_foo();
}

// Might be abstract, might be an empty implementation
protected abstract function _foo();
}

class Bar extends Foo {
protected function _foo() {
// Bar-specific foo stuff.
}
}

就个人而言,我更喜欢你的方式,因为我认为它更具可读性。这也意味着 child 不必拥有自己的 foo() 实现。似乎更面向对象。但是,如果您需要每个子类都有自己添加的 foo() 实现,这可能会为您解决问题。

关于PHP/OOP 方法覆盖 DRY 方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7394986/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com