Independent getter/setter methods, or combined?

2019-03-18 01:33发布

While working on a project, I've been making some changes and browsing around existing framework API docs for insight.

While perusing the Kohana docs, I noticed that the getters/setters of any given class are typically combined:

public function someProperty($value = null){
    if(is_null($value){
        return $this->_someProperty;
    }
    $this->_someProperty = $value;
    return $this;
}

Rather than:

public function setSomeProperty($value){
    $this->_someProperty = $value;
    return $this;
}

public function getSomeProperty(){
    return $this->_someProperty;
}

Is there any value in doing this (the former), beyond lessening the method count of a given class? I was always under the understanding that methods (functions in general) should be more descriptive of an action. Do other experienced developers cringe, even a tiny bit, when they see this?

I was just surprised to see a popular framework use such conventions (I haven't used Kohana of course)

7条回答
做自己的国王
2楼-- · 2019-03-18 01:51

I consider this bad practise because it violates CommandQuerySeparation. Setting a value is changing state (Command). Getting a value is asking for state (Query). A method should not do both, but one thing only.

Also, it's not really obvious what a method does when it's just called username, e.g. does not have a verb, like get or set. This gets even worse in your example, because the return value is either the object itself or the property value, so its not consistent.

Moreover, getters (and setters) should be used sparingly as they will quickly convolute your API. The more getters and setters you have, the more knowledge about an object is required by collaborators of that object. If you find your objects asking other objects about their internals, chances are you misplaced the responsibilities.

查看更多
手持菜刀,她持情操
3楼-- · 2019-03-18 01:52

For the sake of argument,

The combined approach does offer some benefits:

  1. Avoids __get and __set magic while still emulating a public property. (I would not ever recommend using magic for these situations anyway)
  2. Using thing() is less verbose than using getThing() setThing().
  3. Even though the methods will be doing more, they can still be considered as "doing one thing()", that is handling the thing(). Properties also do more than one thing. They allow you to set and get values.
  4. It's argued that the thing() doesn't give a verb. However, we can assume that a thing() without a verb means that we use it like a property (we get and set it). For interfaces, we can say that a thing() with no argument is readonly and a thing($arg) with an argument is read/write. Why should we be shy from adopting this? At some point we adopted the idea of adding getters and setters didn't we?
  5. If you are using a web-based language (like PHP), then chances are you might be using jQuery as well. JQuery is already doing this sort of thing() and it has worked out well.
  6. Using func_num_args(), as mentioned already, helps achieve this approach perfectly.

Personally, I've already taken a good portion of risks in my current apps at this point so I'm probably going with the old tried-and-true getters and setters (see the section "Finding the Balance" of Jimmy Bogard's post in regards to getters/setters for data operations). And I suppose we are already trained to look for these get/set prefixes (as well as our IDE's) to see what properties we can work with in a class. This is a discussion I would be open to returning to at some point.

查看更多
我欲成王,谁敢阻挡
4楼-- · 2019-03-18 02:00

If you do it everywhere it is a good way, but than it really needs to be for everything, maybe the programmers of this framework are used to is, (it's a bit jquery alike)

However it would confuse me

For setting and getting I always use setters and getters:

   public function __set($key, $value) {
      // assign value $value to $this->key
   }

   public function __get($key) {
      // return value of this->key
   }
查看更多
男人必须洒脱
5楼-- · 2019-03-18 02:02

jQuery goes the same way as Kohana. However I think it's better to create separate methods for setting and getting. It's more obvious what the method does and I think it's more practically in code-completition in your ide. For example you type set and you get a list of all Properties you can set.

Another disadvantage is: what if you want to set a value really to null? This wouldn't work since the null is the identifier for returnin the value, you are restricted in setting specific values...

So it's nice, since you'll have to write less, but hey what are three letters (set/get) in front of your methods?

查看更多
趁早两清
6楼-- · 2019-03-18 02:08

I'd rather believe they had a reasonable explanation for doing it this way. For example, for easier implementation of ArrayAccess. Only way to know for sure is to ask them directly.

To answer your question, yes I cringe when I see the first method. Goes against OOP principles.

查看更多
淡お忘
7楼-- · 2019-03-18 02:12

Despite the fact that Kohana uses such unusual technique for the OOP, I think you should follow coding conventions at first. But of course it's better to use separate getters and setters for every property in your classes. So, if it's possible to use them not breaking the conventions - just do it and you won't be wrong ;) . You can also read here about good habits in PHP OOP - http://www.ibm.com/developerworks/opensource/library/os-php-7oohabits/ if you've doubted about using some OOP technics. Hope that it'll help :)

查看更多
登录 后发表回答