Re: Immutable Utility Objects

"Daniel" <wellman-pD6z9c7pN/[email protected]> Sat, 03 Dec 2011 20:02:43 -0000
Newsgroups gmane.comp.programming.language-of-the-year
Message-ID <[email protected]>
--1fJyHtMuUs7YJ3raJusDgjMWaLc92KPfnAsemoB
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

And to your question about a grouping of related utility methods with no mu=
table state, that may be a fine design.  In the case of the Math class meth=
ods, it seems like those are truly immutable functions that don't belong on=
 their associated types.  For example, the maximum value function seems (to=
 me anyways) to not make any sense as a method on Integer (e.g. 1.max(4)?).

If you can easily refactor later, then that seems fine.  I think the danger=
 is when those collections of class methods either:

a) Mutate their inputs or cause other state changes.  In that case, the cla=
ss methods may be hiding these interactions when another object might help.

b) Grow into a group of disparate, unrelated functions - a Swiss army knife=
 collection of methods which can be hard for clients to understand.  But a =
simple refactoring to split up the related functions into another class cou=
ld fix that problem.

c) Actually belong on one of the arguments.  But in some cases like Java yo=
u can't (currently) add methods to other types, so you have no choice.  See=
 Google's Collections2 class, which seem to wish it was on the existing Jav=
a collections classes.

Dan

--- In [email protected], Steve Wart <steve.wart@...> wrote:
>
> Why do some people feel so strongly that implementing class-side behavior
> is bad design?
>=20
> For example, I've got an object with no mutable state, and no required
> inheritance, just a set of related utility functions that are needed to
> fire off some processing.
>=20
> I've heard arguments that this approach "inhibits testing" - but does tha=
t
> trump the KISS principle? I seem to be able to test just fine.
>=20
> After all if I need a singleton, or even multiple instances, there's
> nothing stopping me from refactoring.
>=20
> Could it be I'm mistaken in the assumption that people think it's bad?
> After all most languages these days have a "Math" import that has nothing
> but static behavior, and I'm sure there are many other application-specif=
ic
> examples of this.
>=20
> Alternatively, could it be that creating instances to execute all behavio=
r
> overcomes problems with static semantics?
>=20
> Just curious.
>=20
> Thanks,
> Steve
>



--1fJyHtMuUs7YJ3raJusDgjMWaLc92KPfnAsemoB
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit




<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
</head>







<body style="background-color: #fff;">
<span style="display:none">&nbsp;</span>

<!--~-|**|PrettyHtmlStartT|**|-~-->
<div id="ygrp-mlmsg" style="position:relative;">
  <div id="ygrp-msg" style="z-index: 1;">
<!--~-|**|PrettyHtmlEndT|**|-~-->

    <div id="ygrp-text" >
      
      
      <p>And to your question about a grouping of related utility methods with no mutable state, that may be a fine design.  In the case of the Math class methods, it seems like those are truly immutable functions that don't belong on their associated types.  For example, the maximum value function seems (to me anyways) to not make any sense as a method on Integer (e.g. 1.max(4)?).<br>
