Communicating between Classes

My head is spinning from all of the advice and different approaches on Sitepoint so far…

However I believe that I read somewhere that it is “good” to communicate between classes/objects and “bad” to be passing data between objects.

Not understanding OOP, MVC, and lots of other things yet, hopefully this is a decent scenario…

I want to write code to register a new user. I think there should be two classes…

class Customer{

  • id
  • username
  • password
  • first_name
  • last_name
  • age

}

class Register{

  • username
  • password

  • isUniqueUsername()
  • isValidUsername()
  • isValidPassword()
  • sendActivationEmail()
  • activateCustomerAccount()
    }

Would I want to maybe read in the Username and Password from the form (via the Customer class) and then call the methods in the class Register?

My procedural background is used to writing start-to-finish blocks of codes to do something (e.g. “Register User”), but with OOP, I’m not sure of…

  • What classes/data to work with,
  • What to pass,
  • Where to pass it, or
  • How to communicate between classes/objects.

TomTees

Marcus has done an excellent walkthrough for your situation. Think of your page as a kind of controller. You’re going to have programming specifically for your page but it’s going to operate at a high level of abstraction. It’s not going to deal with implementation like databases, or copying this or that piece of data, or anything like that.

Your page will retrieve the data from the $_POST object, and do some grunt work like that as well as output any XHTML / text you need to output to the page. Otherwise it wants to call other objects / classes to do its dirty work for it.

Hence you’ll create an object from the RegistrationProcess class (I prefer RegistrationManager, you’ll use whatever name makes the most sense to you) is called by your page. You can process the data into one complex data type so it’s packaged, or pass in the simple data types the way Marcus shows. Calling the public function register() on your new object is how you hand off responsibility for all the further work needed. Now you’re running the register function. I would probably write register() as a do nothing function, a controller. All it will do is call other functions. Marcus has done a pretty stellar job of laying this kind of thing out. What are the details? We don’t know or care, they’re being handled by other functions that each do ONE thing.

PS I’m not as strict as Marcus is, I think 10 lines max is a bit harsh, but when I’m in my code editor, if I have to scroll more than a screen or so it starts getting difficult to manage and I absolutely start looking for ways to encapsulate something out to make things shorter.

For someone new to OOP, here is what I recommend to get a start. OOP is designed around two basic program levels: functions / data, and classes. A good OOP function is defined in the exact same way as a good procedural function. It should be cohesive. When I’m writing a function, I want it to do one thing or nothing (ie a controller that calls other functions to do its dirty work but doesn’t actually do anything itself).

I know many people have different perspectives, but I am an OOP programmer, and if you’re interested than you will be comfortable becoming one too. I know there are many people who never get beyond procedural programming, but as far as you’ve come already (and given how thoughtfully you’ve already set up your two classe) I think you will eventually have a hard time remembering why you waited so long. :wink: Here’s my take on it. OOP is a perfectly valid programming style that’s more than 30 years old. It is a direct outgrowth of procedural programmers who wanted language features that better enabled them to make their programming simpler and more understandable. Classes were simply added to the C programming language as a best practice to create the first OOP language in 1979, C++. OOP simply makes it easier to observe the best practices you want to use in procedural programming to limit your pain. So for me OOP is about making it easier to experience less pain… I like that! :smiley:

Think about when you have used structs in a procedural language. Do you want to have 200 variables in a complex web application? Hell no! So you group a bunch of the variables together into a User struct, and a bunch of variables into a Register struct, etc. Now instead of 200 simple data types, you now have maybe a dozen simple data types and 5 or six complex data types that encapsulate the other items. The human brain just consumes information better that way. (Try memorizing 250 cities. Not easy? Now try memorizing five cities from every state. It’s technically the same job, but it’s now much more managable).

OOP classes simply extend the struct. Your struct can contain your data. Your class works exactly the same as far as that goes. However, you can ALSO include your programming code as well. In fact, all of your programming code will go into the class that it pertains to. This will inevitably leave you with some ragged pieces that don’t really fit anywhere. That’s usually when I create an ApplicationLogic, or an ApplicationHelper class and you can write your “odd” functions in there. That’s the high level view.

Hi…

Not sure what this means. Communication means passing data, right?

Not sure either of these should be classes, but I don’t know enough aboput your problem yet. Right now your problem is simple enough that procedural will work just fine.

What’s caused you to look at OO?

You should have some kind of class with a register() method on it. That register method will take the username, password and whatever else it needs for the registration process.

Hm…I just said “registration process”. That sounds more like an object. Objects are things that do stuff. “Roles” or “actors” are alternate words.

How about…?


class RegistrationProcess {
    private $customers, $mailer;

    function __construct($customers, $mailer) {
        list($this->customers, $this->mailer) = array($customers, $mailer);
    }

    function register($username, $password, $name, $email, $address) {
        $this->throwIfInsecure($username, $password);
        $change = $this->customers->transactionalOperation();
        $person = $change->createPerson($name, $email, $address);
        $person->addCredentials($username, $password);
        $change->commit();
        $this->mailer->mail($email, 'Welcome', $this->welcomeEmail($name));
    }

    private function throwIfInsecure($username, $password) { ... }
    private function welcomeEmail($name) { ... }
}

Do the same, but don’t write any methods over 10 lines. This will force you to write local private methods to break the problem down, or to use external objects to do the work for you.

Which to choose? Above, the validation rules and the e-mail title and content were part of the registration process. It’s right that these remain local to this class. The rest of the process, transactions, talking to the database, sending mails, etc. is mechanical. Anything mechanical you want to push down into worker objects. Your method should describe the solution in a language appropriate to the problem.

Here the Mailer class will twiddle with mail headers and the ChangeSet class will keep track of the DB connection for us (assuming it is a DB). If you were describing the registration process to someone and you started to talk about mail headers their eyes would glaze over. That’s a sign it should be pushed down into another class with it’s own language.

yours, Marcus