2012-07-30 34 views
2

我为一家保险经纪人工作,我在此处实施的一件事是一种报价服务,它将客户的详细信息作为输入,并提供多家保险公司的报价列表作为回应。循环通过子类还是有更好的方法吗?

目前,它的工作原理如下:

  • 索引页接收报价数据的JSON字符串反过来
  • 报价数据被发送到每个保险公司的计算脚本 - 这些脚本在指数数组上市 页
    • 各保险人的计算咨询数据库表,看看哪些利率的设定可以使用给定的数据发送到特定的脚本,该保险将开始
    • 日期和速度产生d并返回到索引
  • 索引中的排序结果按升序排列,将它们作为一个JSON字符串到发送方

这种解决方案的问题是:

  • 难以测试 - 每套价格都是单一的代码块,因此不能单独进行测试
  • 难以维护 - 为保险公司增加一组新的费率涉及将当前费率复制到新脚本中,m进行必要的更改,并在数据库表中创建一个新条目,其中包含新费率的开始日期。这反过来又导致:
  • 大量率
  • 之间的重复代码的

我的新的部分形成的解决方案是有一个主Quoteservice类,其中包含常见的功能,所有的报价,无论保险人或产品和Insurer1Insurer2等。从索引页面调用的子类获得报价。这些反过来会对每组费率都有小类(Insurer1May2012,Insurer1July2012等)。我的问题是试图摆脱对数据库表格的选择,以便为开始日期选择正确的速率。

我希望能说

$quoteresults=array(); 
$quoteresults=array_merge(Insurer1->getQuote($quotedata), $quoteresults); 
$quoteresults=array_merge(Insurer2->getQuote($quotedata), $quoteresults); 

,并让每个InsurerX对象使用基于起始日期正确的子类(InsurerXMay2012InsurerXJuly2012等) - 可能是通过在每个调用一个函数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; 
    } 
} 
+0

似乎有趣,但你可以使用一些代码片断和示例数据缓解理解 – 2012-07-30 11:41:54

+0

@RupeshPatel我添加一些代码给的我在想什么的想法。 – Gareth 2012-07-30 12:08:19

回答

0

尽管可能,将类名称中的变量数据存储不是我会推荐的方法。 PHP语言中已经有了这种数据存储的内置结构。

而不是每个类型的报价的每个日期有一个子子类,我会使用类的构造函数采取日期变量,它可以用它来计算所需的报价。

例如:

class Insurer1 extends Quoteservice { 
    public function __construct(DateTime $date) { 
     // Do something with the data. 
    } 
} 

// ... would be initialised like this: 

$quoteResults = array(); 
$quoteResults[] = new Insurer1("2012-07-30"); 
$quoteResults[] = new Insurer2("2012-07-21"); 

Quoteservice类可以实现的方法,例如getStartDate(),这将提供给的Quoteservice所有实例。

您甚至可以完全删除对Insurer1,Insurer2 ...类的需求,并将保险人的名称作为另一个参数传入构造函数。

$someQuote = new Quoteservice("2012-07-30", "Insurer1"); 
+0

对不起,我没有解释得很清楚。 “Insurer1Jun2012”这个班的名字对我来说只是一个方便。我建议在类中有一个函数getStartdate(),它返回一个日期或unix时间戳,说明费率何时生效。 – Gareth 2012-07-30 11:26:11

1

试图将这个作为一个单独的PHP页面/脚本来实现是非启动器。一旦你开始分离逻辑,其他一切都变得更简单。

报价数据被发送到每个保险公司的计算脚本反过来

我敢打赌性能吸大的时间了。

每组速率是代码的单片块,以便片不能被单独测试

然后,作为最低限度,应为每一个保险公司URL,这又可以实现路由到该保险公司特有的其他网址。当然,你可以将你的脚本作为前端控制器来聚合web服务。

它通过类的子类寻找最好的方式来循环后似乎

