PHP OOP购物车设计/类型提示建议

时间:2013-03-06 19:44:32

标签: php shopping-cart type-hinting

我创建了一个我的第一堂课,一个购物车课。它很棒,并且完成了我所需要的一切。但是,总会有一个......

我已经阅读了很多关于类型提示的内容,并被建议只通过我的shoppingcart类一个暗示变量:

$cart = new cart(item $id);

我理解这样做的原因但是我很困惑我的项目类应该做什么以及如果我选择实现它将使用哪些方法。

目前我的网站使用MVC启发的结构来分离方法/视图和控制器。我的视图包含一个帖子表单,它将项目ID发送到控制器,控制器创建对象并调用additem方法(或其他相关方法)。

您是否认为我实施网站的方式受益于项目类?

2 个答案:

答案 0 :(得分:6)

类型提示是一种向用户通知他们应该调用它们的方法 的方法。它还允许您(作为实现该方法的方法)依赖对您传递的参数的某些特征。

以下是没有提示类型的购物车的示例

<?php
class Cart {
    protected $items = array();

    public function addItem($item) {
        $this->items[] = $item;
    }
}

$cart = new Cart();
$cart->addItem('My Super Cool Toy');

运行上述内容后$cart中的内容是Cart的一个实例,其中包含一个项目“我的超级酷玩具”。但是,Cart对象不知道该项是什么。它不知道它如何与它交互或它可以用它做什么。例如,我如何获得上面购物车的小计?我不能。

以下是类型提示的示例:

<?php
class Cart {
    protected $items = array();

    public function addItem(Item $item) {
        $this->items[] = $item;
    }

    public function getSubTotal() {
        $total = 0;
        foreach ($this->items as $item) {
            $total += $item->getPrice();
        }
        return $total;
    }
}

class Item {
    protected $name;
    protected $price;

    public function __construct($name, $price) {
        $this->name = $name;
        $this->price = $price;
    }

    public function getName() {
        return $this->name;
    }

    public function getPrice() {
        return $this->price;
    }
}

$cart = new Cart();
$cart->addItem(new Item('My Super Cool Toy', 10.99));

现在我处于一个完全不同的境地。我知道我的Cart已满Item秒。我知道我可以getPrice() Item。我可以依靠那里,因为你可以调用addItem方法的唯一方法是给我一个Item对象。

如果没有类型提示,可以这样做吗?是。 然而没有好的方法可以依赖任何特定的实现。作为调用者,我可能为您提供Item对象。但我也可能会给你一个字符串或数字。如果你所拥有的只是一个字符串或一个数字,你怎么能最终给我一个价格呢?

现在让我们更好一点

快速进入接口编码。假设我有各种类型的玩具:遥控车和玩偶。据推测,我们与他们玩的方式不同。在这种情况下,一个“item”对象不起作用,因为它们可以做不同的事情。 但是,它们都表现出相同类型的行为。他们都是玩具。所以让我们为它创建一个接口:

<?php
interface Toy {
    public function play();
}

让我们为我们的玩具创建一些具体的课程:

<?php
class RemoteControlledCar implements Toy {
    public function play() {
        print "I'm driving a car";
    }
}

class Doll implements Toy {
    public function play() {
        print "GI Joe";
    }
}

现在,我们要将玩具存放在玩具箱中:

<?php
class ToyBin {
    protected $toys = array();

    public function addToy(Toy $toy) {
        $this->toys[] = $toy;
    }

    public function playWithMyToys() {
        foreach ($this->toys as $toy) {
            $toy->play();
        }
    }
}

看看,你已经成功正确编程了 。你知道你有一个装满Toy玩具的玩具箱。你不必关心它们是什么类型的玩具,你也不必知道如何与它们互动。你只知道你能够用它们做某些事情(在这种情况下,play与它们一起)。因此,您有一个可以依赖的界面。

为什么这样更好? 由于几个原因,接口实际上是编程的方式

  1. 他们只需要界面创建者的努力。接口不需要任何功能。它只是作为其他人实施的“契约”。
  2. 他们让您依赖可用的特定功能。在我的示例中,您知道任何“玩具”可以ToyBin加入play()。而且你不必担心如何。
  3. 它们允许在不牺牲代码质量的情况下实现灵活性。您可以编程任何可以以任何方式玩的玩具。
  4. 希望这有助于澄清事情。

答案 1 :(得分:0)

完全按照MVC的原则,您可以看到项目被建模为一个类。即使这只是一个子类数据库记录,它也为将来的扩展提供了一个简单的平台。但是,我希望在诸如addItem()之类的方法上看到类“item”的这个类型变量,而不是必需的cart类的构造函数。暗示你的购物车只有一件物品吗?

从设计模式的角度来看,无论如何都要为您的商品设置课程。您现在可能没有这些要求,但在以后阶段您可能希望将方法添加到项目类中:

  • 获取相关项目
  • 获取图片
  • 评价项目

等等。

使用PHP面向对象,如果可以的话,使用类型提示通常总是一个好主意(如果参数肯定需要是固定类型)。对于像整数这样的简单类型,总是值得检查或转换为该类型,这是您在方法中所做的第一件事。这种方式更安全,通过检查错误随着时间的推移,您将学习很多代码库中可能存在的错误。