title: application design, object oriented not desirable?
body: <p>Long post ahead.</p>
  
  <p>I have to write a business application and I came to a conclusion that conventional way of doing this is a poor choice. I will expose here my point of view and would like to hear some opinions, and critics, or, inversely, some confirmation of my thoughts.</p>
  
  <p><strong>CONTEXT</strong>:</p>
  
  <p>A Company sells some highly complex financial contracts. External Clients contact this company in order to ask for a price. They provide a set of parameters of the product they wish, this is used to make a Price. The provided parameters are not totally explicit: clients usually buys a specific product, so a very large number of parameters is implicit, and only known by the Salesman who is in charge of this particular Client for this particular Country.</p>
  
  <p>The salesman wants to automate the pricing process. Obviously, his knowledge is the only way for me to rightly make a request for Price, because of all implicit parameters for each specific client, and each specific Salesman. From the Sales side, all Financial Products are categorized by their Family. From the IT side, there is only a huge flat list of all possible parameters, and a certain combination of them makes what a Salesman calls "Product A" or "Product B".</p>
  
  <p>The application is supposed to map Salesman perspective into IT perspective and give back a price.</p>
  
  <p><strong>EXTENDING AN EXISTING SOLUTION:</strong></p>
  
  <p>Product Families are pretty good proxies for Object Hierarchies and inherit from each other. A large number of parameters are set by default, or overridden in child classes. The problem is however, the class' methods are not only dependent on the number of parameters, or their types, but also dependent on some commercial logic, like the specific Salesman, specific Client (that's the whole point), or Country. Obviously, Clients and Salesmen can be added or removed quickly, so it is highly desirable to also 'parametrize' this. Here is an example of how this would look like (at least, how I imagine it):</p>
  
  <pre><code>class AbstractProduct:
      pass
  
  class ProductA(AbstractProduct):
      def __init__(self, a,b, ... z, client_name=None, sales_name=None ...):
          self.a=a
          # ....
  
  
      def make_a_price(self):
          if self.sales_name == "A.J" and self.client_name="Homer.S":
              request = {
                  "a":self.a,
                  "b":self.b,
                  "c": 23,
                  "d":"blah"
              }
          elif self.sales_name =="B.J" :
              request = {
                  "a": self.a,
                  "b": self.b,
                  "c": 23,
                  "d": "tom",
                  "e":"dummy",
                  "f":"dummy"
              }
          else:
              request = {
                  "K":42
              }
          # ...
          # ...
          request["common_parameter1"]="a"
          request["common_parameter2"]="b"
          # ...
  
          price = send_request_for_price()
          return price
  </code></pre>
  
  <p><strong>ISSUES:</strong></p>
  
  <p>It seems to me that mixing any kind of commercial logic inside the price-requesting logic is nonsense because:</p>
  
  <ul>
  <li><p>I need updating my code base for any kind of commercial reason</p></li>
  <li><p>I do not hold any domain knowledge, so I might break something for a product, or a client while modifying a feature for another client... I cannot guarantee that there is no regression (extensive testing is required)</p></li>
  <li><p>Once again, I do not hold any domain knowledge, so I cannot draw any conclusion for inheritance or composition relationships between objects.</p></li>
  <li><p>Adding <code>if</code> statements to check for Salesman / Client / Country whatever is silly</p></li>
  <li><p>I could create a bunch of factories, but this only moves complexity higher: I would end up dealing with commercial cases at the Object level, instead of variables level.</p></li>
  <li><p>Well, just because commercial logic (country/sales/client-specific implicit parameters) has nothing to do with pricing.</p></li>
  </ul>
  
  <p><strong>PROPOSED SOLUTION:</strong></p>
  
  <p>A 'Product' is just a set of parameters, some of them are constant within a commercial scope (for a particular client/country/..), and some of them are free (Free +  Constant = entire Univers). So let's store in a database all constant parameters with a commercial scope as primary key.</p>
  
  <p>All free parameters left must have a function which returns exactly this parameter as result. Store these functions names in the database too. These functions are composed of other functions etc... and so recursively, until all composed functions are decomposed into 'atomic functions' which takes only variables, or None as parameters (no other functions), and can have validation functions (predicates, which only return True / False, so that the parameter is in a good format). Store all of those functions and their parameters names in the database. </p>
  
  <p>Write an 'Evaluator' which, for a given commercial scope, reads from the database a sequence of constant parameters and set them into price request; as well as a list of the functions to run in order to set Free parameters. This Evaluator breaks down composed functions into atomic once, and recursivly calls them within the context. Validation functions are run before each atomic function (if there is any)</p>
  
  <p><strong>What does this buys me?:</strong></p>
  
  <ul>
  <li>I can guarantee that there are no regressions since each function is 'unique' and attached to an ID in my database (no code sharing through inheritance or composition)</li>
  <li>No business logic in my code</li>
  <li>Straightforward implementation (at least, in my opinion): each function is completely independent, and Evaluator is 30 lines long (not counting SQL requests)</li>
  <li>If a new commercial rule is introduced or replaced, I just need to re-point my database entry to another function</li>
  <li>I can add new parameters to functions, and new format-validating functions for each parameter as simply as adding rows in my database.</li>
  </ul>
  
  <p>So... profit?</p>