我为一家保险经纪人工作,我在这里实施的其中一件事是报价服务,该服务将客户的详细信息作为输入,并为许多保险公司提供报价列表作为响应。
它目前的工作方式如下:
- 索引页面接收 JSON 字符串中的报价数据
- 报价数据依次发送到每个保险公司的计算脚本 - 这些脚本在索引页面的数组中列出
- 每个保险公司的计算都参考数据库表,以查看在保险开始日期的情况下应该使用哪组费率
- 数据被发送到特定脚本并生成一个速率并返回给索引
- 索引按升序对结果进行排序,并将它们作为 JSON 字符串返回给发送者
这个解决方案的问题是:
- 难以测试 - 每组速率都是一个单一的代码块,因此不能单独测试各个部分
- 难以维护 - 为保险公司添加一组新费率涉及将当前费率复制到新脚本,进行必要的更改,并在数据库表中使用新费率的开始日期创建新条目。这反过来导致:
- 费率之间有很多代码重复
我新的部分形成的解决方案是有一个主Quoteservice
类,它包含所有报价通用的功能,无论是保险公司还是产品Insurer1
,Insurer2
等等。从索引页面调用的子类以获取报价率。这些反过来将具有每组费率(等)的子Insurer1May2012
类Insurer1July2012
。我的问题在于试图摆脱对数据库表的需要来为开始日期选择正确的费率。
我想能够说
$quoteresults=array();
$quoteresults=array_merge(Insurer1->getQuote($quotedata), $quoteresults);
$quoteresults=array_merge(Insurer2->getQuote($quotedata), $quoteresults);
并让每个InsurerX
对象根据开始日期使用正确的子类( 等) - 可能通过在其每个子类上调用一个函数InsurerXMay2012
,该函数返回子类的费率生效时的日期(或时间戳)。不幸的是,在寻找循环遍历类的子类的最佳方法之后,这似乎不是最好的方法。InsurerXJuly2012
getStartdate()
最终目标是能够只添加该类型Insurer1Sept2012
的一个子类来更改速率,而不必更改多个文件和/或数据库表。(覆盖以前的费率不是一种选择 - 调整过程需要能够在它们被取代后长达 12 个月内获得费率)
我如何看待新版本的示例
abstract class Quoteservice
{
// Various common functionality here...
}
class Insurer1 extends Quoteservice
{
public function getQuote($quotedata)
{
$subclass=null;
// This is the bit I'm not sure of...
// Maybe something like:
foreach($subclasses as $thissubclass)
{
$subclassstart=$thissubclass->getStartdate();
// Ignore all start dates greater than proposed start date
if($subclassstart < $quotedata['startdate'])
{
$subclasses[$subclassstart]=$thissubclass;
}
}
ksort($subclasses);
$subclass=array_pop($subclasses);
return $subclass->getQuote()
}
}
class Insurer1May2012 extends Insurer1
{
public function getStartdate()
{
return 1335830400; // unix time stamp for 1st May 2012
}
public function getQuote($quotedata)
{
// Calculate May's rate here...
return $quoteinfo;
}
}
class Insurer1July2012 extends Insurer1
{
public function getStartdate()
{
return 1341100800; // unix time stamp for 1st July 2012
}
public function getQuote($quotedata)
{
// Calculate July's rate here...
return $quoteinfo;
}
}