Questions about getters and setters, methods, and patterns

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
RiscOS
Forum Newbie
Posts: 4
Joined: Fri Aug 08, 2008 6:08 am

Questions about getters and setters, methods, and patterns

Post by RiscOS »

1: Must I use getters and setters? What if a class has 20+ instance variables? I'd then have to create 40 extra instance methods to handle getting and setting.

2: Function/method arguments. Should I check before doing anything in the method that the args are the correct type and if they are not return?

3: Should functions always return something? Even if it something like true, just to indicate everything went ok? Is it bad programming not to?

4: I am developing a web app. I have the main class as a Singleton so that only one is ever made. I have an class property, an array (with multiple sub arrays) for storing the info for the application. I read that for info like this you should make a new object with the Registry/Register pattern and pass this obkect instead to your other classes.

Is this any better then just passing the array in my main class (or part of it)?
marcth
Forum Contributor
Posts: 142
Joined: Mon Aug 25, 2008 8:16 am

Re: Questions about getters and setters, methods, and patterns

Post by marcth »

RiscOS wrote:1: Must I use getters and setters? What if a class has 20+ instance variables? I'd then have to create 40 extra instance methods to handle getting and setting.
No. I wouldn't recommend mixing things up though--either a class uses setters/getters or it doesn't. You should read up on PHP's magic methods. Read up on Overloading as well.
RiscOS wrote: 2: Function/method arguments. Should I check before doing anything in the method that the args are the correct type and if they are not return?
Sometimes. PHP is not a strongly typed language. I always type-cast objects and array parameters:

Code: Select all

<?php
class ActionResponse {}

class boo {
  public function foo(ActionResponse $response), array $params) {}
}
?>
RiscOS wrote: 3: Should functions always return something? Even if it something like true, just to indicate everything went ok? Is it bad programming not to?
No. But don't mixed it up. If a method can potentially return a value, the method should always return a value. Personally, my methods always return values that have the same meaning (example: returning a positive number referrs to a primary key but returning a negative number refers to a DB error code = BAD).
RiscOS wrote: 4: I am developing a web app. I have the main class as a Singleton so that only one is ever made. I have an class property, an array (with multiple sub arrays) for storing the info for the application. I read that for info like this you should make a new object with the Registry/Register pattern and pass this obkect instead to your other classes.

Is this any better then just passing the array in my main class (or part of it)?
I would avoid using Singletons in your app (They are basically Global variables, which all to often make a mess of things). I suppose if you needed one, it would be some sort of Settings singleton that holds all your configurations for your app. You'd want to pass this Settings singleton into your Main class. You main class does not have to be a Singleton. What does it matter if people instantiate it twice?
RiscOS
Forum Newbie
Posts: 4
Joined: Fri Aug 08, 2008 6:08 am

Re: Questions about getters and setters, methods, and patterns

Post by RiscOS »

Do you use getters and setters?

Ok. I shall not use the Singelton pattern for my core class. I've read about this and thought maybe as it's the main class I should make sure it's only called once. I guess it doesn't matter. So shall I keep the settings in my main classes app as a property? Or should I make a Singleton Object and store the info there? or maybe a Registry type object?
marcth
Forum Contributor
Posts: 142
Joined: Mon Aug 25, 2008 8:16 am

Re: Questions about getters and setters, methods, and patterns

Post by marcth »

Generally, I don't use Setters/Getters. The only time I would is if I wanted to validate what's being set, or format what's being "getted" :)

Here's an example of a Settings Singleton (There may be bugs in it and it's not complete).

Code: Select all

<?php
class Settings {
  private $settings;
  private static $instance;
  private $importedFile;
 
  public function __construct() {
    $this->settings = array();
    $this->importedFile = NULL;
  }
 
 
  public function __set($name, $value) {
    $this->settings[$name] = $value;
  }
 
 
  public function __get($name) {
    return array_key_exists($name, $this->settings)? $this->settings[$name] : NULL;
  }
 
 
  public static function getInstance() {
    if(is_null(self::$instance)) {
      self::$instance = new Settings();
    }
    
    return self::$instance; 
  }
 
 
  /*
   * 
  */
  public function import($file) {
    $this->importedFile = realpath($file);
 
    switch(strtolower(strrchr($file, "."))) {
      case '.php':
        require ($file);
        unset($file);
        $this->settings = array_merge($this->settings, get_defined_vars());
      break;
    
      default:
       throw new Exception(__METHOD__ . ' does not know how to import the specified configuration file');
      break;
    }
  }
 
 
  public function reset() {
    $this->settings = array();
    $this->import($this->importedFile);
  }
}
?>
RiscOS
Forum Newbie
Posts: 4
Joined: Fri Aug 08, 2008 6:08 am

