我有一些类需要交互。每个类都有许多选项,可以对其进行调整以获得一种或另一种行为。
(注意:我没有测试代码,因此可能存在一些语法错误)
(注意2:我用PHP编写,但我想这个问题对每种OOP语言都有效)
<?php
class Process
{
protected $element;
protected $config;
protected $default_config = array(
'process_path' => '/bin/command',
'default_output_path' => '/tmp/',
'element_conf' => array()
);
public function __construct(array $config)
{
$this->config = $config;
$element_config = array_key_exists('element_conf', $this->config)
? $this->config['element_conf']
: array();
$this->element = new Element($element_config);
}
public function run()
{
$this->element->behave();
// ...
}
// ...
}
class Element
{
protected $type;
protected $config;
protected $default_config = array(
'behaviour_type' => 'evil',
'can_kill_people' => true
);
public function __construct(array $config)
{
$this->config = array_replace($this->default_config, $config);
$this->type = $this->config['behaviour'];
}
public function behave()
{
// ...
}
// ....
}
class Config
{
// get data from config file and makes it available with a static getter/setter
}
-------------------------------
$element_conf = array(
'can_kill_people' => false
);
$process_conf = array(
'default_output_path' => Config::get('default_output_path'),
'element_conf' => $element_conf
);
$pr = new Process($process_conf);
$pr->run();
我想保持尽可能高的封装,所以我避免直接引用Config类的类(配置也可以从其他地方到达)。
我想听听你对的看法
该方法提供了内部类(元素)的配置。我想在顶级初始化它的配置(在调用
run()
方法之前);但我觉得这条路不好走元素的配置取决于流程。为类提供配置的方法。最好像我的代码中那样传递/设置数组配置,或者我应该将每个设置作为构造函数参数传递,还是使用设置器?
是否将配置保留在受保护的属性中,作为数组还是将每个相关设置分配给单个受保护/私有属性?(就像我为
Element::type
做的那样)管理类配置的常用方法是什么您是否也尝试使用类来存储配置?你喜欢阵列吗?或者直接传递/设置参数/属性?(在我看来,最后一种方法不那么容易维护)。或者更好的是,是否存在专门针对这种情况的设计模式?
如果要通过Element对象对流程类进行参数化,则将Element对象作为参数传递,而不是将其参数作为参数传递。这种方法还强调了Process类依赖于Element类,而Element类现在不能从Process构造函数中立即看到。
至于数组配置——在我看来,使用数组很容易编写,但很难实际使用类,你怎么能容易地知道你的类支持什么设置?我宁愿在构造函数中使用单独的参数,也不愿使用具有已定义属性的单独配置类。
只要你把它封装在一个合理的公共接口中,你如何在类内部做事情其实并不重要。您想要做的是保持尽可能多的私有内容,以便在必要时保持更改类内部工作方式的能力,同时保持向后兼容的公共接口。还要记住,当您能够在不破坏向后兼容性的情况下更改受保护的属性和方法时,protected与public基本相同,因为受保护的特性和方法可以由子类使用。
最后一件事是,如果你的类真的有很多参数可以改变它的行为,那么也许你应该考虑将这些不同的行为拆分为新的类是否会更好,这些新的类会扩展基类或实现它的接口(无论什么更适合你的情况)。
没有最好的方法在全局范围内做某事,只有最好的方法来做你想做的事情(无论是否通用)(应用第一个断言:D)
配置默认值
配置项可以是强制性的,也可以不是强制性的,但应该始终具有默认值(因此它可能不是强制性的)。在我看来,有两种方法可以提供默认值:
- 声明方式
安装配置对象时,将提供所有默认值,但如果源不是动态的,则不可能提供动态值 - "内联"方式
当您请求当前值时,您将提供默认值
但是,事实上,您可以使用自己的规则同时使用这两种方法。
使用这些规则,您可以为元素的配置提供一个默认值。但它的当前配置可以作为子配置或其他源提供。。。流程可以使用的
声明性配置
在源代码中,配置是声明性的,这意味着当您开发它时,您知道配置是存在的,并且必须/可以/应该提供配置。因此,使用带有private元素的对象来存储配置值/format或每个配置键使用一个简单的常量并不重要。
在我的框架中,所有配置都作为数组存储在Config类的受保护成员中。这是因为我需要泛型,但我不允许在配置文件中缺少值
OOP只允许OOP
当你使用OOP时,尽可能多地使用它,对象是类的实例,类是声明的,你知道它的内容意味着什么。如果不使用对象,就不能创建通用源。