<br>
If you can easily refactor later, then that seems fine.  I think the danger is when those collections of class methods either:<br>
<br>
a) Mutate their inputs or cause other state changes.  In that case, the class methods may be hiding these interactions when another object might help.<br>
<br>
b) Grow into a group of disparate, unrelated functions - a Swiss army knife collection of methods which can be hard for clients to understand.  But a simple refactoring to split up the related functions into another class could fix that problem.<br>
<br>
c) Actually belong on one of the arguments.  But in some cases like Java you can't (currently) add methods to other types, so you have no choice.  See Google's Collections2 class, which seem to wish it was on the existing Java collections classes.<br>
<br>
Dan<br>
<br>
--- In <a href="mailto:pragprog%40yahoogroups.com">[email protected]</a>, Steve Wart &lt;steve.wart@...&gt; wrote:<br>
&gt;<br>
&gt; Why do some people feel so strongly that implementing class-side behavior<br>
&gt; is bad design?<br>
&gt; <br>
&gt; For example, I've got an object with no mutable state, and no required<br>
&gt; inheritance, just a set of related utility functions that are needed to<br>
&gt; fire off some processing.<br>
&gt; <br>
&gt; I've heard arguments that this approach &quot;inhibits testing&quot; - but does that<br>
&gt; trump the KISS principle? I seem to be able to test just fine.<br>
&gt; <br>
&gt; After all if I need a singleton, or even multiple instances, there's<br>
&gt; nothing stopping me from refactoring.<br>
&gt; <br>
&gt; Could it be I'm mistaken in the assumption that people think it's bad?<br>
&gt; After all most languages these days have a &quot;Math&quot; import that has nothing<br>
&gt; but static behavior, and I'm sure there are many other application-specific<br>
&gt; examples of this.<br>
&gt; <br>
&gt; Alternatively, could it be that creating instances to execute all behavior<br>
&gt; overcomes problems with static semantics?<br>
&gt; <br>
&gt; Just curious.<br>
&gt; <br>
&gt; Thanks,<br>
&gt; Steve<br>
&gt;<br>
<br>
</p>

    </div>
     

    <!--~-|**|PrettyHtmlStart|**|-~-->
    <div style="color: #fff; height: 0;">__._,_.___</div>

        
  
   
    <div id="ygrp-actbar" style="clear: both; margin-bottom: 10px; white-space: nowrap; color: #666; padding-top: 15px;">
      <div>
        <a href="mailto:wellman-pD6z9c7pN/[email protected]?subject=Re%3A%20Immutable%20Utility%20Objects" style="margin-right: 0; padding-right: 0;">
	  Reply to <span style="font-weight: 700;">sender</span></a> |
        <a href="mailto:[email protected]?subject=Re%3A%20Immutable%20Utility%20Objects">
	  Reply to <span style="font-weight: 700;">group</span></a> |
        	  <a href="http://groups.yahoo.com/group/pragprog/post;_ylc=X3oDMTJxdTBqb2wzBF9TAzk3MzU5NzE0BGdycElkAzI4Mzg3MDgEZ3Jwc3BJZAMxNzA1MDA3MjA3BG1zZ0lkAzEwMjEzBHNlYwNmdHIEc2xrA3JwbHkEc3RpbWUDMTMyMjk0MjU2Nw--?act=reply&messageNum=10213">Reply <span style="font-weight: 700;">via web post</span></a> |
            	<a href="http://groups.yahoo.com/group/pragprog/post;_ylc=X3oDMTJlYWhydTg3BF9TAzk3MzU5NzE0BGdycElkAzI4Mzg3MDgEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA250cGMEc3RpbWUDMTMyMjk0MjU2Nw--" style="font-weight: 700;">Start a New Topic</a>
      </div>

                <a href="http://groups.yahoo.com/group/pragprog/message/10211;_ylc=X3oDMTM2aWo4aTdpBF9TAzk3MzU5NzE0BGdycElkAzI4Mzg3MDgEZ3Jwc3BJZAMxNzA1MDA3MjA3BG1zZ0lkAzEwMjEzBHNlYwNmdHIEc2xrA3Z0cGMEc3RpbWUDMTMyMjk0MjU2NwR0cGNJZAMxMDIxMQ--">Messages in this topic</a>
          (<span style="font-weight: 700;">3</span>)
          </div> 
<!------- Start Nav Bar ------>