Re: Questions about getters and setters, methods, and patterns

Post by RiscOS »

I see you use array_key_exists.

I was using that for checking certain keys existed in my settings array, but i was reading on the somewhere on the web that it is slow and that you should use isset() instead.

What do you think about this? Unless arrays have several hundred elements, am I likely to see any speed improvement using isset?
marcth
Forum Contributor
Posts: 142
Joined: Mon Aug 25, 2008 8:16 am

Re: Questions about getters and setters, methods, and patterns

Post by marcth »

RiscOS wrote:I see you use array_key_exists.

I was using that for checking certain keys existed in my settings array, but i was reading on the somewhere on the web that it is slow and that you should use isset() instead.

What do you think about this? Unless arrays have several hundred elements, am I likely to see any speed improvement using isset?
I don't really care. In the applications I write (and in my experience), it's always the database that's the bottleneck. You can accustom yourself to using isset over array_key_exists if you'd like--I doubt very much if you'd notice a performance increase. And if you have an associative array with 1000s of items, I think you'll have bigger problems that the use of array_key_exists.
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: Questions about getters and setters, methods, and patterns

Post by allspiritseve »

RiscOS, what kind of application are you making? How many classes do you have?

If you have one class with 20 properties that don't need to be modified before they're accessed, then I think you should either be using an array instead, or refactoring that class into a couple of other classes. The key question you need to ask, is whether this class has any behavior, or is just meant to hold data. Maybe you could post the class here, and we could help you decide?

I would advise against a singleton. If multiple classes need your config/settings data, pass them as an array in the constructor of those classes. Maybe I'm wrong, but it doesn't seem like you're at the point of needing a registry. For now, just work on passing everything a class needs in it's constructor, and when that becomes too difficult, look for a better solution.
marcth
Forum Contributor
Posts: 142
Joined: Mon Aug 25, 2008 8:16 am

Re: Questions about getters and setters, methods, and patterns

Post by marcth »

TBA
marcth
Forum Contributor
Posts: 142
Joined: Mon Aug 25, 2008 8:16 am

Re: Questions about getters and setters, methods, and patterns

Post by marcth »

What allspiritseve is quite important. Are you trying to build a high-traffic site?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Questions about getters and setters, methods, and patterns

Post by alex.barylski »

What if a class has 20+ instance variables
Then you need to seriously consider refactoring your class into smaller classes.
marcth
Forum Contributor
Posts: 142
Joined: Mon Aug 25, 2008 8:16 am

Re: Questions about getters and setters, methods, and patterns

Post by marcth »

Hockey wrote:
What if a class has 20+ instance variables
Then you need to seriously consider refactoring your class into smaller classes.
agreed
webaddict
Forum Commoner
Posts: 60
Joined: Wed Mar 14, 2007 6:55 am
Location: The Netherlands

Re: Questions about getters and setters, methods, and patterns

Post by webaddict »

RiscOS wrote:1: Must I use getters and setters? What if a class has 20+ instance variables? I'd then have to create 40 extra instance methods to handle getting and setting.
Well, as Hockey already mentioned: if you have > 20 attributes in a class, it probably does to much and it is time to refactor. That said, I tend to think that accessors and mutators (get/set-ters) are used too frequently in the php surroundings. An object represents both data and behaviour and can be talked to through a public interface. If it has no behaviour, then it's merely a Data Transfer Object, which in PHP can be easily reduced to an array or an stdObject.

Usually, an object that incorperates no behaviour indicates misplaced responsibility, because it usually indicates a clear violation of the important OO principle "tell don't ask". One of the key differences between procedural programming and object oriented programming is that in procedural programming you would ask for data and then go on using aforementioned data for example in a procedure. In object oriented programming you should be asking the object that has the data "do this for me, ok?".

