I'm coding a solution builder (exercise). The user story is that an agent defines the customer and the desired solution. In this case I'm focused on just a Phone System solution. The agent fills out a set of predefined Requirements for the solution. The system then reads the requirements, determines which hardware, software, and licenses are needed to implement the solution. It repeats this for all applicable phone system solution, i.e., one set of requirements spawns multiple possible solutions.
What I'm trying to determine are the correct patterns and classes that would allow me execute the above and remain open to the additional solution types and addition solutions for this Phone System type.
Am I approaching (see below) this correctly and am I using the correct patterns and division of logic for my classes?
My structure is:
At the lowest level I've a bunch of classes implementing a RuleInterface with just the determineItem() method. Item can be hardware, software, licenses. I am using a strategy pattern as these rules can be mix-match. This should be using the Strategy pattern, correct?
Example:
public class VendorAlphaPbxSelection implements RuleInterface{
public function determineItem(array $params)
{
if ($params['max_phones'] <= 150 && $params['max_concurrent'] <= 50) {
return "alpha_pbx_small";
}
if ($params['max_phones'] <= 300 && $params['max_concurrent'] <= 100) {
return "alpha_pbx_medium";
}
if ($params['max_phones'] <= 600 && $params['max_concurrent'] <= 200) {
return "alpha_pbx_large";
}
return false; // if no option found
}
}
I know that I need to be able to assign a bunch of rules to a yet another strategy, e.g., I've the VendorAlphaCloudStrategy, VendorBravoCloudStrategy, VendorCharliePremiseStrategy, VendorCharlieCloudStrategt solutions / classes.
So I wrote the following:
class VendorAlphaCloudStrategy implements SolutionStrategyInterface {
private $phone_rule;
private $power_adapter_rule;
private $license_rule;
private $rate_rule;
private $usage_rule;
private $porting_rule;
public function __construct(
RuleInterface $phone_rule,
RuleInterface $power_adapter_rule,
RuleInterface $licence_rule,
RuleInterface $rate_rule,
RuleInterface $usage_rule,
RuleInterface $porting_rule
)
{
$this->phone_rule = $phone_rule;
$this->power_adapter_rule = $power_adapter_rule;
$this->licence_rule = $licence_rule;
$this->rate_rule = $rate_rule;
$this->usage_rule = $usage_rule;
$this->porting_rule = $porting_rule;
}
// getters and setters here
}
Only... I've no method for the SolutionStrategyInterface as there are no common methods. So far I'm only using it for the polymorphism since I don't know which solution's strategies will be assigned to my solution.
but now I am stuck. I know that I will have a class that implements this strategy and that this strategy needs to return a list of items, but what is needed to make this class work (besides getters and setters)? Are there other patterns I should be considering? Basically the CloudPhoneSystem classes should execute processRequirements, the requirements need to somehow get to the right rule, and that rule needs to return the correct item to the CloudPhoneSystem.
I think I'm having trouble because my strategy (VendorAlphaCloudStrategy) is also using another strategy just for the individual rules.
Or am I overthinking this somewhere and just need to move properties and methods around to different classes? Any helping pointing me in the right direct would be greatly appreciated. I feel like it is something really, really obvious, but I'm just blind to it.
The other classes are:
class AbstractPhoneSystem {
protected $items;
protected $solution_strategy;
protected $requirements;
public function __construct(
SolutionStrategyInterface $solution_strategy,
RequirementInterface $requirements
)
{
$this->solution_strategy = $solution_strategy;
$this->requirements = $requirements;
}
abstract public function processRequirements();
// getters and setters here
class CloudPhoneSystem extends AbstractPhoneSystem
{
public function processRequirements()
{
// run template for cloud rules
}
}
class PremisePhoneSystem extends AbstractPhoneSystem
{
public function processRequirements()
{
// run template for on-premise rules
}
}
Aucun commentaire:
Enregistrer un commentaire