xsolve-pl/model-factory
Composer 安装命令:
composer require xsolve-pl/model-factory
包简介
This library provides a versatile skeleton for organizing model factories.
关键字:
README 文档
README
Table of contents
Introduction
This library provides a versatile skeleton for organizing model factories.
It can be used to provide objects that will be later on passed to some serializer and returned via API, or some adapters or facades for your objects before they are handed over to some other libraries or bundles.
It aims to empower models so that they can easily get access to some services or create nested models lazily without requiring much work upfront.
If you want to use this library in a Symfony application you may be interested in using the dedicated bundle available at xsolve-pl/model-factory-bundle.
License
This library is under the MIT license. See the complete license in LICENSE file.
Getting started
Include this library in your project using Composer as follows (assuming it is installed globally):
$ composer require xsolve-pl/model-factory
For more information on Composer see its Introduction.
Usage examples
Implementing model factory
This library defines a simple interface for model factory that provides
information about whether it supports given object (i.e. is able to produce
model object appropriate for given object) and instantiate such model object.
It also include convenient methods allowing to operate on multiple objects at
once. See Xsolve\ModelFactory\ModelFactory\ModelFactoryInterface for
more details.
One you are free to implement this interface with your own model factory
classes, a basic abstract class for model factory is included as well in
Xsolve\ModelFactory\ModelFactory\ModelFactory. It includes all the
necessary logic and leaves out only a public supportsObject method and a
protected instantiateModel method to be implemented. Using it as a base
class creating a new model factory class becomes very easy:
<?php namespace Example; use Xsolve\ModelFactory\ModelFactory\ModelFactory; class FooModelFactory extends ModelFactory { /** * {@inheritdoc} */ public function supportsObject($object) { return ($object instanceof Foo); } /** * {@inheritdoc} */ protected function instantiateModel($object) { /* @var Foo $object */ return new FooModel($object); } }
Using external dependencies in model
There are cases where some external dependency is required in model object to return some value. Simple example would be having an model object representing a package for which volumetric weight needs to be calculated (which results from multiplying its volume by some coefficient specific for each shipment company). A helper class calculating such value would usually be defined as a service in DI container, with coefficient provided via some config files or fetched from some data storage.
With this library it is extremely easy to gain access to such services in model
object by utilizing
Xsolve\ModelFactory\ModelFactory\ModelFactoryAwareModelInterface. If
Xsolve\ModelFactory\ModelFactory\ModelFactory was used as a base class
for your model factory class, then every model implementing aforementioned
interface will be injected with model factory that was used to produce it.
Since model factories can be defined as services themselves, they can be
injected with any service from DI container and can expose public proxy methods
for model objects to access them.
Following example presents sample usage of this interface. First we define model factory class:
<?php namespace Example; use Xsolve\ModelFactory\ModelFactory\ModelFactory; class BazModelFactory extends ModelFactory { /** * @var VolumetricWeightCalculator */ protected $volumetricWeightCalculator; /** * @param VolumetricWeightCalculator $volumetricWeightCalculator */ public function __construct(VolumetricWeightCalculator $volumetricWeightCalculator) { $this->volumetricWeightCalculator = $volumetricWeightCalculator; } /** * @return VolumetricWeightCalculator */ public function getVolumetricWeightCalculator() { return $this->volumetricWeightCalculator; } /** * {@inheritdoc} */ public function supportsObject($object) { return ($object instanceof Baz); } /** * {@inheritdoc} */ protected function instantiateModel($object) { /* @var Baz $object */ return new BazModel($object); } }
Our model class would look as follows (note that
Xsolve\ModelFactory\ModelFactory\ModelFactoryAwareModelTrait is
used here to provide convenient setModelFactory and getModelFactory methods):
<?php namespace Example; use Xsolve\ModelFactory\ModelFactory\ModelFactoryAwareModelInterface; use Xsolve\ModelFactory\ModelFactory\ModelFactoryAwareModelTrait; class BazModel implements ModelFactoryAwareModelInterface { use ModelFactoryAwareModelTrait; /** * @var Baz */ protected $baz; /** * @param Baz $baz */ public function __construct(Baz $baz) { $this->baz = $baz; } /** * @return float */ public function getVolume() { return ($this->baz->getLength() * $this->baz->getWidth() * $this->baz->getHeight()); } /** * @return float */ public function getVolumetricWeight() { return $this ->getModelFactory() ->getVolumetricWeightCalculator() ->calculate($this->getVolume()); } }
Grouping model factories into collections
To make it easy to produce models for multiple objects it is possible to group model factories into collections. If your application provides multiple API (or multiple API versions that are so different that they utilize completely different models) you are able to group factories in separate collections and avoid the risk of producing incorrect models.
Basic implementation of model factory collection is provided in
Xsolve\ModelFactory\ModelFactoryCollection\ModelFactoryCollection
class. It allows to register multiple model factories via its
'addModelFactory` method and provides same interface as a single
model factory, so that it is completely interchangable. Its methods attempt
to find appropriate model factory for each object provided.
<?php namespace Example; use Xsolve\ModelFactory\ModelFactoryCollection\ModelFactoryCollection; $fooModelFactory = new FooModelFactory(); $bazModelFactory = new BazModelFactory(); $modelFactoryCollection = new ModelFactoryCollection(); $modelFactoryCollection ->addModelFactory($fooModelFactory) ->addModelFactory($bazModelFactory); $foo1 = $storage->getFoo(1); $baz1 = $storage->getBaz(1); $foo1Model = $modelFactoryCollection->createModel($foo1); $baz1Model = $modelFactoryCollection->createModel($baz1);
This snippet defines one model factory collections $modelFactoryCollection and two model
factories $fooModelFactory and $bazModelFactory which are added to the collection.
Afterwards it is possible to call createModel method (as well as other methods
characteristic for model factories) on the collection and model will be created as long as
there is one and only one model factory supporting given object.
Creating nested models
In some cases the models you would like to produce can contain other models (e.g. produced for objects associated with the root object). If this nesting is deep (as it may be for some APIs optimized for SPA applications that aim to reduce number of requests required to fetch data) it becomes tedious to build all models upfront and connect them in a proper way. An easier solution is to empower models to be able to produce nested models on their own via the same model factory collection that was used to instantiate themselves.
To achieve this your model may implement
Xsolve\ModelFactory\ModelFactoryCollection\ModelFactoryCollectionAwareModelInterface
which will result in model factory collection that was used to create the model
to be injected to it. The basic implementation of this interface is provided in
Xsolve\ModelFactory\ModelFactoryCollection\ModelFactoryCollectionAwareModelTrait.
Let's assume that previously presented Example\Foo class object contains a
property containing an array of Example\Baz class objects and we want this
association to be carried to model objects as well. If both Example\FooModelFactory
and Example\BazModelFactory are a part of the same model factory collection
and instances of Example\FooModel class are instantiated via collection's
createModel or createModels methods of this collection, implementation of
Example\FooModel class could look as follows:
<?php namespace Example; use Xsolve\ModelFactory\ModelFactoryCollection\ModelFactoryCollectionAwareModelInterface; use Xsolve\ModelFactory\ModelFactoryCollection\ModelFactoryCollectionAwareModelTrait; class FooModel implements ModelFactoryCollectionAwareModelInterface { use ModelFactoryCollectionAwareModelTrait; /** * @var Foo */ protected $foo; /** * @param Foo $foo */ public function __construct(Foo $foo) { $this->foo = $foo; } /** * @return BazModel[] */ public function getBazs() { return $this ->getModelFactoryCollection() ->createModels($this->foo->getBazs()); } }
Of course if Example\BazModel implements the same interface it will also be
injected with the same model factory collection and will be able to produce
models for nested objects - it's as easy as that!
xsolve-pl/model-factory 适用场景与选型建议
xsolve-pl/model-factory 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 17.05k 次下载、GitHub Stars 达 3, 最近一次更新时间为 2017 年 11 月 24 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「rest」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 xsolve-pl/model-factory 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 xsolve-pl/model-factory 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 xsolve-pl/model-factory 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A PSR-7 compatible library for making CRUD API endpoints
Api bundle
A Flickr wrapper to allow you to call the Flickr api with Guzzle as the backend.Goal is to have 100% Flickr api coverage rather than just upload/display photos (currently at 23%).
BlockCypher's PHP SDK for REST API
Helper classes for creating cookie headers
支付宝开放平台v3协议文档,支持最新版PHP8+
统计信息
- 总下载量: 17.05k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 3
- 点击次数: 8
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2017-11-24