类集合转换类集合_PHP中的集合类

类集合转换类集合

A Collection class is an OOP replacement for the traditional array data structure. Much like an array, a collection contains member elements, although these tend to be objects rather than simpler types such as strings and integers.

Collection类是传统数组数据结构的OOP替代。 就像数组一样,集合包含成员元素,尽管它们通常是对象,而不是诸如字符串和整数之类的简单类型。

The general characteristics of a collection class are:

收集类的一般特征是:

  • Establishes a wrapper around a array of objects.

    建立围绕对象数组的包装器。
  • Collections are mutable – new elements may be added and existing elements may be modified or removed.

    集合是可变的–可以添加新元素,并且可以修改或删除现有元素。
  • Sorting algorithms are unstable (which means the order for equal elements is undefined).

    排序算法不稳定(这意味着相等元素的顺序是不确定的)。
  • Can use lazy instantiation to save system resources.

    可以使用延迟实例化来节省系统资源。

数组问题 (Problem with Arrays)

Applications frequently have objects that contain a group of other objects, and this is a great place to make use of collections. For example, suppose we decide to create a book store system. Let’s say we’ve written a customer class which, among other things, holds a list of books that the customer would like to purchase:

应用程序经常具有包含一组其他对象的对象,这是使用集合的好地方。 例如,假设我们决定创建一个书店系统。 假设我们已经编写了一个客户类,其中除其他外,它包含客户想要购买的书籍清单:

<?php
class Customer 
{
    public $items = array();
    // ...
}

$customer = new Customer(1234);
foreach ($customer->items as $item) {
    echo $item->name;
}

If the most obvious approach (using an array) were the best possible approach, I wouldn’t write this article. The above example has these problems:

如果最明显的方法(使用数组)是最好的方法,那么我不会写这篇文章。 上面的示例存在以下问题:

  • We’ve broken encapsulation – the array is exposed as a public member variable.

    我们已经破坏了封装–数组作为公共成员变量公开。
  • There is ambiguity in indexing and how to traverse the array to find a specific item.

    在索引以及如何遍历数组以查找特定项目方面存在歧义。

Additionally, to make sure the array is available for any code that might access it, we must populate the list of information from the database at the same time as the customer information. This means that even if we want to print just the customer’s name, we must fetch all of the item information, unnecessarily increasing load on the database and potentially bogging down the entire application.

另外,为了确保该数组可用于可能访问它的任何代码,我们必须与客户信息同时填充数据库中的信息列表。 这意味着,即使我们只想打印客户的姓名,我们也必须获取所有商品信息,不必要地增加了数据库的负载,并有可能使整个应用程序陷入瘫痪。

We can solve those problems by creating a collection class as an OOP wrapper around the array and use lazy instantiation. Lazy instantiation is the mechanism by which we create elements in the array only when we actually need it. It’s called “lazy” because the object determines on its own when to instantiate the component objects rather that blindly creating them when it is instantiated.

我们可以通过创建一个集合类作为数组的OOP包装器并使用延迟实例化来解决这些问题。 延迟实例化是仅在实际需要时才在数组中创建元素的机制。 之所以称为“惰性”,是因为对象自行确定何时实例化组件对象,而不是在实例化时盲目地创建它们。

基本收藏课 (A Basic Collection Class)

A collection class needs to expose methods that allow us to add, retrieve, and delete items, and it’s helpful to have a method that lets us know the size of the collection. So, a basic class would start like this:

集合类需要公开允许我们添加,检索和删除项目的方法,拥有一个让我们知道集合大小的方法会很有帮助。 因此,一个基本的类将开始如下:

<?php
class Collection 
{
    private $items = array();

    public function addItem($obj, $key = null) {
    }

    public function deleteItem($key) {
    }

    public function getItem($key) {
    }
}

The $items array provides a location in which to store the objects that are members of the collection. addItem() lets us add a new object to the collection, deleteItem() removes an object, and getItem() returns an object.

$items数组提供了一个位置,用于存储作为集合成员的对象。 addItem()让我们向集合中添加一个新对象, deleteItem()删除一个对象,而getItem()返回一个对象。

With addItem(), we add an object to the collection by putting it in the $items array at a specified location specified by $key (if no key is provided, we let PHP pick the next available index). If an attempt is made to add an object using a key that already exists, an exception should be thrown to prevent inadvertently overwriting existing information:

