特质或对象注入到分离的对象中,这会改变注入对象的状态

时间:2018-08-29 20:37:10

标签: php oop

在以下情况下,对多重继承使用哪个更正确?第二种方法是否正确遵循SOLID原理?还是可以使用任何常见的设计模式代替?

这是简化的概念代码。许多类都需要扩展Image类,例如BicycleImage,BusImage。其中一些需要addNoise(),但不是每个都需要。另外,还需要更多的“状态改变”类,例如SharpenEdges,incrementIntesity等。并非每个子类都使用。

基类:

<?php

abstract class Image
{
    private $pixels;

    public function setPixel(int $x, int $y, int $intensity): void
    {
        $this->pixels[$x][$y] = $intensity;
    }

    public function saveImage(): void {}
}

特质方法:

trait RandomNoiseTrait
{
    public function addNoise(): void
    {
        $this->setPixel(mt_rand(1, 100), mt_rand(1, 100), mt_rand(1, 100));
    }
}

class CarImage extends Image
{
    use RandomNoiseTrait;

    public function drawCar(): void {}
}

$carImage = new CarImage();
$carImage->drawCar();
$carImage->addNoise();
$carImage->saveImage();

将对象注入到单独的对象中,这会更改注入对象的状态:

class CarImage extends Image
{
    public function drawCar(): void {}
}

class RandomNoise
{
    private $image;

    public function __construct(Image $image)
    {
        $this->image = $image;
    }

    public function addNoise(): void
    {
        $this->image->setPixel(mt_rand(1, 100), mt_rand(1, 100), mt_rand(1, 100));
    }
}

$carImage = new CarImage();
$carImage->drawCar();

$noise = new RandomNoise($carImage);
$noise->addNoise();

$carImage->saveImage();

1 个答案:

答案 0 :(得分:0)

您的问题主要基于观点,因为通常有许多方法可以解决给定的体系结构或逻辑问题。

在这种情况下,根据您提供的信息,我很可能会选择类似Strategy设计模式的内容。实际上,这与您在问题中所建议的并不太相似。

关于您的问题的这种设计模式的示例可能是:

namespace Image;

use Image\Manipulation\Manipulation;

abstract class Image
{
    protected $pixels = [];


    public function setPixel(int $x, int $y, int $intensity): self
    {
        $this->pixels[$x][$y] = $intensity;

        return $this;
    }

    public function manipulate(Manipulation $manipulation): self
    {
        $manipulation->setImage($this)->manipulate();

        return $this;
    }

    abstract public function draw(): string;

    public function save(): bool
    {
        return true;
    }
}


namespace Image\Manipulation;

use Image\Image;

abstract class Manipulation
{
    protected $image;


    public function setImage(Image &$image): self
    {
        $this->image = $image;

        return $this;
    }

    abstract public function manipulate();
}


namespace Image\Manipulation;

class Noise extends Manipulation
{
    public function manipulate()
    {
        $this->image->setPixel(mt_rand(1, 100), mt_rand(1, 100), mt_rand(1, 100));
    }
}

它的用法是:

$image = new Image\CarImage;
$noise = new Image\Manipulation\Noise;

$image->draw();
$image->manipulate($noise)->draw();