我为一家保险经纪人工作,我在这里实施的其中一件事就是报价服务,它将客户的详细信息作为输入,并提供一些保险公司的报价清单作为回应。
目前的工作原理如下:
此解决方案的问题是:
我新的部分形成的解决方案是拥有一个主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;
}
}
答案 0 :(得分:1)
尝试将此实现为单个PHP页面/脚本是非首发。一旦你开始分离逻辑,其他一切变得更加简单。
报价数据依次发送给每个保险公司的计算脚本
我敢打赌,演出也会耗费大量时间。
每组费率都是一个单一的代码块,因此无法单独测试各个部分
然后,至少应该是每个保险公司的一个URL,这可能反过来实现到该保险公司特定的其他URL的路由。当然,您将脚本实现为用于聚合Web服务的前端控制器。
似乎在寻找循环通过类的子类的最佳方法
之后
您似乎错过了面向对象编程的关键点 - 封装。
天啊,不!使用正确的子类(InsurerXMay2012 ....
您感到困惑的是代码和数据。难怪each set of rates is a monolithic block of code
可能通过在每个子类上调用函数getStartdate()
当您检查电子邮件时,您是否认为POP服务器会读取它所拥有的每封电子邮件,以便找到发给您的电子邮件?
虽然我认为最佳解决方案会将功能分散到多个聚合URL(即HTTP级架构),并且路由应该由数据构造(即数据库)驱动,但很有可能在合理的系统中实现所需的结果只使用面向对象的PHP。但是,除非您能够分离问题,分层代码架构,分离代码和数据,并研究如何正确地通过代码路由执行线程,然后你只是搞乱意大利面条代码。
答案 1 :(得分:0)
尽管可能,将变量数据存储在类名中并不是我建议的方法。 PHP语言中已存在用于此类数据存储的内置构造。
我不是为每种引用类型的每个日期都有一个子子类,而是使用类的构造函数来获取一个日期变量,用它来计算所需的引号。 / p>
例如:
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");
答案 2 :(得分:0)
我认为Insurer
不应延长QuoteService
。它们具有不同(如果偶尔重叠)的功能。 QuoteService
是InsuranceQuotes
的聚合器。 Insurer
是InsuranceQuote
的提供者。 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
类。设计表来保存这些数据将是设计过程中最困难的部分。如果不了解您的数据形状,我不想建议一个结构。