你似乎缺少面向对象编程的一个关键点 - 封装。

使用正确的子类(InsurerXMay2012 ....

OMG,NO!

你混淆了代码和数据。难怪each set of rates is a monolithic block of code

可能通过它的每个子类

的调用函数getStartdate()当你检查你的电子邮件,你认为POP服务器读取每一封电子邮件它拥有刚刚找到的那些哪些给你?尽管我认为最佳的解决方案会跨越多个聚集的URL(即HTTP级别体系结构)分割功能,并且路由应该由数据结构(即数据库)驱动,但很可能在理智的情况下获得理想的结果系统只使用面向对象的PHP。但是,除非你能分离问题,否则分层代码体系结构,分离代码和数据,以及如何通过代码正确地路由执行线程,然后你只是弄得一团糟的意大利面代码。

+0

谢谢,但嘲笑我并没有真正帮助我。我不会详细说明当我在这里导致当前情况的时候,需求是如何演变的,足以说明它是相当复杂的。您的建议(通过特定的承保人的URL路由)听起来很像我已经(与大丑计算脚本除外):客户端获取报价 - >报价发送到'/报价/房车/' - >'指数。 php'它发送到每个'insurerX.php'反过来其中选择'基于日期insurerXMay2012.php'(使用DB数据) - >发送回报价 - >被添加到结果。 – Gareth 2012-07-30 13:22:30

+0

这促使在重写(比计算脚本的丑等)尝试的事情是,我的老板上周增加了新的钙质,不知道他是不是正确地做到了。该过程需要很简单:添加脚本来纠正文件层次结构中的位置,就是这样。其他的一切都应该由服务来处理。 – Gareth 2012-07-30 13:34:16

0

我不认为Insurer应该扩展QuoteService。他们有不同的(如果偶尔重叠)功能。 QuoteServiceInsuranceQuotes的聚合器。 InsurerInsuranceQuote的提供商。一个InsuranceQuote取决于谁的Insurer是,谁是Insuree可能。因此,它可能会去是这样的:

$client= new Insuree; 
$quoter= new QuoteService; 
$quoter->calculate($client); 
$quoter->show_quotes(); 

带班这样的:

class Insuree { 

    protected $age; 
    protected $gender; 
    protected $marital_status; 
    protected $drivers_license; 
    protected $address; 
    //etc. with constructor and getters/setters 
} 

class Insurer { 

    function get_quote(Insuree $client, $args=null) { 
    //do stuff 
    return $quote; //InsuranceQuote obj. 
    } 
} 

class InsuranceQuote { 
    protected $period; 
    protected $total; 
    //etc. with constructor, getters, setters 

    function out(){ 
    //echo something 
    } 
} 

class QuoteService { 

    protected $insurers; //SplObjectStorage containing Insurer objects 
    protected $quotes; //SplObjectStorage containing InsuranceQuote objects 

    function __construct($args=null){ 
    $this->get_insurers($args); //limit the list with $args if you like 
    $this->quotes=new SPLObjectStorage; 
    } 

    protected function get_insurers($args){ 
    $this->insurers=new SPLObjectStorage; 
    //access list of insurers from db(?) 
    while($row = $list->fetch_assoc()){ 
     $i=new Insurer($list); 
     $this->insurers->attach($i); 
    } 
    } 

    function calculate(Insuree $client, $args=null) { 
    foreach($this->insurers as $quoter){ 
     $this->quotes->attach($quoter->get_quote($client, $args)); 
    } 
    } 

    function show quotes(){ 
    foreach($this->quotes as $quote) $quote->out(); 
    } 

} 

关于如何继承Insurer:数据具体到每一个Insurer必须存储在某个地方。如果它可以以标准格式存储,那么您只需要一个Insurer类。设计表格来保存这些数据将是设计过程中最困难的部分。在不了解数据形状的情况下,我不想提出一个结构。

相关问题