PHPackages                             timehunter/delivery-order-test - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. timehunter/delivery-order-test

ActiveLibrary

timehunter/delivery-order-test
==============================

:description

03PHP

Since Mar 9Pushed 7y agoCompare

[ Source](https://github.com/RyanDaDeng/delivery-order-test)[ Packagist](https://packagist.org/packages/timehunter/delivery-order-test)[ RSS](/packages/timehunter-delivery-order-test/feed)WikiDiscussions master Synced today

READMEChangelogDependenciesVersions (3)Used By (0)

DeliveryOrderTest
=================

[](#deliveryordertest)

[![Coverage Status](https://camo.githubusercontent.com/3570159a3357b4a6756b3deafa9b1a88ed34b7c773c3c93d3b471f576ea34e25/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f5279616e446144656e672f64656c69766572792d6f726465722d746573742f62616467652e7376673f6272616e63683d6d617374657226736572766963653d676974687562)](https://coveralls.io/github/RyanDaDeng/delivery-order-test?branch=master)[![Build](https://camo.githubusercontent.com/fb584292af656e0f3cb500598bf9b3abd54018766d7974ae9476cc1b3674603c/68747470733a2f2f7472617669732d63692e6f72672f5279616e446144656e672f64656c69766572792d6f726465722d746573742e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/RyanDaDeng/delivery-order-test)[![StyleCI](https://camo.githubusercontent.com/af140be81fbca337426e7c00daaf031582a250293e3501b5e330e85368cc8415/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f3137343632393530312f736869656c64)](https://github.styleci.io/repos/174629501)

15th March 2019 Update
----------------------

[](#15th-march-2019-update)

I just quickly added a new alternative approach by using Strategy pattern under DeliveryOrderModule/Strategy folder. Strategy pattern is good to be used when the class needs to be fully decoupled and distributed to anywhere.

Note: I haven't added test for Strategy pattern yet. Honestly, I still prefer Template method, all the duplicate code put into super class so that all subclass share those code. And the requirement clearly states each of delivery order has its own workflow which is a perfect usage to define steps in super class (AbstractDeliveryOrderProcessor)

(Strategy pattern is just a bonus showcase and it doesn't have test etc....)

Description
-----------

[](#description)

The solution is written on Laravel framework.

Installation
------------

[](#installation)

1. This is a Laravel composer package, you need to have a Laravel installed first.
2. Via Composer

```
$ composer require timehunter/delivery-order-test
```

Question Analysis
-----------------

[](#question-analysis)

Potential design patterns can be used for this problem: factory, template method and strategy

The problem can be categorised as the following points:

1. How to create different objects based on dynamic input value? e.g. “enterpriseDelivery” return EnterpriseDelivery object

- use Factory pattern which encapsulates the logic of creating objects.

2. Different object should contain its own workflow and dependent services.

- use Strategy pattern(interface) or template method(inheritance)

3. Domain driven design

- Basically make the system as module based and each module has its own services. If there are any common interfaces, they can be shared across different module.
- From the question mentioned, I can see there are three modules can be found: Delivery Order module, Third party module and Marketing module

My solution
-----------

[](#my-solution)

#### Assumptions

[](#assumptions)

1. Marketing service and Third Party api service have been fully tested.

#### Designs

[](#designs)

1. I use Template Method design pattern which is based on inheritance. It allows me modify parts of an algorithm by extending those parts in sub-classes.
2. I also use factory pattern to determine which type of delivery order object I need to return.

[![](https://github.com/RyanDaDeng/delivery-order-test/raw/master/template_method.jpg)](https://github.com/RyanDaDeng/delivery-order-test/blob/master/template_method.jpg)

Note:

1. As mentioned in the question, the EnterpriseDelivery Order needs to be validated with third party api first, if its failed, the logic should no longer continue. In this case, I have a defined steps in the abstract class, e.g. check validation first, then do the logic.

```
....
    public function process()
    {
        if ($this->validate()) {
            $this->before();
            $this->handle();
            $this->after();

            return true;
        } else {
            return false;
        }
    }
....
```

The handle function is an abstract function which will be implemented for all sub-classes. Use this function to define its own workflow.

Usage
-----

[](#usage)

```
 $json = "[{},{},{}...{}]"; // the given sample json data
 $service = new DeliveryOrderService($json);
 $objects = $service->processJson() // this return a list of different delivery order objects

```

Testing
-------

[](#testing)

1. use PHPUnit
2. Mocking Interfaces for testing
3. Pass different json to test if the service returns the correct delivery type
4. use travis-ci for CI/CD:

Improvements &amp; Relecftions
------------------------------

[](#improvements--relecftions)

1. The package does not use Laravel feature e.g. service containers, facades. They can be applied by creating service provider to register their dependencies.
2. API service and marketing service can be singleton.
3. If any new delivery order type comes in, we just need to create a new sub-class which extends Abstract base class without touching source code (open for extension).
4. Strategy pattern can be used instead of inheritance if the interface and design are finalised.
5. Exception handler can be implemented on the top of abstract class.

###  Health Score

19

—

LowBetter than 10% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/957c97ad667a07032424eb2eb70cf2db7ad705c62926c23436f9ea4e32dca5b5?d=identicon)[timehunter](/maintainers/timehunter)

---

Top Contributors

[![RyanDaDeng](https://avatars.githubusercontent.com/u/37111049?v=4)](https://github.com/RyanDaDeng "RyanDaDeng (24 commits)")

### Embed Badge

![Health badge](/badges/timehunter-delivery-order-test/health.svg)

```
[![Health](https://phpackages.com/badges/timehunter-delivery-order-test/health.svg)](https://phpackages.com/packages/timehunter-delivery-order-test)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
