可继承数组的设计模式?

时间:2012-11-16 02:50:43

标签: php design-patterns inheritance

给出以下类结构:

class Foo {
    protected static $_things = ['thing'];
}

class Bar extends Foo {
    protected static $_things = [
        'thing', 'other-thing'
    ];
}

class Baz extends Bar {
    protected static $_things = [
        'thing', 'other-thing', 'something-else'
    ];
}

class Quux extends Baz {
    // Note the lack of "other-thing"
    protected static $_things = [
        'thing', 'something-else', 'one-more'
    ];
}

重构这个并保持数组元素更干的最佳方法是什么?例如,“thing”元素只应定义一次(在Foo中),“other-thing”元素只应定义一次(在Bar中),依此类推。

实际上,这个数组非常大,有时最多可以有4或5级继承,每个都需要以某种特殊的方式“修改”这个数组,无论是添加还是删除元素。

我一直在考虑初始化方法的想法,这些方法会进行适当的修改,但是想先看看是否有更好的方法。

3 个答案:

答案 0 :(得分:2)

我能想到的最简单的解决方案(严重基于单例模式)。

我认为没有任何编译时间的方法可以满足您的需求。

<?php
class A {
    private static $a = [1, 2, 3];
    public static function getA() {
        return self::$a;
    }
}

class B extends A {
    private static $a = null;
    public static function getA() {
        if (self::$a === null)
            self::$a = array_merge(A::getA(), [4, 5, 6]);
        return self::$a;
    }
}

echo join(',', B::getA()) . "\n";

答案 1 :(得分:0)

判断不完全了解用例有点难,但继承似乎是错误的方法。 无论如何,您需要分离数据的存储方式和访问方式,即将数据结构与数据模型分开。

最佳解决方案是创建一个单独的列表类,并在多个客户端中使用它。例如类似的东西:

class SomeList{
    private $_things = ['thing'];
    function mergeItems( $items ){
        //merge the $this->_things and $items arrays uniquely
        //...
    }
}

class Foo{
    private $list;

    function __construct( $list ){
        $this->list = $list;
        $this->list->mergeItems( ['thing', 'other-thing'] );
    }
}

你永远不应该在静态属性中存储状态

答案 2 :(得分:-1)

也许这样的事情会起作用:

class Foo {
    protected static $_things = ['thing'];
}

class Bar extends Foo {
    protected static $_things = array_merge($_things, ['other-thing']);
}

//and so on...