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– User07/09/2015 10:32:19Commented Jul 9, 2015 at 10:32
3 Answers 3
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 aService
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 asRelatedProductsService
?Dennis– Dennis07/08/2015 22:12:55Commented Jul 8, 2015 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– Alexus07/09/2015 00:28:27Commented Jul 9, 2015 at 0:28
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.
-
2I disagree that the strategy pattern is useful for that. It is about varying the algorithm. In this case the algorithm does not vary.User– User07/09/2015 10:16:06Commented Jul 9, 2015 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– umlcat07/15/2015 16:54:14Commented Jul 15, 2015 at 16:54
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
butCombineMotorsAndProducts
- rename the method
combineProductsAndMotors
tocompute
.
-
Just to be clear, this is a refactoring, rather than a pattern.Ben Aaronson– Ben Aaronson07/09/2015 11:34:00Commented Jul 9, 2015 at 11:34
Explore related questions
See similar questions with these tags.