Now, I'm not saying that I think all getters and setters are useless or undesirable: they certainly do have their uses. One of the main reasons that people use getters and setters is to comply with standards that are imposed by using a third party library, such as an ORM. Since an ORM has to save an objects attributes to the database, it'll have to know how to get them.

If you ask me, the preffered way to decide whether or not you should incorporate a setter or getter for a certain attribute is experience. That is to say: don't write it initially and only write it if time proves that you can't live without it.
RiscOS wrote:2: Function/method arguments. Should I check before doing anything in the method that the args are the correct type and if they are not return?
Well, you can obviously only work with the correct values, no? Some incoming values are easily transformed or typecasted to it's correct datatype, but sometimes that is just not possible. On such occasions, you'll have to let the client code know what just happened and why you can not continue executing the behaviour.

A likely scenario is that you get a wrong datatype because you did something wrong somewhere. Usually the interface between objects is well-defined (or it should be) and the client code will know what type the object is. In that exact situation assertions might be helpful. The assert function of PHP is - in my opinion - a hidden gem. It really is a very easy development tool. So: if you're expecting something to be an integer, you could just assert( is_int( $id ) ). Just remember that this is a development aid, not a way to validate user input.
RiscOS wrote:3: Should functions always return something? Even if it something like true, just to indicate everything went ok? Is it bad programming not to?
Hmm.. I dare not say that it is bad programming not to return something from a method, but in practice I always do return. Remember: return values and exceptions are the only way to communicate with client code. In my humble opinion public methods should always return a value, to indicate whether or not the requested behaviour was succesfully executed.
RiscOS wrote:4: I am developing a web app. I have the main class as a Singleton so that only one is ever made. I have an class property, an array (with multiple sub arrays) for storing the info for the application. I read that for info like this you should make a new object with the Registry/Register pattern and pass this obkect instead to your other classes.
Stop it. Seriously. The singleton pattern is getting abused by many in php today, while the implementation can not be justified and the benefits don't outweigh the disadvantages. If you want just one object of that type, just instantiate it once. If you want further clarification on that statement, don't hasitate to ask.

Also, your mention of a "main class" is making my neckhares stand up straight. Objects should have a clearly defined responsibility: a "User" should be able to login. What is a "Main" supposed to do?


EDIT: Sorry for the lengthy reply, I want to be "Fastest Advancing Newcomer 2009" :P
Last edited by webaddict on Mon Sep 15, 2008 7:34 am, edited 1 time in total.
jmut
Forum Regular
Posts: 945
Joined: Tue Jul 05, 2005 3:54 am
Location: Sofia, Bulgaria
Contact:

Re: Questions about getters and setters, methods, and patterns

Post by jmut »

RiscOS wrote:I see you use array_key_exists.

I was using that for checking certain keys existed in my settings array, but i was reading on the somewhere on the web that it is slow and that you should use isset() instead.

What do you think about this? Unless arrays have several hundred elements, am I likely to see any speed improvement using isset?
OFF
isset and array_key_exists are not interchangable! Decision is not performance but rather what you need function do. array_key_exist will return true on index having value null, while isset will return false!
koen.h
Forum Contributor
Posts: 268
Joined: Sat May 03, 2008 8:43 am

Re: Questions about getters and setters, methods, and patterns

Post by koen.h »

marcth wrote:
Hockey wrote:
What if a class has 20+ instance variables
Then you need to seriously consider refactoring your class into smaller classes.
agreed
While this is probably true in most cases it is possible to come up with scenarios where objects do need those variables. Consider something like Zend_Session with all those PHP session settings.

Another example could be an action controller where the class provides some convenience properties (db, session, acl, ...). Many people would take them from a registry or a service locator at instantiation time or pass it to the constructor. I'm having difficulty with this. How do you know what object $this->db will be in your controller? What methods can you expect to be available? Most likely somewhere on the other side of your project there is a bit of code that determines that this db object implements IDatabase. But how can the controller know this?

I think that the most clean OO way is to use setters with type hinting. It asks more code but it takes the guess work (and potential errors) out of client coders code.
Post Reply