-2

我在某个过程中收到一个对象,这个对象需要弄清楚它的配色方案。例如,我有一个这样存储的着色方案:

class FirstScheme {
    public static $COLORS = array('1' => 'green', '2' => 'red', ...);
}
class SecondScheme {
    public static $COLORS = array('1' => 'red', '2' => 'green', ...);
}

我事先知道所有着色方案的名称;它们只能在代码更改时更改。但是每个对象使用的着色方案需要在运行时通过匹配该对象的属性来确定。

在这里我不知道该怎么办。在python中,我会定义一个 dict,其中包含颜色方案到名称的映射,如下所示:

d = {'attr_value1': FirstScheme, 'attr_value2': SecondScheme, 'attr_value3': FirstScheme, ...}

然后只需访问“颜色”变量,因为每个类都应该有它。但是在PHP中没有办法以这种方式引用一个类,那么正确的方法是什么?请注意,多个属性可以映射到相同的着色方案。

4

3 回答 3

2

如果每个类都应该有颜色,请定义允许获取它们的接口:

interface ColorsProvider {
    function getColors();
}
class FirstScheme implements ColorsProvider {
    public static COLORS = array('1' => 'green', '2' => 'red', ...);

    public function getColors() {
        return self::COLORS;
    }
}
class SecondScheme implements ColorsProvider {
    public static COLORS = array('1' => 'red', '2' => 'green', ...);

    public function getColors() {
        return self::COLORS;
    }
}

然后,你有一堆你的参数:

$a = array(
  'attr_value1' => new FirstScheme(),
  'attr_value2' => new SecondScheme(),
);

您可以致电:

$param = 'attr_value1';

if(!isset($a[$param]))
    throw new Exception("undefined param");

if(!($a[$param] instanceof ColorsProvider))
    throw new Exception("Param should point to ColorsProvider");

$a[$param]->getColors();

请注意,它是完全客观的。在 PHP 中有更简单的方法来获得这种效果,但我的解决方案很优雅。


另一点是界面完全分离了颜色的来源。将来自文件、数据库、xml、硬编码等。


默认实现可能是:

abstract class DefaultColorsProviderImpl implements ColorsProvider             {
    protected static COLORS = array();

    public function getColors() {
        return self::COLORS;
    }
}

class FirstScheme extends DefaultColorsProviderImpl {
    protected static COLORS = array( ... );
}

但仍然允许进行从文件中返回颜色的通用实现。

于 2013-05-25T11:54:41.400 回答
1

在他们自己的类中硬编码颜色的替代方法是以下方法:

class ColorScheme {

   protected $colors;

   public function __construct(array $colors) {
       $this->colors = $colors;
   }

   public function getColors() {
       return $this->colors;
   }

}

$scheme1 = new ColorScheme(array('red', 'blue', 'green'));
$scheme2 = new ColorScheme(array('yellow', 'pink', 'cyan'));

PHP 中 python 字典的等价物是关联数组。所以你可以这样做:

$d = array (
    'values_1' => $scheme1->getColors(),
    'values_2' => $scheme2->getColors()
);
于 2013-05-25T11:54:26.280 回答
1

当然可以:

$schemes = [
  'attr_value1' => FirstScheme::$COLORS,
  'attr_value2' => SecondScheme::$COLORS,
  ...
];

甚至在运行时:

$schemes = [
  'attr_value1' => 'FirstScheme',
  'attr_value2' => 'SecondScheme',
  ...
];

接着:

$reflector = new ReflectionClass($schemes['attr_value1']);
$schema = $reflector->getStaticPropertyValue('COLORS');

但这似乎根本无法维护,并且您希望将此类信息存储在适当的数据层中,而不是将它们硬编码为类的静态字段[这不是他们的目的]。

于 2013-05-25T11:57:12.667 回答