I would like to design software that has the following solution:
- Products have features.
- Each products has rules for features:
- Product must have features
a,b and d
.
_ Product must have at least x of list of features f,g and m
_ Each feature of product has a weight.
- At runtime I'd like to create products using, from external input (file/user input) and add features to the product with rules.
- I'd like ask each product, given the features it's been fed, what score it has and what's missing.
Let me illustrate the last point:
Let's say product A
has rules regarding must have features a and b
, must have at least 2 of c, d, e and f
and could also have (but not must) features g, h ,i and j
.
I've also assigned the following weights a,b each equal 5
, c, d, e and f each equal 10
and g, h ,i and j each equal 2.5
. (all in all 60 points)
Case 1:
Product a
of type A
has features a, c, d, h, j
. I'd like the following report:
Is not A because missing b
. Score = 0.5 ( (5 + 10 + 10 + 2.5 + 2.5) / 60 )
Can also receive b, e, f, g, i
Case 2:
Product b
of type A
has features a, b, c, e, h, j
. I'd like the following report:
Is A. Score = 0.5833 ( (5 + 5 + 10 + 10 + 2.5 + 2.5) / 60 )
Can also receive d, f, g, i
Here's what I've come up so far:
What would you recommend?
Thanks!
A domain model is useful (I think I got it right based on your text):
From there, I don't see enough variations in design (e.g., Product A
is just an instance of the Product
class, Feature a
is just an instance of the Feature
class) to justify patterns. Not even a Factory is needed, IMO. Am I missing something from your question?
As I understand that you got object who run the same logic (reports, scores and missing features). But you got different settings for each object, product A don't have the same settings than product B.
Then I think you can check the design pattern template : https://sourcemaking.com/design_patterns/template_method
It can help you to define the different rules of your product.
I am assuming that there will be text input for product e.g. A,a,c,d,h,j for case 1. Using Static factory for Products is good approach. Using strategy for Report generation is not correct. If your context for strategy is product then do you have a use case where Product-A at run time changes to Product-B? I guess NO. (Strategy is used when without changing State there is family of algorithms and its interchangeable). Here Products will contain different combinations of rules and features and hence state changes (No Strategy). I guess no additional design pattern is required.
Following OO design will work.
Abstract-Product contains Collection of Rules which is filled up in Concrete Product constructor. Abstract-Product also contains Collection of Features which is filled up while parsing ext data input String.
Feature is modeled as an enum with weight as param.
Rule is modeled as abstract class with abstract "boolean check()" which concrete rules override. concrete Rule requires product to access its collection of features, hence product to rules is bidirectional association.
When concrete product is configured from ext input String though static factory, we call generateReport() method which iterates over all rules in collection. each rule applies the rule and updates the violation String (if violated) with its specific message (part) (e.g. feature b is absent etc). generateReport() in ConcreteProduct makes consolidation of report message taking in to account violation messages.
Similar approach for weight computation as its only dependent upon the features.
So I guess only Static Factory is enough as a design pattern. Features can be instatiated by enum.ValueOf().
Here I suppose indirectly we will be using Bridge Design pattern between Product Hierarchy and Rule Hirrarchy by implementing generateReport() with the help of check() in Rule.