Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are many ways you can implement this in code, but here is in my humble opinion, the best way to go about solving the problem before programming anything:</p> <h3>Define Parts &amp; Products (Pre-code)</h3> <p>When defining all the "parts" it will be paramount to identify hierarchy and categorization for the parts. This is true because some rules may be exclusive to a unique part <em>(ex. "brown mustard only")</em>, some categorical <em>(ex. "all mustards")</em>, some by type <em>(ex. "all condiments")</em>, etc.</p> <h3>Build Rule Sets (Pre-code)</h3> <p>Define the rule sets (prerequisites, exclusions, etc.) for each unique part, category, type, and finished product.</p> <p>It may sound silly, but a lot of care must be taken to ensure the rules are defined with an appropriate scope. For example, if the finished product is a <code>Burger</code>:</p> <ul> <li>Unique Item Rule - <em>"Mushrooms only available with Blue Cheese selected"</em> <code>prerequisite</code></li> <li>Categorical Rule - <em>"Only 1 mustard may be selected"</em> <code>exclusive</code></li> <li>Type Rule - <em>"Pickles are incompatible with Peppers"</em> <code>exclusive</code> </li> </ul> <p>After having spent so much time on unique/category/type rules for "parts", many designers will overlook rules that apply only to the finished product even when the parts have no conflict.</p> <ul> <li>Product Rule - <em>"Maximum 5 condiments"</em> <code>condition</code></li> <li>Product Rule - <em>"Burger must have a bun"</em> <code>prerequisite</code></li> </ul> <p>This graph of rule can quickly grow very complex.</p> <h3>Suggestions for Building Data Structures (Code)</h3> <ol> <li><p>Ensure your structures accommodate hierarchy and categorization. For example: "brown mustard" and "dijon mustard" are individual objects, and they are both mustards, and both condiments.</p> <p>Carefully select the right combination of inheritance modeling (base classes) and object attributes (ex. <code>Category</code> property, or <code>HasCondiments</code> flag) to make this work.</p></li> <li><p>Make a <em>private field</em> for <code>RuleSets</code> at each hierarchic object level.</p></li> <li><p>Make <em>public properties</em> for a <code>HasConflicts</code> flag, and a <code>RuleViolations</code> collection.</p></li> <li><p>When a part is added to a product, check against all levels of rules (its own, category, type, and product) -- do this via a <em>public function</em> that can be called from the product. Or for better internalization, you can make an <em>event handler</em> on the part itself.</p></li> </ol> <h3>Write your algorithms (Code)</h3> <p>This is where I suck, and good thing as it is sort of beyond the scope of your question. </p> <p>The trick with this step will be how to implement in code the rules that travel up the tree/graph -- for example, when a specific part has issue with another part outside its scope, or how does it's validation get run when another part is added? My thought:</p> <ol> <li><p>Use a <em>public function</em> methodology for each part. Pass it the product's <code>CurrentParts</code> collection.</p></li> <li><p>On the Product object, have handlers defined to handle <code>OnPartAdded</code> and <code>OnPartRemoved</code>, and have them enumerate the <code>CurrentParts</code> collection and call each part's validation function.</p></li> </ol> <h3>Example Bare-bones Prototype</h3> <pre><code>interface IProduct { void AddPart(); void OnAddPart(); } // base class for products public class Product() : IProduct { // private or no setter. write functions as you like to add/remove parts. public ICollection&lt;Part&gt; CurrentParts { get; }; // Add part function adds to collection and triggers a handler. public void AddPart(Part p) { CurrentParts.Add(p); OnAddParts(); } // handler for adding a part should trigger part validations public void OnAddPart() { // validate part-scope rules, you'll want to return some message/exception foreach(var part in CurrentParts) { part.ValidateRules(CurrentParts); } ValidateRules(); // validate Product-scope rules. } } interface IProduct { // "object" should be replaced with whatever way you implement your rules void object RuleSet; void ValidateRules(ICollection&lt;Part&gt; otherParts); } // base class for parts public class Part : IPart { public object RuleSet; // see note in interface. public ValidateRules(ICollection&lt;Part&gt; otherParts) { // insert your algorithms here for validating // the product parts against this part's rule set. } } </code></pre> <p>Nice and clean.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload