duanganleng0577 2019-07-21 15:17
浏览 107
已采纳

使用返回实例的方法是反模式吗?

In b4 sorry for creating such a vage topic but I'll try to be as concise as possible. I'm trying to improve an object oriented design for a php package I made. I have an Api class that represents en Http external API. This class has methods like get, post, delete etc... and encapsulates some response retrieval or json decoding. This class recieves a GuzzleHttp client as it's constructor parameter to do so.

Then I created some classes for the many endpoint categories the API has like Sale, User, etc... An example method you can find in a class like Sale would be recent() and it's code would do something like: $this->api->get('recent-sales-endpoint.json'). This would require injecting API into Sale as a dependency and this way I could write its unit tests and so as I always do.

Now if I try to act as a user that installed my library and wants to get the recent sales, I have to do things like:

$api = new Api($client);
$sale = new Sale($api);
$recentSales = $sale->recent();
$car = new Car($api);
$newCars = $car->getNew();

So I was wondering if this was is an improvement or an antipattern for making my package more pleasant to use.

On my API class constructor I create instances for every category class like.

private $client;
private $car;
private $sale;
public function __construct(Client $client)
{
    $this->client = $client;
    $this->car = new Car($this);
    $this->sale = new Sale($this);
}

And then I can create acesssor methods like:

public function sale()
{
    return $this->sale
}

So for the package user to retrieve the data now it would be:

$api = new Api($client);
$recentSales = $api->sale()->recent();
$newCars = $api->car()->getNew();

Which of these two ways do you think is the most correct way? Also I thought I could initialize these instances when being queried the first time instead of doing it in the constructor, but I don't know if I'm complicating the design too much.

  • 写回答

1条回答 默认 最新

  • doukong6031 2019-07-21 15:47
    关注

    I don't think there is correct and incorrect way of doing this. I feel that your option 2 feels nice to use:

    $api = new Api($client);
    $recentSales = $api->sale()->recent();
    

    It's up to you how you want the API of your package to look like. I think it's a good idea to make it somewhat flexible so that developers using your package can pick the option that works best for their use-case.

    You can always look at how other packages do it, I like this libary from stripe: https://github.com/stripe/stripe-php/tree/master/lib

    https://github.com/stripe/stripe-php

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分