Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 工厂模式和多态性使用_Oop_Php_Design Patterns - Fatal编程技术网

Oop 工厂模式和多态性使用

Oop 工厂模式和多态性使用,oop,php,design-patterns,Oop,Php,Design Patterns,我正在使用一个工厂(BillFactory)来确定实例化哪个Bill。每个Bills(AClassBill,BClassBill等)都可以判断提供的数据是否在范围内。在因子中,我迭代每个账单,检查当前数据是否在当前账单范围内。如果它在范围内,我实例化该类的一个对象并返回它 这是代码 interface IBillable { function calculate_bill(); } class Bill implements IBillable { protected $fr

我正在使用一个工厂(
BillFactory
)来确定实例化哪个
Bill
。每个
Bill
s(
AClassBill
BClassBill
等)都可以判断提供的数据是否在范围内。在因子中,我迭代每个账单,检查当前数据是否在当前账单范围内。如果它在范围内,我实例化该类的一个对象并返回它

这是代码

interface IBillable {
    function calculate_bill();
}

class Bill implements IBillable {

    protected $from;
    protected $to;
    protected $rate;
    protected $unit_amount;

    public function get_from() {
        return $this->from;
    }

    public function get_to() {
        return $this->to;
    }

    public function get_rate() {
        return $this->rate;
    }

    public function in_range($unit_amount) {
        $_from = $this->get_from();
        $_to = $this->get_to();
        return ($_from <= $unit_amount && $_to >= $unit_amount);
    }

    public function calculate_bill() {
        return ($this->get_rate() * $this->unit_amount);
    }

}

class AClassBill extends Bill {

    protected $from = 0;
    protected $to = 100;
    protected $rate = 3.05;

    public function __construct($amount) {
        $this->unit_amount = $amount;
    }

}

class BClassBill extends Bill {

    protected $from = 101;
    protected $to = 400;
    protected $rate = 4.29;

    public function __construct($amount) {
        $this->unit_amount = $amount;
    }

    public function calculate_bill() {
        if ($this->unit_amount >= 301) {
            return $this->get_rate() * $this->unit_amount;
        } else {
            $bill1 = $this->get_rate() * ($this->unit_amount - $this->get_from() + 1);
            $bill2 = new AClassBill($this->get_from() - 1);
            return $bill1 + $bill2->calculate_bill();
        }
    }

}

class CClassBill extends Bill {

    protected $from = 401;
    protected $to = -1; // not used
    protected $rate = 7.89;

    public function __construct($amount) {
        $this->unit_amount = $amount;
    }

    public function in_range($unit_amount) {
        $_from = $this->get_from();
        return ($_from <= $unit_amount);
    }

}

class BillFactory {

    private static $s1 = null;
    private static $s2 = null;
    private static $s3 = null;

    public static function instance($units) {
        if (is_null(self::$s1))
            self::$s1 = new AClassBill(0);
        if (is_null(self::$s2))
            self::$s2 = new BClassBill(0);
        if (is_null(self::$s3))
            self::$s3 = new CClassBill(0);

        if (self::$s1->in_range($units)) {
            $b = new AClassBill($units);
        } else if (self::$s2->in_range($units)) {
            $b = new BClassBill($units);
        } else if (self::$s3->in_range($units)) {
            $b = new CClassBill($units);
        } else {
            $b = false;
        }
        return $b;
    }

}

for ($i = 1; $i <= 500; $i++) {
    $b = BillFactory::instance($i);
    if ($b !== false) {
        printf("%10s\t%04d\t%04.2f\t%04d\t%06.2f\n", get_class($b), $i, $b->get_rate(), $i, $b->calculate_bill());
    }
}
接口可扩展{
函数calculate_bill();
}
类比尔实现了IBillable{
保护美元不受损害;
受保护的美元至;
受保护的美元汇率;
受保护的美元单位金额;
公共函数get_from(){
返回$this->from;
}
公共函数get_to(){
返回$this->to;
}
公共功能获取率(){
返回$this->rate;
}
范围内的公共职能(单位金额){
$\u-from=$this->get\u-from();
$\u to=$this->get\u to();
返回($\u from=$unit\u金额);
}
公共职能法案{
返回($this->get\u rate()*$this->unit\u amount);
}
}
类AClassBill扩展了Bill{
受保护的$from=0;
受保护$to=100;
受保护美元汇率=3.05;
公共功能结构(金额){
$this->unit\u amount=$amount;
}
}
类BClassBill扩展了Bill{
保护$from=101;
受保护$to=400;
受保护美元汇率=4.29;
公共功能结构(金额){
$this->unit\u amount=$amount;
}
公共职能法案{
如果($this->unit\u amount>=301){
返回$this->get_rate()*$this->unit_amount;
}否则{
$bill1=$this->get_rate()*($this->unit_amount-$this->get_from()+1);
$bill2=新AClassBill($this->get_from()-1);
返回$bill1+$bill2->计算账单();
}
}
}
类别CClassBill扩展了Bill{
保护$from=401;
受保护的$to=-1;//未使用
受保护美元汇率=7.89;
公共功能结构(金额){
$this->unit\u amount=$amount;
}
范围内的公共职能(单位金额){
$\u-from=$this->get\u-from();
返回值($\范围内的($单位)){
$b=新AClassBill(单位);
}else if(self::$s2->in_范围($units)){
$b=新b类账单(单位);
}else if(self::$s3->in_范围($units)){
$b=新分类账单(单位);
}否则{
$b=假;
}
返回$b;
}
}
对于($i=1;$i获得利率(),$i,$b->计算账单());
}
}
问题出在factory类(
BillFactory
)中。您会注意到,我已经创建了3种类型的
Bill
s(单例模式)的3个虚拟实例。这就是我解决问题的方法。我的问题是我应该使用这个虚拟实例吗?他们是否违反了任何原则

另一种方法是将
in_range
方法转换为静态方法。那么我就不必创建实例了。另外,由于这个
in_range
方法是一个特定于类的属性(意味着它不会在不同的实例上更改),所以它应该是有意义的。在这种情况下,我必须对
方法中
的那些值进行硬编码,或者将所有
范围
属性设置为静态


我应该使用什么方法?你知道更好的吗?

试着重新审视一下设计。看起来应该只有1个Bill类(创建3个不同的实例而不是3个不同的类),并且可能将calculate_Bill委托给策略(策略模式)。

请查看您的代码。这与你所说的不同。它看起来也坏了。我还想说你可以把
范围
放入它自己的对象中-这可能已经解决了你的“问题”。有了所有的静态调用,我想说它更多的是基于类的编程而不是面向对象的编程。@hakre我已经更新了代码。我想现在可以了。我可以添加
范围
类。但是它是如何解决问题的呢?@Gordon,从DP的角度来看呢?