Repository1
注入Service2
。 Repository2
注入Service2
。
假设两种不同的情景:
1)
Repository1
的某些方法需要从Service2
检索数据。
当Service1
两者都提供相应的Repository1
方法时,get()
会注入Service1
还是Service2
?
2)Service2
的一些方法应该从Service1
调用另一种方法。为此类需求注入<?php
include 'common.php';
$query = "SELECT cat_id, parent_id, cat_name FROM " .$DBPrefix. "categories ORDER BY cat_name";
$res = mysql_query($query);
$system->check_mysql($res, $query, __LINE__, __FILE__);
$items = mysql_fetch_assoc($res);
$html = '';
$parent = 0;
$parent_stack = array();
// $items contains the results of the SQL query
$children = array();
foreach ( $items as $item )
$children[$items['parent_id']][] = $item;
while ( $option = each( $children[$parent] ) )
{
if ( !empty( $option ) )
{
// 1) The item contains children:
// store current parent in the stack, and update current parent
if ( !empty( $children[$option['value']['id']] ) )
{
$html .= '<li>' . $option['value']['title'] . '</li>';
$html .= '<ul>';
array_push( $parent_stack, $parent );
$parent = $option['value']['id'];
}
// 2) The item does not contain children
else
$html .= '<li>' . $option['value']['title'] . '</li>';
}
// 3) Current parent has no more children:
// jump back to the previous menu level
else
{
$html .= '</ul>';
$parent = array_pop( $parent_stack );
}
}
// At this point, the HTML is already built
echo $html;
?>
到{{1}}是不是一种坏习惯?使用像AOP这样的事件监听技术来满足这些需求是一种好习惯吗?
答案 0 :(得分:3)
当我们谈论最佳实践时,有很多因素需要考虑。
作为一个良好的开端,尝试理解SOLID原则的概念。 通常,拥有多个具有非常集中角色的类可以调用另一个类而不是将所有功能组合在一个类中。高可重用性和最少代码重复,从而提供可维护性。
对于方案1。)
如果该方法中定义的业务代码与其他服务所需的业务功能相同,则让服务调用另一个服务是完全正常的。这遵循 DRY 原则,没有冗余代码。
但是如果它只是一个没有进一步业务逻辑的简单调用,那么从服务直接调用Dao而不是调用不同的服务为你做这件事也是完全没问题的。特别是如果这两个服务在同一个模块中,没有充分的理由让另一个服务成为明显的简单单行代码的桥接类,除非你想抽象它,但在你的情况下,这只是一个简单的接听电话。
对于方案2。)
但另一件需要考虑的事情是模块化和依赖性方向。如果每个服务相互调用,您的设计可能会出现问题,尽可能避免不同模块上的循环依赖,因为这可能导致意大利面代码,更好地提取相同的代码到公共模块上声明的不同类,可以由许多模块共享。
最后的注意事项,正如罗伯特马丁所说,你将无法立即编写一轮中最干净的代码。最好的代码是通过连续重构和代码清理来伪造的。引用罗伯特马丁,
童子军有一条规则:“总是离开露营地比你发现它更干净。”
答案 1 :(得分:-1)
我对这个问题没有太大的经验,但我个人会避免耦合控制器。我的第一种方法是尝试创建一个适合所有模型的接口,如果可能的话。然后,可以创建一个模型,将多个模型连接在一起,以访问所需的数据,而无需添加对控制器的引用。例如:
Model1 implements iModel{}
Model2 implements iModel{}
ModelWrapper implements iModel{
private iModel model1;
private iModel model2;
public ModelWrapper(iModel model1, iModel model2)
{
this.model1 = model1;
this.model2 = model2;
}
public SomeDataType getSomeValue(){
SomeObject.param1 = model1.method();
SomeObject.param2 = model2.method();
return SomeObject;
}
}
我确信有更好的方法来接近传递给构造函数的模型数量,并且还可以搜索每个模型以查找您要查找的数据。如果未找到数据,则引用空引用或更好的自定义错误。如果实现是一致的,那么包装器可以组合所有模型并允许访问许多自定义组合。至少在这种情况下,当需求发生变化时,您只需添加一个额外的包装器即可获得所需而无需更改当前实现。
也许更有经验的开发人员会以我的回复为基础为您提供更好的实施,但我希望这会有所帮助。