[erlang-questions] Fwd: Fear and Loathing in Programming La La Land

Jan Burse janburse@REDACTED
Fri Mar 30 13:31:31 CEST 2012


Michael Richter schrieb:
> If you're using a language that's so lame it can't do named parameters
> and/or provide sane defaults, the builder pattern is the way around the
> lameness.

There are a couple of languages that have named parameters, i.e. ADA,
SmallTalk, Objective-C, etc..  But with setters you get a little bit 
more than with named parameters when it comes to defaults.

Take the buyMilk example. Assume that "next farmer" has a some
precalculated lookup and "shopping mal" would need a real lookup.
With setter we can simply do:

    class BuyMilk {
       locationAddr = AddrBook.nextFarmerAddr();

       void setLocation(String location) {
           if (location.equals("next farmer")) {
              locationAddr = AddrBook.nextFarmerAddr;
           } else {
              locationAddr = AddrBook.lookup(location);
           }
       }

       void buyMilk() {
           /* ... */
       }

    }

With methods and defaults we would do:

    class BuyMilk {

       void buyMilk(String location) {
           Addr locationAddr;
           if (location.equals("next farmer")) {
              locationAddr = AddrBook.nextFarmerAddr;
           } else {
              locationAddr = AddrBook.lookup(location);
           }
       }

       void buyMilk() {
           buyMilk("next farmer");
       }

    }


But this is only the half story. What happens if we
have more verbs? With methods and defaults something
as follows would happen:

    class Trade {

       Addr find(String location) {
           if (location.equals("next farmer")) {
              return AddrBook.nextFarmerAddr;
           } else {
              return AddrBook.lookup(location);
           }
       }

       void buyMilk(String location) {
            Addr locationAddr = find(location);
            /* ... */
       }

       void sellCloth(String location) {
            Addr locationAddr = find(location);
            /* ... */
       }

       void sellCloth() {
           sellCloth("next farmer");
       }

       void buyMilk() {
           buyMilk("next farmer");
       }

    }

So basically to avoid duplicate code, the code to sanitize
the parameter will land somewhere in a separate routine.
Why not put that code in a setter:

    class Trade {
       locationAddr = AddrBook.nextFarmerAddr();

       void setLocation(String location) {
           if (location.equals("next farmer")) {
              locationAddr = AddrBook.nextFarmerAddr;
           } else {
              locationAddr = AddrBook.lookup(location);
           }
       }

       void buyMilk() {
           /* ... */
       }

       void sellCloth() {
           /* ... */
       }

    }

Clearly the setter thing is an imperative approach. But it
is not that bloathed compared with other approaches, as the
example shows. And it can be applied in a quite disciplined
and elegant way.

Since the setter thing comes also with naming conventions,
usually most of the IDE support the following convenience:

     - Automatic creation of setters (and getters) for
       selected variables, so that one can easily begin coding.
     - Automatic cross referencing of variables together
       with their setters (and getters).
     - Automatic refactoring of variables together
       with their setters (and getters).

In the above one can view setters as write access to variables,
and getters as read access to variables, which also allows
for more varied cross referencing and code analysis.

But of course there are also a couple of pitfalls.

Bye



More information about the erlang-questions mailing list