[AccessD] AccessD Digest, Vol 98, Issue 7

jwcolby jwcolby at colbyconsulting.com
Mon Apr 11 15:36:04 CDT 2011


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

Do you program in .Net?  Everything is an object.  There is no "module", though there can be static 
classes / functions.  I haven't done a poll, but I doubt seriously that anyone uses your paradigm in 
.net.

John W. Colby
www.ColbyConsulting.com

On 4/11/2011 4:09 PM, Kenneth Ismert wrote:
> 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