<!-- |**|begin egp html banner|**| -->
<div id="ygrp-vital" style="background-color: #e0ecee; font-family: Verdana; font-size: 10px; margin-bottom: 10px; padding: 10px;">
      <span id="vithd" style="font-weight: bold; color: #333; text-transform: uppercase; ">Recent Activity:</span>

    <ul style="list-style-type: none; margin: 0; padding: 0; display: inline;">
                                                    </ul>
    
  <div style="clear: both; padding-top: 2px; color: #1e66ae;">
    <a href="http://groups.yahoo.com/group/pragprog;_ylc=X3oDMTJlZ2Uwa2VwBF9TAzk3MzU5NzE0BGdycElkAzI4Mzg3MDgEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTMyMjk0MjU2Nw--" style="text-decoration: none;">Visit Your Group</a>
  </div>
</div>

              <div id="ygrp-mkp" style="border: 1px solid #d8d8d8; clear: both; float: left; font-family: Arial; margin: 5px 0 10px 0; padding: 0 10px;">
      <div id="hd" style="color: #628c2a; font-size: 85%; font-weight: 700; line-height: 122%; margin: 10px 0;">MARKETPLACE</div>
      <div id="ads" style="margin-bottom: 10px;">
                          <div class="ad" style="color: #628C2A; font-family: Arial; font-weight: 700; padding: 0 0;">
                        <p><a href="http://global.ard.yahoo.com/SIG=15osbn0fk/M=493064.14543979.14562481.13298430/D=groups/S=1705007207:MKP1/Y=YAHOO/EXP=1322949767/L=c57924ee-1de9-11e1-8fd7-2b750b954466/B=_SsuONBDRok-/J=1322942567581672/K=PytAJl3qfGkA2UAm6oruXg/A=6060255/R=0/SIG=1194m4keh/*http://us.toolbar.yahoo.com/?.cpdl=grpj">Stay on top of your group activity without leaving the page you're on - Get the Yahoo! Toolbar now.</a></p> <script language=javascript>
if(window.yzq_d==null)window.yzq_d=new Object();
window.yzq_d['_SsuONBDRok-']='&U=13cnvhuu0%2fN%3d_SsuONBDRok-%2fC%3d493064.14543979.14562481.13298430%2fD%3dMKP1%2fB%3d6060255%2fV%3d1';
</script><noscript><img width=1 height=1 alt="" src="http://us.bc.yahoo.com/b?P=c57924ee-1de9-11e1-8fd7-2b750b954466&T=1dhbsersh%2fX%3d1322942567%2fE%3d1705007207%2fR%3dgroups%2fK%3d5%2fV%3d2.1%2fW%3dH%2fY%3dYAHOO%2fF%3d1327694685%2fH%3dY29udGVudD0iWWFob29fVGVjaDtHbztXaWRnZXRzO1dlYnNpdGVfU2VydmljZXM7UG9kY2FzdHM7RmxpY2tyO1lhaG9vX1NlYXJjaF9NYXJrZXRpbmc7RmluYW5jZTtCcmllZmNhc2U7Q2FsZW5kYXI7IiBkaXNhYmxlc2h1ZmZsaW5nPSIxIiBzZXJ2ZUlkPSJjNTc5MjRlZS0xZGU5LTExZTEtOGZkNy0yYjc1MGI5NTQ0NjYiIHNpdGVJZD0iNDQ1MjU1MSIgdFN0bXA9IjEzMjI5NDI1Njc1NDY1NTQiIA--%2fQ%3d-1%2fS%3d1%2fJ%3dAC238962&U=13cnvhuu0%2fN%3d_SsuONBDRok-%2fC%3d493064.14543979.14562481.13298430%2fD%3dMKP1%2fB%3d6060255%2fV%3d1"></noscript><!--QYZ ,;;MKP1;1705007207;2;-->          </div>
                      </div>
    </div>
  