使用addItem() ,我们将对象放入$items数组中,该对象由$key指定的指定位置添加到集合中(如果未提供键,则让PHP选择下一个可用索引)。 如果尝试使用已经存在的密钥添加对象,则应引发异常,以防止无意中覆盖现有信息:

public function addItem($obj, $key = null) {
    if ($key == null) {
        $this->items[] = $obj;
    }
    else {
        if (isset($this->items[$key])) {
            throw new KeyHasUseException("Key $key already in use.");
        }
        else {
            $this->items[$key] = $obj;
        }
    }
}

The deleteItem() and getItem() methods take the key as a parameter indicating which items are targeted for removal or retrieval. An exception should be thrown if an invalid key is supplied.

deleteItem()getItem()方法采用键作为参数,指示哪些项是要删除或检索的对象。 如果提供了无效的密钥,则应该引发异常。

public function deleteItem($key) {
    if (isset($this->items[$key])) {
        unset($this- >items[$key]);
    }
    else {
        throw new KeyInvalidException("Invalid key $key.");
    }
}

public function getItem($key) {
    if (isset($this->items[$key])) {
        return $this->items[$key];
    }
    else {
        throw new KeyInvalidException("Invalid key $key.");
    }
}

Because the $key parameter to the addItem() method is optional, we won’t necessarily know the key used for each item in the collection. Adding a method that can provide a list of keys to any external code that might need it is a good idea. The keys can be returned as an array:

因为addItem()方法的$ key参数是可选的,所以我们不一定知道集合中每个项目使用的密钥。 添加一个可以为可能需要的任何外部代码提供键列表的方法是一个好主意。 键可以作为数组返回:

public function keys() {
    return array_keys($this->items);
}

It might also be helpful to know how many items are in the collection.

知道集合中有多少项也可能会有所帮助。

public function length() {
    return count($this->items);
}

And because getItem() and deleteItem() can throw an exception if an invalid key is passed, a means of determining whether a given key exists in the collection is also a good idea.

并且由于如果传递了无效的键, getItem()deleteItem()可能引发异常,所以确定集合中是否存在给定键的方法也是一个好主意。

public function keyExists($key) {
    return isset($this->items[$key]);
}

To use the Collection class as it stands now, create the file Collection.php and save the code for the Collection class in it. Create files for the KeyInvalidException and KeyhasUseException classes, too (they can be simple sub-classes of the base Exception class). Be sure to add require statements if you’re not using an autoloader, and then try the following test code:

要使用当前的Collection类,请创建文件Collection.php并在其中保存Collection类的代码。 也为KeyInvalidExceptionKeyhasUseException类创建文件(它们可以是Exception基类的简单子类)。 如果您不使用自动加载器,请确保添加require语句,然后尝试以下测试代码:

<?php
require_once "Collection.php";

class Salut
{
    private $name;
    private $number;

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

    public function __toString() {
        return $this->name . " is number " . $this->number;
    }
}

$c = new Collection();
$c->addItem(new Salut("Steve", 14), "steve");
$c->addItem(new Salut("Ed", 37), "ed");
$c->addItem(new Salut("Bob", 49), "bob");

$c->deleteItem("steve");

try {
    $c->getItem("steve");
}
catch (KeyInvalidException $e) {
    print "The collection doesn't contain Steve.";
}

This example may not be particularly interesting, but it should give you an idea of how the class is used.

这个示例可能并不是特别有趣,但是它应该使您了解如何使用该类。

结论 (Conclusion)

Collections can be seen as more-specialized way of working with lists for which certain contracts are guaranteed. A Collection class is a very useful OO alternative to the traditional array, and one that can be implemented in virtually any application you might build. It provides careful management of its members and a consistent API that makes it easy to write code that uses the class.

可以将集合视为保证列表特定合同的更专业的工作方式。 Collection类是传统数组的一种非常有用的OO替代方法,它几乎可以在您可能构建的任何应用程序中实现。 它提供了对其成员的仔细管理和一致的API,使编写使用该类的代码变得容易。

翻译自: https://www.sitepoint.com/collection-classes-in-php/

类集合转换类集合

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值