patternphpMinor
OOP Decision Maker Class - ServerArbiter
Viewed 0 times
oopserverarbiterdecisionclassmaker
Problem
I am writing a
Basically, a server will be chosen depending on various factors. One may be 'server load'. Imagine this arbiter is used to decide which server to add a torrent to - it will choose the server with the least number of torrents in the download queue.
Architecture
My current architecture for this solution consists of a
The
And the actual
A
Rules
I currently have rules such as the
For torrents example described above, I was going to have a
```
class ServerDownloadsComparisonRule
{
/**
* @var Server[]
*/
private $servers;
public function __construct(array $servers)
{
// -- SNIP --
// Make sure each $server is instance of Server entity
// -- SNIP --
}
public function resolve(Server $server)
{
// I'm guessing this is where I will compare the downloads to get the one
ServerArbiter, the job of which is to make a decision about which server to "choose" given a set of rules. The aim is to be able to add / remove rules at will - for ease of future maintenance. My language of choice is php, so please bear this in mind when answering.Basically, a server will be chosen depending on various factors. One may be 'server load'. Imagine this arbiter is used to decide which server to add a torrent to - it will choose the server with the least number of torrents in the download queue.
Architecture
My current architecture for this solution consists of a
ServerArbiter object:public function __construct(RuleSet $ruleSet, array $servers);The
RuleSet is effectively just a list of Rule objects that implements \Iterator so it can be foreach()d around.public function addRule(Rule $rule);And the actual
Rule objects implement the Rule interface:public function resolve(Server $server);A
Server is just a (doctrine) Entity - that is, it contains class members, setters and getters, and some validation. These properties are populated with data from the servers database table. One of the properties is ipAddress.Rules
I currently have rules such as the
ServerActiveRule, which is just a property that is returned.class ServerActiveRule implements Rule
{
/**
* {@inheritdoc}
*/
public function resolve(Server $server)
{
return $server->isActive();
}
}For torrents example described above, I was going to have a
ServerDownloadsComparisonRule:```
class ServerDownloadsComparisonRule
{
/**
* @var Server[]
*/
private $servers;
public function __construct(array $servers)
{
// -- SNIP --
// Make sure each $server is instance of Server entity
// -- SNIP --
}
public function resolve(Server $server)
{
// I'm guessing this is where I will compare the downloads to get the one
Solution
- Why does the
decide()method do more work? It's the problem of the object constructing your Rules, which is not necessarily theServerArbiter.
- Isn't that already a part of the
Serverentity? Why do you need to inject yet another dependency. If the server's address isn't in theServerentity, why the hell the server's address isn't in theServerentity?!
- Your architecture is fine. Easily separated,
Serversdon't know about theRules.
-
Yes. Since querying all the servers to get their downloads count, it makes sense to remember the best server in the
ServerDownloadsComparisonRule the first time resolve is called, and then just reference it from the cache.if ($bestServer == null) {
$bestServer = $this->findServerWithLeastDownloads();
}
return $server === $bestServer;Code Snippets
if ($bestServer == null) {
$bestServer = $this->findServerWithLeastDownloads();
}
return $server === $bestServer;Context
StackExchange Code Review Q#52515, answer score: 2
Revisions (0)
No revisions yet.