伟大的问题。问题是有很多解决方案,其中大部分都可以工作。
我和MVC一起工作了很多,类似的情况经常发生。特别是在视图中,当某些视图需要类似的渲染时......但并不真正属于视图。
比方说,我们有子类ChildList
,延伸BaseList
。
在子类中添加属性uiHandler
。重载渲染函数,让我们说toString()
,并使用uiHandler与您的特定UI /设计的东西。
我写了一点东西,它是在PHP中......但你应该能够得到一个想法。它使您可以自由选择对象的显示方式,并可灵活地为特定对象使用特定的UI。
看看下面的代码,它似乎很多,但诠释并没有那么糟糕。
BaseList
- 你的基类
BaseListUIExtended
- 使用用户界面,采用可选的UI类的构造函数的参数基类。在C#4中,您可以使用可选的,否则使用2个构造函数。
UIBase
- 界面UI类...
UIChildSpecific
- UI类
ChildList
- 子类可以使用UI还是不行,因为BaseListUIExtended
可选的构造参数。
定义界面
/**
* Base UI interface
*/
interface IUIBase {
/**
* Renders the Base Class
*
* @param UIBase $obj
* @return string
*/
public function render($obj);
}
定义的基类,儿童类
//**************************************************************
// Define Base Classes
//**************************************************************
/**
* Base Class
*/
class BaseList {
/**
* List of items
* @var array
*/
protected $_items = array();
/**
* Gets collection of items
*
* @return array
*/
public function getItems() {
return $this->_items;
}
/**
* Adds new item to the list
* @param object $item
*/
public function add($item) {
$this->_items[] = $item;
}
/**
* Displays object
*/
public function display() {
echo $this->toString();
}
/**
* To String
*/
public function __toString() {
// Will output list of elements separated by space
echo implode(' ', $this->_items);
}
}
/**
* Extended BaseList, has UI handler
* This way your base class stays the same. And you
* can chose how you create your childer, with UI or without
*/
class BaseListUIExtended extends BaseList {
/**
* UI Handler
* @var UIBase
*/
protected $_uiHandler;
/**
* Default Constructor
*
* @param UIBase Optional UI parameter
*/
public function __construct($ui = null) {
// Set the UI Handler
$this->_uiHandler = $ui;
}
/**
* Display object
*/
public function display() {
if ($this->_uiHandler) {
// Render with UI Render
$this->_uiHandler->render($this);
} else {
// Executes default BaseList display() method
// in C# you'll have base:display()
parent::display();
}
}
}
//**************************************************************
// Define UI Classe
//**************************************************************
/**
* Child Specific UI
*/
class UIChildSpecific implements UIBase {
/**
* Overload Render method
*
* Outputs the following
* <strong>Elem 1</strong><br/>
* <strong>Elem 2</strong><br/>
* <strong>Elem 3</strong><br/>
*
* @param ChildList $obj
* @return string
*/
public function render($obj) {
// Output array for data
$renderedOutput = array();
// Scan through all items in the list
foreach ($obj->getItems() as $text) {
// render item
$text = "<strong>" . strtoupper(trim($text)) . "</strong>";
// Add it to output array
$renderedOutput[] = $text;
}
// Convert array to string. With elements separated by <br />
return implode('<br />', $renderedOutput);
}
}
//**************************************************************
// Defining Children classes
//**************************************************************
/**
* Child Class
*/
class ChildList extends BaseListUIExtended {
// Implement's logic
}
测试...
//**************************************************************
// TESTING
//**************************************************************
// Test # 1
$plainChild = new ChildList();
$plainChild->add("hairy");
$plainChild->add("girl");
// Display the object, will use BaseList::display() method
$plainChild->display();
// Output: hairy girl
// Test # 2
$uiChild = new ChildList(new UIChildSpecific());
$uiChild->add("hairy");
$uiChild->add("girl");
// Display the object, will use BaseListUIExtended::display() method
$uiChild->display();
// Output: <strong>hairy</strong><br /><strong>girl</strong>
+1毛女孩 – demoncodemonkey 2010-09-30 16:16:39
嗨,有现在多看看你的例子,这是一个很好的解决方案,但是......它不适用于更复杂的解决方案。当所有项目都是字符串或其他值类型时,你的解决方案是优雅的,但是如果列表中的对象是复杂的对象,需要更复杂的渲染方法,这不会太好,因为需要某种“if-is “在IUIBase实现中的渲染方法中,这是我想要解决的问题。 – Marcus 2010-10-02 07:40:48
@马库斯,从我的理解你的问题,你想渲染的对象,但不想保持UI /设计分开。这正是我的示例代码所做的。每个类都有它自己的UI处理程序,这会将UI与逻辑分开(类似于MVC中的“视图”和“控制器”)。 字符串被用于简化。您可以创建Container,并使用容器定位所有对象(按钮,标签,文本框)。无论哪种方式,你将不得不在你的类(杂乱的代码+难以维护)或某种UI处理程序(更干净的代码+更容易维护)中编写UI /设计逻辑。 – Alex 2010-10-04 12:46:55