Whip Monstrous Code Into Shape 20-Consider Wrapping it Up

分享 oustn ⋅ 于 2016-12-27 14:15:51 ⋅ 最后回复由 JobsLong 2016-12-31 13:13:02 ⋅ 399 阅读

Imagine that you perform an API request to fetch a bit of JSON. That response will become an array of objects, once decoded. Too often, though, I see developers littering their views or creating helper functions, all to add a bit of behavior or formatting to how the data is rendered. There's no need for this. Instead, you might consider wrapping each item within a simple POPO, and then add your behavior and formatting to this class alone.


这是这个系列的最后一节,介绍的是包装一条记录。想象一下开发的时候有些是从外部 api 服务器获取的 JSON 数据,json_decode 之后就变成了一个 stdClass 对象数组。

[
    {
        "id": 4,
        "name": "Prof. Kyleigh Quitzon",
        "power": 77,
        "created_at": "2016-12-12 12:12:40",
        "updated_at": "2016-12-12 12:12:40"
    },
    {
        "id": 5,
        "name": "Dr. Agustin Frami",
        "power": 89,
        "created_at": "2016-12-12 12:12:40",
        "updated_at": "2016-12-12 12:12:40"
    },
    {
        "id": 6,
        "name": "Ms. Carmela Beahan MD",
        "power": 57,
        "created_at": "2016-12-12 12:12:40",
        "updated_at": "2016-12-12 12:12:40"
    },
    ...
]

返回的数据是数组,很多 collection 很好用的方法都没有办法用,另外数据也是标准的 stdClass,如果要格式化某个数据,不得不在视图中写各种逻辑或者编写自己的 helper 方法。

@foreach($heroes as $hero)
    英雄姓名: {{ $hero->name }},
    英雄能力:{{ $hero->power }},
    狂暴能力:{{ $hero->power * 1.3 }}
    创建时间: {{ humanTime($hero->created_at) }}
@endforeach

// humanTime 辅助方法

function humanTime($date){
    $carbon = \Carbon\Carbon::createFromFormat(\Carbon\Carbon::DEFAULT_TO_STRING_FORMAT, $date);

    return $carbon->diffForHumans();
}

这种情况下,可以考虑使用包装类,也就是创建一个类,负责管理一个个数据,并且可以添加自定义的方法。

class HeroWrap
{
    private $item;

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

    public function humanTime()
    {
        $carbon = Carbon::createFromFormat(Carbon::DEFAULT_TO_STRING_FORMAT, $this->item->created_at);

        return $carbon->diffForHumans();
    }

    public function wild()
    {
        return $this->item->power * 1.3;
    }

    public function __get($property)
    {
        if (isset($this->item->$property)){
            return $this->item->$property;
        }

        throw new \Exception("$property doesn't exist!");
    }
}

在从 api 服务器获取到数据后,就创建一个 collect,并调用 map 方法,把所有的数据都包装成 HeroWrap

$heroes = // get heroes from api service;

$heroes= collect($heroes)->map(function ($hero) {
    return new HeroWrap($hero);
});

这样在视图里面就可以很简单的使用了,一方面方便修改,比如要修改狂暴指数,只要改改HeroWrap里面的wild方法就行;另外一方面方便扩展。

@foreach($heroes as $hero)
    英雄姓名: {{ $hero->name }},
    英雄能力:{{ $hero->power }},
    狂暴能力:{{ $hero->wild() }}
    创建时间: {{ $hero->humanTime() }}
@endforeach

以上就是 Whip Monstrous Code Into Shape 这个系列的所有内容了,后面看到有意义的再写吧,写东西对我来说真的太难了,即使是有一个思路,要表达出来也是很困难...

Oustn

本帖已被设为精华帖!
本帖由 overtrue 于 3周前 加精
回复数量: 2
  • nickfan 乐天知命,随遇而安~
    2016-12-28 09:25:40
    $heroes= collect($heroes)->map(function ($hero) {
        return new HeroWrap($hero);
    });

    精华所在,转换collection成员偷梁换柱。

  • JobsLong MOD 那么,下一步的行动是什么?
    2016-12-31 13:13:02

    来学习 ~~

暂无评论~~
  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
Ctrl+Enter