1

This is a Design question relating to finding out a good OO design pattern or design structure or class combination that can house an algorithm that processes user selection to produce product recommendations.

Scenario

User specifies Motor and Product requirements and hits Submit. Algorithm processes input, loads various motors and products, selects relevant motors and products as per specifications. It then combines them, computes various parameters of the combos, and also notes any discrepancies. Then, it provides an output in a form of valid product-motor combinations with computed specs, and also any discrepancies noted as warnings.

Question

Can I have an object called Algorithm, that is essentially a bundle of methods that loads Products, Motors, combines them, does computations on them, sets up various flags, etc? Or is there a better design?

Current Design

My current design came from procedural background and used to be just a series of functions, now housed in a couple of classes. Simplified algorithm is something like this (where Algorithm is a bundle of methods related to driving the algorithm, and BundleOfComputationalMethods that focuses on computational needs):

class Algorithm
{
    public $bundle;

    function __construct()
    {
        $this->bundle = new BundleOfComputationalMethods();
    }

    function getRequestDataFromPOST()
    {
        $this->bundle->options = $_POST;
    }

    function loadMotors(){}

    function loadProducts(){}

    function combineProductsAndMotors()
    {
        $this->getRequestDataFromPOST();

        $this->loadMotors();
        $this->loadProducts();

        for ($k = 1; $k <= $this->bundle->spec->max; $k++)
        {
            $this->bundle->computeRotationalSpeed();
            $this->bundle->checkIfSpeedWithinLimits();
            if ($this->bundle->speedIsOkay)
            {
                //bundle contains a "selection" to be presented back to the user
                //(Motor, Product, computed specifications, pricing, any warnings/errors)
                $result .= json_encode($this->bundle);
            }
        }

        return $result;
    }
}
  • I just read about AntiPatterns as it refers to procedural backgrounds, too. – User Jul 9 '15 at 10:32
2

I would improve on OOP part a bit.

Provide better naming:

You can to change Algorithm to something more specific like RelatedProductsService. Then, expose a method: getrelatedProducts($options)

Separate Your responsibilities:

You also want to avoid just passing POST along the class into it's children. That is a code smell and creates unnecessary dependencies. Have your caller of RelatedProductsService extract the post data into some structure and only what's needed and pass it inside as $options.

I would also move the functionality to load and combine engines, JSON encoding out as well into it's own classes. You have too many things crammed into one class :)

Good Read: Single Responsibility Principal

  • thanks. I think I am having trouble because a Service is not a physical entity :) And I am having trouble fitting a Service into my OOP model ... If OOP is about passing messages between objects, does this one in particular mean passing messages between Input and Output? So far this model really sounds more procedural rather than object oriented. (a method that takes input, does something, produces output). So is an OO equivalent is to wrap that method into a class and call it something, such as RelatedProductsService? – Dennis Jul 8 '15 at 22:12
  • No, in my answer I have proposed a number of separations in your code. Service is a balckbox providing certain output - example: returns you a list of related products. How it does it is not callees concern. Inside your service, you might use algorithms, etc. Object a lot of times doesn't represent real life entities, because there are rarely situation when you have program corresponding with 100% accuracy to reality. – Alexus Jul 9 '15 at 0:28
2

Can I have an object called Algorithm, that is essentially a bundle of methods that loads Products, Motors, combines them, does computations on them, sets up various flags, etc? Or is there a better design?

The Strategy Software Design Pattern seems to match the description of your post:

https://en.wikipedia.org/wiki/Strategy_pattern

This Pattern allows a method or group of methods to be treated as an "object", as you require.

Don't coerce yourself into using "Software Design Patterns" because are are a trend, use them because, may help you solve a problem.

  • 2
    I disagree that the strategy pattern is useful for that. It is about varying the algorithm. In this case the algorithm does not vary. – User Jul 9 '15 at 10:16
  • @User Yes, I did check that the algorithm did not change, yet the idea of encapsulating an action as an object applies. There are variations of this Design Pattern with different names, that apply to your case, but the "Strategy" name was first, while the other names varies, from one person to another ... – umlcat Jul 15 '15 at 16:54
0

The pattern that comes in to my mind when reading this is the "Method Object".

If you have a big method you transfer it into an object. The state of the method (e.g. arguments) can be part of the object attributes.

Changes I see immediately:

  • Do not name the class Algoritm but CombineMotorsAndProducts
  • rename the method combineProductsAndMotors to compute.
  • Just to be clear, this is a refactoring, rather than a pattern. – Ben Aaronson Jul 9 '15 at 11:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.