<div id="ft" style="font-family: Arial; font-size: 11px; margin-top: 5px; padding: 0 2px 0 0; clear: both;">
  <a href="http://groups.yahoo.com/;_ylc=X3oDMTJkaW9ramVjBF9TAzk3MzU5NzE0BGdycElkAzI4Mzg3MDgEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2dmcARzdGltZQMxMzIyOTQyNTY3" style="float: left;"><img src="http://l.yimg.com/a/i/us/yg/logo/us.gif" height="15" width="137" alt="Yahoo! Groups" style="border: 0;"/></a>
  <div style="color: #747575; float: right;">Switch to: <a href="mailto:[email protected]?subject=Change Delivery Format: Traditional" style="text-decoration: none;">Text-Only</a>, <a href="mailto:[email protected]?subject=Email Delivery: Digest" class="margin-rt" style="text-decoration: none;">Daily Digest</a> &bull; <a href="mailto:[email protected]?subject=Unsubscribe" style="text-decoration: none;">Unsubscribe</a> &bull; <a href="http://docs.yahoo.com/info/terms/" style="text-decoration: none;">Terms of Use</a></div>
</div>

<!-- |**|end egp html banner|**| -->

  </div> <!-- ygrp-msg -->

  <!-- Sponsor -->
  <!-- |**|begin egp html banner|**| -->
  <div id="ygrp-sponsor" style="width:160px; float:right; clear:none; margin:0 0 25px 0; background: #fff;">

<!-- Start Recommendations -->
<div id="ygrp-reco">
     </div>
<!-- End Recommendations -->



  </div>   <!-- |**|end egp html banner|**| -->

  <div style="clear:both; color: #FFF; font-size:1px;">.</div>
</div>

  <img src="http://geo.yahoo.com/serv?s=97359714/grpId=2838708/grpspId=1705007207/msgId=10213/stime=1322942567/nc1=5191955/nc2=5741398/nc3=4507179" width="1" height="1"> <br>

<div style="color: #fff; height: 0;">__,_._,___</div>
<!--~-|**|PrettyHtmlEnd|**|-~-->

</body>

<!--~-|**|PrettyHtmlStart|**|-~-->
<head>
  <style type="text/css">
  <!--
  #ygrp-mkp {
  border: 1px solid #d8d8d8;
  font-family: Arial;
  margin: 10px 0;
  padding: 0 10px;
}

#ygrp-mkp hr {
  border: 1px solid #d8d8d8;
}

#ygrp-mkp #hd {
  color: #628c2a;
  font-size: 85%;
  font-weight: 700;
  line-height: 122%;
  margin: 10px 0;
}

#ygrp-mkp #ads {
  margin-bottom: 10px;
}

#ygrp-mkp .ad {
  padding: 0 0;
}

#ygrp-mkp .ad p {
  margin: 0;
}

#ygrp-mkp .ad a {
  color: #0000ff;
  text-decoration: none;
}
  #ygrp-sponsor #ygrp-lc {
  font-family: Arial;
}

#ygrp-sponsor #ygrp-lc #hd {
  margin: 10px 0px;
  font-weight: 700;
  font-size: 78%;
  line-height: 122%;
}

