[AccessD] AccessD Digest, Vol 98, Issue 7

Kenneth Ismert kismert at gmail.com
Mon Apr 11 15:09:32 CDT 2011


John,

I understand the reasoning and all however... because the code is no longer
> contained within the object that needs it, you now open yourself up to the
> old "I need to modify this method... oops... that change breaks something
> else that uses the code".
>

It is always possible to over-factor, and merge two similar pieces of code
together that really should be separate. In that case, you factor the code
back into multiple pieces, and correct the dependencies.


> Class programming exists for a reason.  Placing code in the object that
> needs the code exists for a reason.  Black box programming exists for a
> reason.  The reason in many cases is to prevent exactly this kind of
> interaction when we accidentally change a piece of code used in many places
> and break one of those places.
>

I would submit that calling side-effect free functions from a class does not
pierce the black box. The important things, state and access, are protected
by the class. But the function can be anywhere: built-in VBA functions,
Access application methods, or DAO library calls. You undoubtedly call these
functions from within your classes.


> Yes, there are instances where lots of different things need the exact same
> code, and yes, I have been known to call module functions from classes, but
> it truly is a questionable practice in most cases.
>

Test cases replace questionability with a guarantee of proper function. The
function shouldn't define what it does -- the test cases should. If changes
to a function break a test, then you know immediately that there is a
problem. Functional unit testing guards against changes that would break
dependent code.

I haven't found a reason why classes can't rely on properly crafted and
tested module-level functions.

-Ken


>
> John W. Colby
> www.ColbyConsulting.com
>
> On 4/11/2011 1:10 PM, Kenneth Ismert wrote:
>
>> John, All:
>>
>> I'm going to expand a little on what I'm trying to get at. This post
>> really
>> isn't advice on what you should do. And it certainly isn't criticism.
>>
>> I have been returning to the old Lisp idea of functional programming:
>> libraries of functions that act only on their inputs and only return a
>> result. The goal is 'side-effect-free' -- inputs are NEVER modified, and
>> external variables are never referenced. If a function needs to return
>> complex information, it returns either a type or an object. Database
>> functions unavoidably have side-effects, but these are regarded as
>> 'external' to the code, and are explicitly documented.
>>
>> The thing that surprised me was how well libraries play with objects.
>> Libraries provide discrete, testable chunks of code that support any
>> instance. Libraries separate functions into common-sense groups. Classes
>> provide an instance wrapper over the libraries, stringing functions
>> together
>> to support the application.
>>
>> Plus, it is pretty easy to convert classes to this scheme while
>> maintaining
>> compatibility.
>>
>> The advantages became apparent when I refactored some of my early
>> monolithic
>> classes. These large, 'kitchen sink' classes had dozens of methods which
>> mixed database, business, and application functionality. They were
>> unwieldy,
>> hard-to-understand, and hard-to-extend. I simply copied the class into a
>> module, stripped out the instance stuff (properties and module-level
>> variables), and turned the methods into side-effect-free functions. I then
>> stripped out the code within the original class methods, turning them into
>> wrappers calling library functions with their instance variables.
>>
>> The result: classes become lightweight, making their functionality much
>> more
>> obvious. Compatibility is maintained, but the new system is much easier to
>> refactor and extend.
>>
>> The class on-top-of function approach is also a good answer to those who
>> want to re-use your code, but can't because they need some method that is
>> marked private in a class. They typically demand that all methods be made
>> public, which is usually silly because the class designer has good reasons
>> for limiting the public visibility of certain methods or properties.
>>
>> But with a function library, you can have your cake and eat it, too.
>> Classes
>> hold the instance information, and interact with libraries in an
>> instance-safe way, because the functions never modify their inputs. Others
>> with different needs can call the functions directly, or write their own
>> classes. Heck, I even find myself cramped by my own classes at times, and
>> having the option to call underlying functions directly has benefited me.
>>
>> Writing test code for functions is much easier than for complex class
>> systems. Test code provides reasonable proof of reliability.  Reliable
>> complexity can only be built out of small, simple, understandable, and
>> testable pieces.
>>
>> -Ken
>>
>>



More information about the AccessD mailing list