atrauzzi / domain-tool
Conventions and many favourite utility methods for your domain libraries!
Requires
- php: >=5.5
This package is not auto-updated.
Last update: 2016-09-28 18:16:57 UTC
README
Premise
When authoring domain code, it's almost guaranteed that you'll end up hand-coding many similar operations for a number of classes. Amongst these chores could be things like:
- Assigning to and accessing data from multiple attributes via an array
- Copying state from models to view models
- Writing or generating and maintaining "empty" getter and setter methods
- Obtaining a list of the attributes on a model, sometimes all, sometimes based on a whitelist
- Converting an object to an array, sometimes based on a whitelist
- Casting instances of one class to another up or down their inheritance chain
If any of these seem boring to you, then you're right on the money. They typically are, and yet they're also some of the most common features you leverage when using base model classes and ORMs.
In the simplest of scenarios, this library might seem like overkill. Many base model classes implement __call
, __get
and __set
to
expose attributes at runtime. It usually comes to pass however that you'll end up writing extra code to manipulate the variety of
ways PHP model classes can be defined and made to contain and expose their state.
Before getting too far in, with or without Domain Tool, you're more than welcome to continue leveraging those mechanisms in your projects!
Beyond simple data access however, this library aims to provide functionality and compatibility not found in every base model or ORM library. Domain Tool is a spectrum - you can use it for one utility, or you can buy in completely.
Use as little or as much as you want! :)
"I already have an ORM that does these things for me"
Many of the features found in this library are inspired by ORMs. Specifically ActiveRecord-style libraries which blend the concepts of repositories and domain models together into one class. There are some schools of thought however which put forward that some flexibility is lost and code risks being repeated or becoming complex as a result of ActiveRecord design patterns.
The best summary of what this library aims to facilitate is separation. If you are not taking a layered approach to your domain development, then you may not have immediate need for this library.
That said, it will be a testament to it's flexibility for this library to support being added to any solution where an ORM is used to facilitate a layered design. With the right adapter, and correctly coded layers, you will be able to target models regardless of whether they are aware of this library or not.
"Serialization? Aren't there others out there?"
Yes! In my experience as a REST API developer however, I've found that serialization is tricky thing to solve conveniently. Many serializer libraries attempt to simplify this chore and get pretty close. That said, I've found two distinct approaches to serialization which Domain Tool supports:
Serialization Profiles
With the first approach, you simply want somewhere to define a whitelist of rules for your models. This can be done with
Domain Tool's profiles using in
and out
lists. You can even map attributes to different incoming and outgoing names if desired.
View Models
In other scenarios, you may wish to author a view model. In this case, you only need to set up an adapter for the class. When the time comes to serialize, all attributes that the adapter can infer will be serialized. Domain Tool also offers methods to populate a view model from original data via fill and dump! View models are now a snap!
Usage
There are two ways you can use this libary.
Static Utility Methods
All of this library's functionality is driven by static utility methods which perform single operations and accumulate no state.
Simply call the desired method - it will do what it says on the label! Until the library reaches it's first release, take a look at
the public static methods defined in Atrauzzi\DomainTool\Service
.
Interface + Trait
An interface and trait are supplied if you don't mind taking a dependency on this library in your domain models. This technique ends up calling back to the static utility methods, but makes usage a little more familiar for people used to the more idiomatic ActiveRecord style syntax.
Glossary
As it turns out, often times a library will resort to using multiple, ambiguous terms to define the problem domain it aims to solve. To address this, I'm maintaining a list of all the terms you will encounter over regular use of Domain Tool. If something doesn't seem quite clear, find it here. If it's missing or I've used it incorrectly, open a ticket and let me know!
Attribute
In this library (and by way of it, yours), attributes exist on your models and are typically defined as such:
/** @var int */
protected $id;
/** @var string */
protected $firstName;
/** @var boolean */
protected $enabled;
An attribute fully defined is the combination of a class property and any getters and setters present for it. Model adapters may extend this definition depending on how the underlying models they access choose to expose metadata.
Attribute Array
An attribute array defines a by-value subset of all the state of a model's values.
[
'id' => null,
'first_name' => 'Bucky',
'enabled' => true
]
This might seem like an overcomplication of what is really just "an array" in PHP, but this definition
helps in practice. You will often see the name $attributes
, which intends one of these structures.
Model Adapter
A class that knows how to obtain data and metadata about a specific type of model class.
Profile
Profiles store sets of configuration options for Domain Tool's various utility methods.
- Which variables can be assigned
- Which variables can be read
A familiar example of where this would be useful is during [de]serialization. Oftentimes you only want to work with a subset of the attributes or methods found in a model.
Profile Loader
A class that knows how to retrieve profile configuration within a specific environment. Without one configured, Domain Tool will assume some common conventions for attribute access and permissive input and output behaviours.
Meta
Upcoming Libraries
Domain Tool will be facilitating a few more libraries to assist with writing nicely layered code:
- Domain Tool for Laravel
- Domain Service Tool
Stay tuned! I will link them up here as they are created.
License
Domain tool is free for anyone to use and modify. I accept no responsibility for what happens as a result of using this library and make no guarantees as to it's production readiness or availability.