#ygrp-sponsor #ygrp-lc .ad {
  margin-bottom: 10px;
  padding: 0 0;
}

  a {
    color: #1e66ae;
  }

  #actions {
    font-family: Verdana;
    font-size: 11px;
    padding: 10px 0;
  }

  #activity {
    background-color: #e0ecee;
    float: left;
    font-family: Verdana;
    font-size: 10px;
    padding: 10px;
  }

  #activity span {
    font-weight: 700;
  }

  #activity span:first-child {
    text-transform: uppercase;
  }

  #activity span a {
    color: #5085b6;
    text-decoration: none;
  }

  #activity span span {
    color: #ff7900;
  }

  #activity span .underline {
    text-decoration: underline;
  }

  .attach {
    clear: both;
    display: table;
    font-family: Arial;
    font-size: 12px;
    padding: 10px 0;
    width: 400px;
  }

  .attach div a {
    text-decoration: none;
  }

  .attach img {
    border: none;
    padding-right: 5px;
  }

  .attach label {
    display: block;
    margin-bottom: 5px;
  }

  .attach label a {
    text-decoration: none;
  }
  
  blockquote {
    margin: 0 0 0 4px;
  }

  .bold {
    font-family: Arial;
    font-size: 13px;
    font-weight: 700;
  }

  .bold a {
    text-decoration: none;
  }

  dd.last p a {
    font-family: Verdana;
    font-weight: 700;
  }

  dd.last p span {
    margin-right: 10px;
    font-family: Verdana;
    font-weight: 700;
  }

  dd.last p span.yshortcuts {
    margin-right: 0;
  }

  div.attach-table div div a {
    text-decoration: none;
  }

  div.attach-table {
    width: 400px;
  }

  div.file-title a, div.file-title a:active, div.file-title a:hover, div.file-title a:visited {
    text-decoration: none;
  }

  div.photo-title a, div.photo-title a:active, div.photo-title a:hover, div.photo-title a:visited {
    text-decoration: none;
  }

  div#ygrp-mlmsg #ygrp-msg p a span.yshortcuts {
    font-family: Verdana;
    font-size: 10px;
    font-weight: normal;
  }

  .green {
    color: #628c2a;
  }

  .MsoNormal {
    margin: 0 0 0 0;
  }

  o {
    font-size: 0;
  }

  #photos div {
    float: left;
    width: 72px;
  }

  #photos div div {
    border: 1px solid #666666;
    height: 62px;
    overflow: hidden;
    width: 62px;
  }

  #photos div label {
    color: #666666;
    font-size: 10px;
    overflow: hidden;
    text-align: center;
    white-space: nowrap;
    width: 64px;
  }

  #reco-category {
    font-size: 77%;
  }

  #reco-desc {
    font-size: 77%;
  }

  .replbq {
    margin: 4px;
  }

  #ygrp-actbar div a:first-child {
   /* border-right: 0px solid #000;*/
    margin-right: 2px;
    padding-right: 5px;
  }

  #ygrp-mlmsg {
    font-size: 13px;
    font-family: Arial, helvetica,clean, sans-serif;
    *font-size: small;
    *font: x-small;
  }

  #ygrp-mlmsg table {
    font-size: inherit;
    font: 100%;
  }

  #ygrp-mlmsg select, input, textarea {
    font: 99% Arial, Helvetica, clean, sans-serif;
  }

  #ygrp-mlmsg pre, code {
    font:115% monospace;
    *font-size:100%;
  }

  #ygrp-mlmsg * {
    line-height: 1.22em;
  }

  #ygrp-mlmsg #logo {
    padding-bottom: 10px;
  }

  #ygrp-mlmsg a {
    color: #1E66AE;
  }

  #ygrp-msg p a {
    font-family: Verdana;
  }

  #ygrp-msg p#attach-count span {
    color: #1E66AE;
    font-weight: 700;
  }

  #ygrp-reco #reco-head {
    color: #ff7900;
    font-weight: 700;
  }

  #ygrp-reco {
    margin-bottom: 20px;
    padding: 0px;
  }

  #ygrp-sponsor #ov li a {
    font-size: 130%;
    text-decoration: none;
  }

  #ygrp-sponsor #ov li {
    font-size: 77%;
    list-style-type: square;
    padding: 6px 0;
  } 

  #ygrp-sponsor #ov ul {
    margin: 0;
    padding: 0 0 0 8px;
  }

  #ygrp-text {
    font-family: Georgia;
  }

  #ygrp-text p {
    margin: 0 0 1em 0;
  }

  #ygrp-text tt {
    font-size: 120%;
  }

  #ygrp-vital ul li:last-child {
    border-right: none !important; 
  } 
  -->
  </style>
</head>

<!--~-|**|PrettyHtmlEnd|**|-~-->
</html>
<!-- end group email -->


--1fJyHtMuUs7YJ3raJusDgjMWaLc92KPfnAsemoB--