Friday, April 26, 2024
HomeMatlabHan Solo Revisited » Developer Zone

Han Solo Revisited » Developer Zone


A very long time in the past in a weblog put up far, far-off… Andy wrote about Han Solo Encapsulation – to maintain Jabba’s “system working as designed he wanted to encapsulate his system behind a rock strong interface”.

By a stroke of fine fortune, or even handed design selections relying in your perspective, a current refactoring job that I assumed may have far reaching penalties changed into just a few modifications in a single class, in the end saving a lot time. Let’s take a look.

My situation is that I’ve a DataProvider that accepts a DataRequest and returns some information:


classdef DataProvider
    
    strategies
        
        perform information = getData(dataProvider,dataRequest)

            arguments
                dataProvider (1,1) DataProvider
                dataRequest (1,1) DataRequest
            finish

            

        finish
        
    finish
    
finish

The DataRequest appears like this:


classdef DataRequest
    
    properties
        Make (1,1) string = lacking
        Mannequin (1,1) string = lacking
        ManufacturingYear (1,1) datetime = lacking
    finish
    
finish

It defines related properties that the DataProvider must serve up the information. All of the values are scalar and have default values of lacking to signify the truth that they’re “unset” by the person.

To kind its question, the DataProvider should extract the values of every property. To do that, it must know that “unset” is represented by “lacking” and due to this fact it needs to be ignored from the search situation.

Right here’s one doable implementation in DataProvider:


classdef DataProvider
    
    strategies
        
        perform information = getData(dataProvider,dataRequest)

            arguments
                dataProvider (1,1) DataProvider
                dataRequest (1,1) DataRequest
            finish
            
            searchTerms = {};
            propsToGet = ["Make" "ManufacturingYear" "Model"];
            
            for prop = propsToGet
                if ~ismissing(dataRequest.(prop))
                    searchTerms = [searchTerms {prop} {dataRequest.(prop)}];
                finish
            finish

            outcome = dataProvider.search(searchTerms{:});

            

        finish
        
    finish
    
finish

The issue right here is that DataProvider, and every other code that makes use of DataRequest, is coupled to how DataRequest represents its “unset” values. That’s one thing that needs to be encapsulated inside the DataRequest. What my DataProvider actually desires is an array of name-value pairs of non-missing property names and values.

(We may additionally describe this for example of the inform don’t ask precept since we’re not truly hiding DataRequest’s properties from the skin world.)

Let’s refactor the DataRequest so as to add a technique that does simply that. I’ve referred to as it namedargs2cell as a result of its similarity to the built-in MATLAB perform.


classdef DataRequest
    
    properties
        Make (1,1) string = lacking
        Mannequin (1,1) string = lacking
        ManufacturingYear (1,1) datetime = lacking
    finish
    
    strategies
        
        perform paramCell = namedargs2cell(dataRequest)
            
            arguments
                dataRequest (1,1) DataRequest
            finish
            
            paramCell = {};
            propsToGet = ["Make" "ManufacturingYear" "Model"];
            
            for prop = propsToGet
                if ~ismissing(dataRequest.(prop))
                    paramCell = [paramCell {prop} {dataRequest.(prop)}];
                finish
            finish
            
        finish
        
    finish
    
finish

This makes our DataProvider a lot easier:


classdef DataProvider
    
    strategies
        
        perform information = getData(dataProvider,request)

            arguments
                dataProvider (1,1) DataProvider
                request (1,1) DataRequest
            finish

            searchTerms = namedargs2cell(request);
            outcome = dataProvider.search(searchTerms{:});

            

        finish
        
    finish
    
finish

Returning to our encapsulation precept, what can we obtain? In my real-life case, I wished to vary the DataRequest to permit a number of values to be specified for a given property somewhat than simply scalars. It due to this fact is sensible to signify “unset” with an empty somewhat that with a scalar lacking. Since all information of how “unset” is represented is contained inside the DataRequest, the solely modifications I wanted to make had been inside DataRequest itself. No different code needed to be touched:


classdef DataRequest
    
    properties
        Make (1,:) string
        Mannequin (1,:) string
        ManufacturingYear (1,:) datetime
    finish
    
    strategies
        
        perform paramCell = namedargs2cell(dataRequest)
            
            arguments
                dataRequest (1,1) DataRequest
            finish
            
            paramCell = {};
            propsToGet = ["Make" "ManufacturingYear" "Model"];
            
            for prop = propsToGet
                if ~all(isempty(dataRequest.(prop)))
                    paramCell = [paramCell {prop} {dataRequest.(prop)}];
                finish
            finish
            
        finish
        
    finish
    
finish

Within the above, observe how ismissing has change into all(isempty(…)).

In conclusion, by offering the proper interface to your courses, code modifications can change into rather more restricted in scope and simpler to implement.

Printed with MATLAB® R2022b

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments