2012-07-30 32 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類。設計表格來保存這些數據將是設計過程中最困難的部分。在不瞭解數據形狀的情況下,我不想提出一個結構。

相關問題