OOP clarification

Collapse
X
 
  • Time
  • Show
Clear All
new posts

  • fjm
    replied
    Heya Atli. I'm glad that you joined in to help. :)

    Originally posted by Atli
    I think your assumption that methods should preferably be private is not really correct.
    OK. I understand this acutally. I was just thinking that maybe it would be better to make methods private where possible for added security but I see that isn't always a good thing or even realistic especially after seeing your example.

    Originally posted by Atli
    Private members should complement the public once, but never be a requirement. Ideally, you should be able to inline ALL private functions into the public functions without having to change how the outside code uses the class.
    OK, I understand that. I guess my question is what if a public method really has nothing to do with any of the other methods? Let's say that you have several methods that just draw data from the database and the sql requires a var for the WHERE statement. We would have to pass that variable into the method. I guess what I am trying to say here is that I am not seeing much difference between a regular function and a public method where the public methods sole purpose in life is to return data from a database. Now, if that public function actually called a private function for something, I could see it. Am I wrong? Thanks for the link on interfaces, I will check that out.


    Originally posted by Atli
    The way in which you designed your example class is very odd, really. It has no public functions, which basically just makes it a complex array with a constructor.
    OK. This goes back to what I was saying about the constructor. Instead of using a public method to do this, I thought the constructor was supposed to handle this which was why I designed it that way.

    Originally posted by Atli
    Class members should work together. Public members being the controllers; the way the outside interacts with it. Private members providing functionality for the public functions; the internal mechanism that the outside doesn't need to be bothered with.
    If I'm understanding you right, you're saying that instead of using the constructor to interact with the private methods, I should be using public functions. Yes?

    I think that maybe your example is even better than mine because it illistrates my point even better. In your example, if you wanted to use another public method that has NOTHING AT ALL to do with any of the other methods, what do you do? Do you make another class for it? Say for example that you wanted to have another function that said goodbye but instead of using the person's first name, you would be required to use their last name. I know, I know... it's a really dumb example but it makes the point. :) Would you use a new class for this or use this same class?

    I understand what you are saying, more so now then ever before. That's why I'm nitpicking here. I'm honestly getting this for a change. :)

    Leave a comment:


  • fjm
    replied
    Originally posted by Dormilich
    well, yea, but do you want to handle any output through properties? (that may work for 1 or 2, but what about undefined/several different outputs?)
    Is this not acceptable?

    Originally Posted by fjm
    I know that in your example you are using the constructor to call the sayHello method but what if you have more than 1 or even 10 of these type of methods that require one or two variables? What do you do? How do you call them?
    I am under the impression that each class should have a single function (and not in the literal sense). Let me give you an example. I have a class with two methods. The first method gets data from a database then internally passes the values to the second method where the data is checked then returned to the main script. In the constructor, I call the first method which starts the process. My thoughts are that the class should only do one thing. You can feed it the var(s) and it returns what you need.

    Code:
    class Hello{
        public  $out;
        private $text;
    
        public function __construct($text)
        {
            $this->text = $text;
            $this->sayHello();
        }
    
        private function sayHello()
        {
            $text = $this->text;
            $var = 'Hello, my name is: ' . $text;
            return $this->out = $var;
        }
        
        public function doSomething()
        {
            $val = 'Do something here';
            return $val;
        }
    }
    
    $hello = new Hello('Tom');
    echo $hello->out;
    In my original example, I added a doSomething method. Let's just say that this class was for nothing more than to say hello. I know that it isn't useful and I could come up with a better example but it conveys my point I think.

    So, with this new public method, say that I wanted to call that method. I first have to create an instance but the constructor is looking for a var that has nothing to do with this doSomething method. How would I work this? Do you see what I mean?

    private methods are good, if you need tasks done that shouldn't be initialized from the outside (like e.g. connecting to a database or loading a configuration)
    Yes, I am seeing exactly what you mean. A good example of this would be a login script where the users' password should be made private.

    Leave a comment:


  • Atli
    replied
    Hi.

    A couple of things I'd like to comment on...

    First.
    I think your assumption that methods should preferably be private is not really correct.

    Private members are only accessible from within the class itself, so any functionality or data you want accessible from the outside should (obviously) not be made private.
    Private members should complement the public once, but never be a requirement. Ideally, you should be able to inline ALL private functions into the public functions without having to change how the outside code uses the class.

    It's best to design classes in a way that allows you to redesign the entire interior of the class without having to change the publicly declared functions and variables. (Check out interfaces to see what I mean)

    Second.
    The way in which you designed your example class is very odd, really.
    It has no public functions, which basically just makes it a complex array with a constructor.

    Objects are meant to be more than just a collection of variables or a collection of anonymous functions. Arrays and normal functions work fine for that.

    Class members should work together.
    Public members being the controllers; the way the outside interacts with it.
    Private members providing functionality for the public functions; the internal mechanism that the outside doesn't need to be bothered with.

    Consider this alteration to your original example:
    (Sorry about the doc blocks... can't seem to not add them :P)
    (Edit... turns out I could :D)
    [code=php]
    <?php
    class Hello {
    private $name;
    private $language;

    public function __construct($na me, $language="enUS ") {
    $this->name = $name;
    $this->language = $language;
    }

    public function sayHello() {
    echo "<h3>", $this->createHello( ), "</h3>";
    }

    public function getHello() {
    return "<h3>". $this->createHello( ) ."</h3>";
    }

    private function createHello() {
    if($this->language == "isIS") {
    return "Halló, ég heiti {$this->name}.";
    }
    else { // Defaults to enUS
    return "Hello, my name is {$this->name}.";
    }

    }
    }

    // Say it in english
    $eng = new Hello('Tom');
    $ice = new Hello('Atli', 'isIS');

    $eng ->sayHello();
    echo "<center>", $ice->getHello(), "</center>";
    ?>[/code]
    I've implemented both a "sayHello" and a "getHello" function, both using the "createHell o" function to provide the message.

    As the "createHell o" function was only ever meant to be used by the other class functions, it is made private; inaccessible to the outside.
    The other two, meant to provide functionality to outsiders, are public.

    I've also added the ability to change languages of the message.
    The "createHell o" function is the only function that is actually aware there is a language choice (besides the constructor), but because of the cooperation between the functions, the effect is shared between them.

    This also means that if I ever need to change the message, I only ever need to change it in one place.
    Likewise, if I ever need to change the way the hello message is printed, that is in one place, rather than scattered all over your outside code, as it would have been with your example.

    Do you see what I'm trying to say?

    Leave a comment:


  • Dormilich
    replied
    Originally posted by fjm
    In your example where you said that you would shorten it to sayHello(), isn't this acting more like a simple function than a class?
    well, yea, but do you want to handle any output through properties? (that may work for 1 or 2, but what about undefined/several different outputs?)

    Originally posted by fjm
    Because I had so many of these types of methods in a single class and would call them directly, I couldn't keep the methods private.
    methods are not supposed to be solely private, what use would the object then have (and what use would the interface have)?

    private methods are good, if you need tasks done that shouldn't be initialized from the outside (like e.g. connecting to a database or loading a configuration)

    Originally posted by fjm
    I know that in your example you are using the constructor to call the sayHello method but what if you have more than 1 or even 10 of these type of methods that require one or two variables? What do you do? How do you call them?
    ???

    Originally posted by fjm
    Code:
    $foo = new MyClass();
    echo $foo->myMethod($var);
    My example above requires that the myMethod() method remain public. Is this not a big deal?
    no

    Originally posted by fjm
    Also, say that I have 20 of these exact type of methods in the class that each expect one or two variables passed. It seems to me that if I am passing variables directly into the methods that I should forgo the class and just use a function. No? I don't see the difference or the advantage in using your sayHello() example over a simple function.
    not every method expects a variable input, often you can use the properties to pass around variables.

    in fact your example could be handled better by a function. but there are situations, where objects are better. I can think of writing an batch mail where the email addresses are stored in a DB.

    OOP is more than using private methods. you also have (to name some):
    - data encapsulation (prevents globals running wild)
    - inheritance (share code, re-usable)
    - patterns for common tasks (e.g. Singleton, Observer, Factory)
    - magic methods (kind of event handling)

    Leave a comment:


  • fjm
    replied
    Originally posted by Dormilich
    for this simple class there could even be more improvements, like omitting Hello->out and using sayHello() or even __toString() for output
    Ok, I understand that. Thanks. :)

    In your example where you said that you would shorten it to sayHello(), isn't this acting more like a simple function than a class? This was the way that I was using it before. Because I had so many of these types of methods in a single class and would call them directly, I couldn't keep the methods private.

    I know that in your example you are using the constructor to call the sayHello method but what if you have more than 1 or even 10 of these type of methods that require one or two variables? What do you do? How do you call them?

    $foo = new MyClass();
    echo $foo->myMethod($var) ;

    My example above requires that the myMethod() method remain public. Is this not a big deal? Also, say that I have 20 of these exact type of methods in the class that each expect one or two variables passed. It seems to me that if I am passing variables directly into the methods that I should forgo the class and just use a function. No? I don't see the difference or the advantage in using your sayHello() example over a simple function.

    Thanks for the help Dormi. :)

    Leave a comment:


  • Dormilich
    replied
    I wouldn't have named the method "sayHello" because it's not 'saying' (aka printing/outputting) anything, but generally it's right. personally, I don't see the necessity of every method having a return value (esp. when you have printing methods) though if possible I let it return true/false.

    on the other hand, you're not using the return value…

    some simplifications I'd make
    Code:
    class Hello
    {
        public  $out;
        private $text;
     
        public function __construct($text)
        {
            $this->text = $text;
            $this->out = $this->sayHello();
            // $this->sayHello();
        }
     
        private function sayHello()
        {
            return 'Hello, my name is: ' . $this->text;
            // $this->out = 'Hello, my name is: ' . $this->text;
        }
    }
    for this simple class there could even be more improvements, like omitting Hello->out and using sayHello() or even __toString() for output

    Leave a comment:


  • fjm
    started a topic OOP clarification

    OOP clarification

    Hey everyone. I'm back in search of a better understanding of OOP. I feel like these past couple of months have paid off for me because I am at a point where I am really beginning to understand how this all works. I'd like to get some clarification on a few things first.

    My questions stem from wanting to use private members and methods. I know that there is a reason for making methods and members public and private and honestly I'm still not totally clear as to when to use one over the other. I have been refactoring some of old classes and in looking at them, I was mortified. I figured that when I was redoing them that I should try and stick with private members and methods where possible because that's a good thing I guess.

    I had download an app a while back that used 5 classes. Each class was like 1500 lines or so and the code looked clean to me. I figured that was a good way to program. I started to do the same thing but after looking over some of my classes, I quickly noticed that my classes were nothing more than functions instead of objects.

    In refactoring this code, I separated out the methods that required functionality inside the class and set my constructor to call a main method that would do what was needed and then return out the values I needed. I just want to make certain that I understand correctly before I continue any further.

    If I have a class like so:

    Code:
    class Hello{
        public  $out;
        private $text;
    
        public function __construct($text)
        {
            $this->text = $text;
            $this->sayHello();
        }
    
        private function sayHello()
        {
            $text = $this->text;
            $var = 'Hello, my name is: ' . $text;
            return $this->out = $var;
        }
    }
    
    $hello = new Hello('Tom');
    echo $hello->out;
    To me, this seems like the correct way to write a class. I am returning out the values that I want. The way I was doing it in the past was to call the method directly and didn’t seem right.

    Does this look correct? I have a few more questions but I'll wait on those for now to see what the feedback is on this. I'll also show you how I was doing before.

    Thank!

    Frank
Working...