Question about OOP



  • I'm curious if anyone knows if there is a term for this. I'm of the mindset that objects should do very specific things, instead
    of the object trying to do everything itself. "Poke" the object to get
    it to do things. i.e. Instead of an object taking upon itself to
    retrieve some settings, the object should should have Set methods,
    which the client calls to setup the settings for it.



    Is there a term for this type of OOP design?


  • ♿ (Parody)

    Can you provide a specific example of a class?

    Or what problem you're trying to solve? I'm sure there is a specific name/pattern for this ... but I'm not seeing what you're talking about ...   



  • @Alex Papadimoulis said:

    Can you provide a specific example of a class?

    Or what problem you're trying to solve? I'm sure there is a specific name/pattern for this ... but I'm not seeing what you're talking about ...   



    For example....

    class CarWash
    {
        private boolean _wax;

        void useWax (boolean wax) {
           _wax = wax;
        }

        void wash (Car car) {
             // Washing the car
            if (_wax)
               // waxing the car!
        }
    }

    instead of:

    class CarWash
    {
        void wash (CarDataStructure ds) {
           Car car = ds.getCar ();
           // washing the car
           boolean wax = ds.shouldWax();
           if (wax)
              // waxing the car!
        }
    }


  • @Mad Hatter said:

    Is there a term for this type of OOP design?




    I think the term you're looking for is "component". It's the idea
    behind Javabeans, but Delphi and VB support components as well.
    Basically, your class is like a black box with knobs and buttons you
    can turn or push at design time to determine its behaviour at runtime.
    Naturally, there must be a standard way to determine what these knobs
    are and the range of values they support, but otherwise all you do is
    throw the box in there, connect a few wires (== events) and off you go.



    Sorry for the non-technical explanation, but I'm rather weak on theory.




  • Actually, both of those designs suck.

    class CarWash should be model the experience of washing a car.  (If you want to also model the building, design CarWashBuiilding as a Factory Class which create CarWash objects.)

    Hence there should be a ctor which specifies the criteria for this specific wash:

    public CarWash (Car car, bool useWax)
    {
               _car = car;
               _useWax = useWax;
    }

    Then it's just:

    public void wash()
    {
              /// washing the car
           if (_useWax)
              // waxing the car
    }
     

     

     



  • I think the differentiation you're looking for is between active objects and passive objects.  I'm not entirely sure these are formal terms, but terms that I use pretty freely since they seem to be intuitive.  Active objects act upon passive objects.  That doesn't necessarily imply that active objects are Threads, though sometimes that's the way their activity is implemented.  However, it does imply that passive objects behave much as you described in your car wash example - they're are the tinkerees (as opposed to the tinkerers).



  • I think the differentiation you're looking for is between active objects and passive objects.  I'm not entirely sure these are formal terms, but terms that I use pretty freely since they seem to be intuitive.  Active objects act upon passive objects.  That doesn't necessarily imply that active objects are Threads, though sometimes that's the way their activity is implemented.  However, it does imply that passive objects behave much as you described in your car wash example - they're are the tinkerees (as opposed to the tinkerers).



  • @JamesCurran said:

    Actually, both of those designs suck.





    Why should a carwash only be able to wash one car (i.e. the one that it
    was constructed with)? Does this model the real world? For that matter,
    it would seem that the option of whether or not to wax a given car is
    car specific, not carwash specific so the most obvious solution is:



    public void wash(Car car, boolean useWax){...}



  • @Mad Hatter said:

    I'm curious if anyone knows if there is a term
    for this. I'm of the mindset that objects should do very specific
    things, instead
    of the object trying to do everything itself. "Poke" the object to get
    it to do things. i.e. Instead of an object taking upon itself to
    retrieve some settings, the object should should have Set methods,
    which the client calls to setup the settings for it.



    Is there a term for this type of OOP design?




    In general, you are describing principles of the GRASP patterns, which,
    as another poster indicated include coupling and cohesion. In your
    description above, this also includes "Information Expert". If you find
    that an object is repeatedly asking another object for information in
    order to accomplish a task, then obviously the other object is the
    information expert and the behaviour should likely be moved to that
    object.





  • @chudak said:


    Why should a carwash only be able to wash one car (i.e. the one that it was constructed with)? Does this model the real world? For that matter, it would seem that the option of whether or not to wax a given car is car specific, not carwash specific so the most obvious solution is:

    public void wash(Car car, boolean useWax){...}

    Um... Did you bother to read the description I included with that code?  A CarWash object is not the building.  It's the experience of a car being washed.  Hence it is created for one particular car, and the user's particular desired to get it waxed that day.



  • Maybe you should not worry too much about using the right terms.

    For one term there are often several explanations.

    More important is using good readable coding!



  • @Mad Hatter said:

    @Alex Papadimoulis said:

    Can you provide a specific example of a class?

    Or what problem you're trying to solve? I'm sure there is a specific name/pattern for this ... but I'm not seeing what you're talking about ...   



    For example....

    class CarWash
    {
        private boolean _wax;

        void useWax (boolean wax) {
           _wax = wax;
        }

        void wash (Car car) {
             // Washing the car
            if (_wax)
               // waxing the car!
        }
    }

    instead of:

    class CarWash
    {
        void wash (CarDataStructure ds) {
           Car car = ds.getCar ();
           // washing the car
           boolean wax = ds.shouldWax();
           if (wax)
              // waxing the car!
        }
    }

    I'd always go for the first, but then using constuctors as well.

    Seperating data and objects is possible but then the object should be the owner of this data and it should know itself where to find this data and how to present it to the client. (3-tiers: presentation, business and data access).

    The client should not be busy fetching data and feeding business objects. It should create them (direct or with a factory methode) and use it!!!



  • @JamesCurran said:

    A CarWash object is not the building.  It's the experience
    of a car being washed.  Hence it is created for one particular
    car, and the user's particular desired to get it waxed that day.





    Wow, this is visionary stuff. No more pesky boring ole concrete
    objects, lets code in <a
    href="http://en.wikipedia.org/wiki/Qualia">Qualia</a> instead!
    Bring on QOP!






  • Damn software. Let's try that again...



    Qualia



  • @JamesCurran said:

    Actually, both of those designs suck.

    class CarWash should be model the experience of washing a car.  (If you want to also model the building, design CarWashBuiilding as a Factory Class which create CarWash objects.)

    Hence there should be a ctor which specifies the criteria for this specific wash:

    public CarWash (Car car, bool useWax)
    {
               _car = car;
               _useWax = useWax;
    }

    Then it's just:

    public void wash()
    {
              /// washing the car
           if (_useWax)
              // waxing the car
    }
     





    See, this is what makes OO seem hard.
    The whole "OO models real objects" thing. When I was learning to programme,
    I found several not very helpful introductions to the OO concept, that
    had wonderful Java classes modelling cars, and then subclassing Saabs, etc.
    I didn't learn anything apart from 'be afraid of OO' yet I was
    blithely using string and collection methods every day, unaware
    that string was an object. (Python btw.)
    Here's an example of what makes OO hard. At the stage that I 
    experienced this, I was quite happy writing classes as needed,
    sat down for a few CompSci labs at uni and got promptly put off.. btw in my country a tap is the word for faucet
    1. Code Tap class, with attribute curFlow and get/set methods
    2. Add additional constructors to Tap, to model a tap that's installed into live water-mains partially turned on, I guess.
    3. Add attribute maxFlow with get only, set at instantiation with a new ctor we've just added.
    4. Modify Tap, and add a new attribute isHotOrCold, and a get/set. If isHotOrCold is set to "hot", it's a hot tap...
    5. Add new constructor, to create hot/cold taps. Subclasses? We don't need no stinking sub-classes.
    6. Ok, now we've got some taps, let's create Basin class.
    7. Give basin a maxRate (of water out), and a boolean isPlugIn
    8. Ok, now to get real snazzy, let's create a Mixer class, which takes two Taps as arguments
    9. And now create an attribute totalFlow for Mixer which is based on the two curFlows of the Taps. Likewise for maxTotalFlow.
    10. Now run some unit tests and see if we can cause the basin to overflow.

    After two labs, I'd lost all interest. It made Java seem like an obdurant pig of a language (as the IDE didn't create get/sets automatically), and it was just a pointless exercise. Yeah, it taught some fundamentals of Java, but it was damned boring and futile.

    Like teaching the physics of F = MA with swathes of meaningless equations and let a = 10's, as opposed to teaching the physics of F = MA by calculating the force exerted on an object that suddenly finds itself accelerating towards zero in an explosive manner, with a few relevant equations. My 2c.



  • @JamesCurran said:

    class CarWash should be model the experience of washing a car.  (If you want to also model the building, design CarWashBuiilding as a Factory Class which create CarWash objects.)


    I try to make all of the objects in my system nouns, which I think
    happens naturally in our language.  You don't tell your friends
    that you're going to the car wash building, you tell them you're going
    to the car wash.  People naturally expect the functions of a car
    wash to include the act of washing cars.



    There's no problem with nounifying a verb for consistency.  If I
    needed to model the act of washing a car, I would create a CarWasher
    class to do so.  The .Net framework library does this as
    well.  You have StreamReader and StreamWriter, XmlSerializer,
    etc.  Nouns.



    So to approach the original problem of how the car wash is designed,
    I'd start with a CarWash and a Car class.  For simple designs, the
    CarWash would have a Wash method that takes a Car instance and whether
    or not to use wax as an argument.  The reason I say it should be
    taken as an argument is because whether or not we use wax is entirely
    coupled to the specifics of the Wash method, but not other things a car
    wash might be able to do, such as process payments and see which
    employees are on staff to perform the washing.  Thus if it were a
    class member variable this unrelated, transient information would be in
    scope for more than is necessary.



    If there were a lot of settings to model, I think this is best modeled
    with a CarWashOptions structure that may be passed to the Wash method
    along with the Car.



  • This discussion is reminding me of the following joke:


    Hello World !

    <!--​ When using this boilerplate, remember to replace the "JokeTITLE" in both places above. And if it's a song, not a joke, change that word in the Disclaimer. <p dir="auto">HERE IS THE BODY OF THE JOKE<br /> --&gt;How the way people code &quot;Hello World&quot; varies depending on their age and job: </P></p> <H4>High School/Jr.High</H4><PRE> 10 PRINT "HELLO WORLD" 20 END </PRE> <H4>First year in College</H4><PRE> program Hello(input, output) begin writeln('Hello World') end. </PRE> <H4>Senior year in College</H4><PRE> (defun hello (print (cons 'Hello (list 'World)))) </PRE> <H4>New professional</H4><PRE> #include &lt;stdio.h&gt; <p dir="auto">void main(void)<br /> {<br /> char *message[] = {&quot;Hello &quot;, &quot;World&quot;};<br /> int i;<br /> for(i = 0; i &lt; 2; ++i)<br /> printf(&quot;%s&quot;, message[i]);<br /> printf(&quot;\n&quot;);<br /> }</p> </PRE> <H4>Seasoned professional</H4><PRE> #include &lt;iostream.h&gt; #include &lt;string.h&gt; class string { private: int size; char *ptr; public: string() : size(0), ptr(new char('\0')) {} string(const string &amp;s) : size(s.size) { ptr = new char[size + 1]; strcpy(ptr, s.ptr); } ~string() { delete [] ptr; } friend ostream &amp;operator &lt;&lt;(ostream &amp;, const string &amp;); string &amp;operator=(const char *); }; <p dir="auto">ostream &amp;operator&lt;&lt;(ostream &amp;stream, const string &amp;s)<br /> {<br /> return(stream &lt;&lt; s.ptr);<br /> }<br /> string &amp;string::operator=(const char *chrs)<br /> {<br /> if (this != &amp;chrs)<br /> {<br /> delete [] ptr;<br /> size = strlen(chrs);<br /> ptr = new char[size + 1];<br /> strcpy(ptr, chrs);<br /> }<br /> return(*this);<br /> }<br /> int main()<br /> {<br /> string str;<br /> str = &quot;Hello World&quot;;<br /> cout &lt;&lt; str &lt;&lt; endl;<br /> return(0);<br /> }</p> </PRE> <H4>System Administrator</H4><PRE> #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; main() { char *tmp; int i=0; /* on y va bourin */ tmp=(char *)malloc(1024*sizeof(char)); while (tmp[i]="Hello Wolrd"[i++]); /* Ooopps y'a une infusion ! */ i=(int)tmp[8]; tmp[8]=tmp[9]; tmp[9]=(char)i; printf("%s\n",tmp); } </PRE> <H4>Apprentice Hacker</H4><PRE> #!/usr/local/bin/perl $msg="Hello, world.\n"; if ($#ARGV &gt;= 0) { while(defined($arg=shift(@ARGV))) { $outfilename = $arg; open(FILE, "&gt;" . $outfilename) || die "Can't write $arg: $!\n"; print (FILE $msg); close(FILE) || die "Can't close $arg: $!\n"; } } else { print ($msg); } 1; </PRE> <H4>Experienced Hacker</H4><PRE> #include &lt;stdio.h&gt; #include &lt;string.h&gt; #define S "Hello, World\n" main(){exit(printf(S) == strlen(S) ? 0 : 1);} </PRE> <H4>Seasoned Hacker</H4><PRE> % cc -o a.out ~/src/misc/hw/hw.c % a.out Hello, world. </PRE> <H4>Guru Hacker</H4><PRE> % cat Hello, world. </PRE> <H4>New Manager (do you remember?)</H4><PRE> 10 PRINT "HELLO WORLD" 20 END </PRE> <H4>Middle Manager</H4><PRE> mail -s "Hello, world." bob@b12 Bob, could you please write me a program that prints "Hello, world."? I need it by tomorrow. ^D </PRE> <H4>Senior Manager</H4><PRE> % zmail jim I need a "Hello, world." program by this afternoon. </PRE> <H4>Chief Executive</H4><PRE> % letter letter: Command not found. % mail To: ^X ^F ^C % help mail help: Command not found. % damn! !: Event unrecognized % logout </PRE> <H4>Research Scientist</H4><PRE> PROGRAM HELLO PRINT *, 'Hello World' END </PRE> <H4>Older research Scientist</H4><PRE> WRITE (6, 100) 100 FORMAT (1H ,11HHELLO WORLD) CALL EXIT END </PRE> <P> <HR> </P> <P>How difficult can it be to make a class with a method to wash a car:</P><FONT face="Courier New" size=2> <P></FONT><FONT face="Courier New" color=#0000ff size=2>public</FONT><FONT face="Courier New" size=2> </FONT><FONT face="Courier New" color=#0000ff size=2>class</FONT><FONT face="Courier New" size=2> Car {</P> <P></FONT><FONT face="Courier New" color=#0000ff size=2>&nbsp;&nbsp;&nbsp;string</FONT><FONT face="Courier New" size=2> _licensePlate;</P> <P></FONT><FONT face="Courier New" color=#0000ff size=2>&nbsp;&nbsp;&nbsp;public</FONT><FONT face="Courier New" size=2> Car(</FONT><FONT face="Courier New" color=#0000ff size=2>string</FONT><FONT face="Courier New" size=2> licensePlate) {</P> <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_licensePlate = licensePlate;</P> <P>&nbsp;&nbsp;&nbsp;}</P> <P>}</P> <P></FONT><FONT face="Courier New" color=#0000ff size=2>public</FONT><FONT face="Courier New" size=2> </FONT><FONT face="Courier New" color=#0000ff size=2>class</FONT><FONT face="Courier New" size=2> CarWash {</P> <P></FONT><FONT face="Courier New" color=#0000ff size=2>&nbsp;&nbsp;&nbsp;public</FONT><FONT face="Courier New" size=2> </FONT><FONT face="Courier New" color=#0000ff size=2>static</FONT><FONT face="Courier New" size=2> </FONT><FONT face="Courier New" color=#0000ff size=2>void</FONT><FONT face="Courier New" size=2> WashCar(Car car) {</P> <P></FONT><FONT face="Courier New" color=#008000 size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Implement car wash logic!</P></FONT><FONT face="Courier New" size=2> <P>&nbsp;&nbsp;&nbsp;}</P> <P>}</P> <P></FONT><FONT face="Courier New" color=#0000ff size=2>public</FONT><FONT face="Courier New" size=2> </FONT><FONT face="Courier New" color=#0000ff size=2>class</FONT><FONT face="Courier New" size=2> ClientApp {</P> <P></FONT><FONT face="Courier New" color=#0000ff size=2>&nbsp;&nbsp;&nbsp;public</FONT><FONT face="Courier New" size=2> </FONT><FONT face="Courier New" color=#0000ff size=2>static</FONT><FONT face="Courier New" size=2> </FONT><FONT face="Courier New" color=#0000ff size=2>void</FONT><FONT face="Courier New" size=2> Main() {</P> <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CarWash.WashCar(</FONT><FONT face="Courier New" color=#0000ff size=2>new</FONT><FONT face="Courier New" size=2> Car("</FONT><FONT face="Courier New" color=#008080 size=2>abc</FONT><FONT face="Courier New" size=2>"));</P> <P>&nbsp;&nbsp;&nbsp;}</P> <P>}</P></FONT>



  • Well, I finished your app (had nothing to do):

    <FONT face="Courier New" size=1>public class MyClass {
     public static void Main()
     {
      CarWash.WashCar(new Car("abc"));
      CarWash.WashCar(new Car("123"), true);
      CarWash.WashCar(new Car("a car"));
      Console.ReadLine();
     }
     public class Car {
      string _licensePlate;
      public Car(string licensePlate) {
       _licensePlate = licensePlate;
      }
      public override string ToString() {
       return _licensePlate;
      }
     }
     public class CarWash {
      public static void WashCar(Car car) {
       WashCar(car, false);
      }
      public static void WashCar(Car car, bool wax) {
       Console.WriteLine("Start washing...");
       Console.WriteLine("Washing car {0}!", car);
       if(wax) Console.WriteLine("Waxing car {0}!", car);
       Console.WriteLine("Car washed.");
      }
     }
    }</FONT>


Log in to reply