PHP代码重复。在什么时候复制代码是正确的方式?
我使用的是CodeIgniter,但这个问题也适用于一般意义。PHP代码重复。在什么时候复制代码是正确的方式?
我的交易与
列item_name | type | date | price | document
我想做的事情在两个完全独立案件下面的表格。
1)获取特定日期范围内的交易清单。 2)获取某个日期范围内每个transaction.type的总价格。
前者可以通过简单地使用一个选择语句具有> datetimestamp
后者可以通过选择SUM,并且由类型而像实施任何所需的分组来实现来实现,其中条件句例如具有> datetimestamp
尽管这是一个简单的例子,但为了实现这一点,我需要两种方法,但是这两种方法(即WHERE子句)的大部分都在两种方法中重复使用。
在速度等方面它并不重要,但它似乎是无意义的代码复制。
第二个例子如下。
我先前在一个单独的方法有一个方法get_data($ID)
这会从一个表中基于传入的ID获得的一行。
这样我会得到我的100个项目例如..返回一个数组,环通过它们并为每个调用get_data。
此设置意味着许多不同的方法可以从不同的来源获得不同的列表,然后仍使用相同的get_data函数和循环来获取所需的数据。
这最大限度地减少了代码重复,但却令人难以置信地不够高效,因为它意味着循环处理大量数据项和数百个数据库查询。
在我目前的设置中,我只是加入我的每个方法中的数据表 - 代码重复但明显提高了效率。
最后一个例子是如下
CI中我能有这样的功能,如下所示:
get_thing($ID)
{
$this->load->database();
$this->db->where('ID',$ID);
$this->db->get('table');
}
,但在备选的情况下,我可能想只得到一个特定的项目文件夹..因此使功能更通用的作品更好..例如
get_thing($array)
{
$this->load->database();
$this->db->where($array);
$this->db->get('table');
}
但我可能要在两个不同的上下文中使用此功能e.g用户页面和管理页面,从而管理员可以看到所有的项目,即使未经证实的。我的代码现在变为:
get_thing($array,$show_unverified = false)
{
$this->load->database();
$this->db->where($array);
if($show_unverified == false)
{
$this->db->where('verified','YES');
}
$this->db->get('table');
}
正如你可能会看到这个可以很快失控和方法可以变得过于复杂,混乱,充满条件句。
我的问题是如下 - 什么是尽量减少重复代码的最佳实践,以及他们怎么可能被应用到上述情况?我花了好几个小时试图让我的代码更有效率,但是我无处可去,因为我无法锻炼我应该实现的目标。
干杯
我对数据库访问函数代码重复的想法是,它往往是更好地保持它分开。
我的规则特别是函数不应该返回不同类型的数据,这取决于参数,例如它不应该返回单个用户,有时也不会返回一个用户数组。它可能会返回错误代码(false)。
但是,如果函数实现不同的访问级别,这些访问级别可以在多个页面间共享。
这基本上总是回归常识。您应该尽量减少重复代码并尽量降低单一功能的复杂性。保持他们小而简单。
因此,基本上每次尝试推广这样的功能时,您都必须询问重复代码的问题是否大于过于复杂的功能问题。
在这种情况下,我会停在你的第二个点和未来,你可以创建最常见任务的一些包装(但要小心不要让包装的迷宫)
//you generic function
function get_thing($array)
{
$this->load->database();
$this->db->where($array);
$this->db->get('table');
}
// a nice and friendly wrapper
function get_thing_by_id($id)
{
get_thing(array('id' => $id));
}
// this is just getting silly. don't go crazy with wrappers, only for very often used things.
// and yes the function name is purposely crazy ;)
function get_thing_verified_by_name_and_city_and_some_more($name, $city, $somethingElse)
{
get_thing(array('name' => $name, 'city' => $city, 'somethingelse' => $somethingElse));
}
这回答第一部分你的问题。假设你正在使用mysql_fetch_assoc或类似的。在迭代结果集时,您可以将循环中的变量中的计数值存储在每个事务类型的总价格中。
第二部分,只要你不重复代码,这会导致你维护代码库时的问题,这是没问题的。对于你的函数,你总是可以测试传递给函数的变量的类型,并相应地设置条件行为。
查看与软件设计模式相关的工厂模式或策略模式以进一步了解。
嗯,是的,我可以,但在这种情况下,这个循环是否有10,000条记录要比使用SUM长得多? – 2013-05-10 13:25:23
我完全同情!希望CodeIgniter(或其他框架)的专家能够解决这个问题。 – 2013-05-10 13:02:43