## 描述
    	从一个或者多个数据存储中获取数据时，数据被格式化成方便我们查询操作的方式。这种模式可以高效查询和提取数据，并提高应用程序的性能。

## 背景和问题
    	存储数据的时候，开发者优先考虑数据怎样存储而不是怎样获取，当查询时，可能需要从几个数据源查询才能得到所需要的信息。

## 解决方案
    预生成符合要求的结果集表。

## 注意事项
1. 考虑什么时候更新结果集。
2. 考虑存储容量的要求和存储成本。
3. 生成的更新结果集时，考虑数据一致性的影响。


## 何时使用
1. 数据查询复杂，性能低下, 需要简化查询，提高性能时。
2. 出于安全或隐私原因，隐藏部分细节，只提供部分聚合数据。

## 结构中包含的角色
1. MaterializedView 实体化视图
2. OrderTable  订单表
3. OrderItemTable 订单明细表
4. GoodTable 商品表

## 可用到的设计模式思维
    每个表都可以抽象成一个独立的子系统，实体化视图是这些系统的前置系统，符合门面模式的概念。

## 最小可表达代码
    class OrderTable
    {
        protected $data = [
            ['id' => 1, 'order_sn' => '9527'],
        ];

        public function all() : array
        {
            return $this->data;
        }
    }

    class OrderItemTable
    {
        protected $data = [
            ['order_id' => 1,'good_id' => 1],
            ['order_id' => 1,'good_id' => 2],
        ];

        public function all() : array
        {
        return $this->data;
        }
    }

    class GoodTable
    {
        protected $data = [
            ['id' => 1, 'name' => '某商品A'],
            ['id' => 2, 'name' => '某商品B'],
        ];

        public function all() : array
        {
        return $this->data;
        }
    }

    class MaterializedView
    {
        protected $orders = [];

        public function reload()
        {
            $goodIdNameMap = [];
            $allGood = (new GoodTable())->all();
            foreach ($allGood as $good) {
                $goodIdNameMap[$good['id']] = $good['name'];
            }

            $orderGoodMap = [];
            $orderItems = (new OrderItemTable())->all();
            foreach ($orderItems as $orderItem) {
                $orderGoodMap[$orderItem['order_id']][] = [
                    'good_id' => $orderItem['good_id'],
                    'good_name' => $goodIdNameMap[$orderItem['good_id']],
                ];
            }

            $this->orders = [];
            $orders = (new OrderTable())->all();
            foreach ($orders as $order) {
                $orderId = $order['id'];
                $this->orders[$orderId] = [
                    'id' => $orderId,
                    'order_sn' => $order['order_sn'],
                    'good_items' => $orderGoodMap[$orderId],
                ];
            }
        }

        public function findOrderById($id)
        {
            return $this->orders[$id] ?? [];
        }
    }

    $materializedView = (new MaterializedView);
    $materializedView->reload();
    $order = $materializedView->findOrderById(1);
    var_dump($order);