You are reading a single comment by @allObjects and its replies. Click here to read the full conversation.
  • Subject domains are like silos and in silos separation of concerns is applied.

    For example, the date subject has subject specific data (and calculation/behavior) and subject specific formatting. Other subjects are: Numbers, bank accounts, address, etc. Subjects are also composition of other subjects.

    So far, we just talked about subject specific separation of concerns.

    Cross-cutting concerns are concerns that are across all subjects / across the silos / horizontal - not subject specific - and this is for example logging, security/access control/... etc. Most of the time, these cross-cutting things are services/servers and clients to domain specific clients.

    In other words, 'the world' is diced and sliced in two dimensions, and some of the pieces are logically and physically 'shared': The logging has a domain specific component and a cross domains shared generic component: invocation of the logging - what to log (and often also some of the configuration info of the logging)- is a domain specific and the actual writing/appending to the log is generic and common to all domains.

    There are programming paradigms to generalize and separate also the specific components to keep the domain code as concise as possible. A good example for that is aspect oriented (ao) programming.

    Javascript is especially nice to this idea, because it can be dynamically / at runtime changed... (in java, it is a bit more difficult, but still doable... therefore annotations are used to 'inject' the code at build / compile time). In JavaScript, ao can be applied even when only programming with functions.

    For an example, let's assume we have a add(summand1, summand2){ ... }function:

    function add(summand1, summand2) {
      return summand1 + summand2;
    }
    

    Now, we want to have (configurable, conditional) logging for before and after - in other words: log the parameters (input) and log the returned result (output).

    Easy, p(l)easy! you say... but it may not really be pleasant...

    function add(summand1, summand2) {
      console.log("add(summand1:" + summand1 + ", " + summand2 +"){...");
      var result = summand1 + summand2;
      console.log("add(summand1:" + summand1 + ", " + summand2 +"){...}:" + result);
      return result;
    }
    

    Ooooookaaaaay... you got your (1st round of) logging (the configurable/conditional we put off for later... and ...never), but you also change the code not just by adding but also in structure: you had to temp store the result for the logging the way the it was.

    function add(summand1, summand2) {
      return summand1 + summand2;
    }
    
    // function to add before and after logging to add function while keeping add's implementation
    function addLogging() {
      var add_f = add;
      add = function(summand1, summand2) {
        console.log("add(summand1:" + summand1 + ", " + summand2 +"){...");
        var result = add_f(summand1, summand2);
        console.log("add(summand1:" + summand1 + ", " + summand2 +"){...}: " + result);
        return result;
      };
      add._logging = add_f;
    }
    
    // remove logging
    function removeLogging() {
      add = add._logging;
    }
    
    // using the last result and add() function in a watch on BTN1
    // even last (result) turns green LED on and red LED off
    // odd last (result) turns red LED on and green LED off
    var last = 0;
    setWatch(function(){
        last = add(last,1);
        digitalWrite(LED1, last % 2);
        digitalWrite(LED2, (last + 1) % 2);
      }, BTN1, {repeat: true, edge: "falling", debounce:20});
    

    Go through these steps after uploading of above code snippet:

    • Enter add(1,2) in console: Console shows =3.

    • Enter addLogging(); to add logging to the add() function.

    • Enter add(1,2) in console again: console shows the logging and =3:

      >add(1,2)
      add(summand1:1, 2){...
      add(summand1:1, 2){...}: 3
      =3
      >
      
    • Entering removeLogging(); will remove logging from the add() function.

    • Enter add(1,2) in console again: console shows just =3 again.

    Now, we want to use the button BTN1.

    Pressing button BTN1 will alternately lite red and green (Pico and Original) onboard LED. But how do we know if odd result shows red LED on, and even green LED?

    We add logging and compare log output in console with lit LED.

    Conclusion: This brief exercise shows conceptually how logging can be added without changing the implementation.

    NOTE: Real world is much more sophisticated and does not have issues like this example (after upload enter in console bad = add, then addLogging(), then add(1,2), and finally bad(1,2). What do you observe and what is the explanation?)

About

Avatar for allObjects @allObjects started