开发者

When do you write a private method, versus protected? [closed]

开发者 https://www.devze.com 2022-12-15 17:01 出处:网络
Closed. This question is opinion-based. It is not currently accepting answers. 开发者_开发百科 Want to improve this question? Update the question so it can be answered with facts and citati
Closed. This question is opinion-based. It is not currently accepting answers. 开发者_开发百科

Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.

Closed 9 years ago.

Improve this question

If I'm writing a class, when do I make a method private, versus protected? In other words, how I can know in advance that a client programmer would never ever need to override a method? In a case where it's something that has external considerations, like a database connection?


public and protected methods form the 'interface' to your object, public for developers using (delegating to) your class, and protected for developers wishing to extend the functionality of your object by subclassing it.

Note that it's not necessary to provide protected methods, even if your class will be subclassed.

Both public and protected interfaces need careful thought, especially if this is an API to be used by developers outside your control, since changes to the interface can break programs that make assumptions about how the existing interface works.

private methods are purely for the the author of the object, and may be refactored, changed and deleted at will.

I would go for private by default, and if you find you need to expose more methods, have a careful think about how they will be used - especially if they are virtual–what happens if they are replaced completely with an arbitrary alternative function by another developer–will your class still work? Then design some appropriate protected which are useful for developers subclassing your object (if necessary), rather than exposing existing functions.


In other words, how I can know in advance that a client programmer would never ever need to override a method?

You cannot. And you don't need to. It is not your job to anticipate IF a developer might want to override a method, let alone how. Just assume he wants to and enable him to do so without having to touch your code. And for this reason, do not declare methods private if you don't have to.

If a developer feels he needs to adjust some functionality of your classes, he can pick from a number of structural and behavioral patterns to do so, e.g. Decorators, Adapters or by subclassing. Using these patterns is good, because it encapsulates the changes into the developer's own class and leaves your own code untouched. By declaring methods private, you make sure the developer will monkey with your class. And that is bad.

A perfect example is Zend Framework's DB adapter. They discourage the use of persistent connections and their adapters provide no mean to this end. But what if you'd want to have this nonetheless and the adapter method was marked private (it isn't, but what if)? Since there is no way to overwrite the method, you would (yes, you would) change the adapter code right within it's class or you'd copy & paste the code into your own adapter class, effectively duplicating 99% of the class just to change a single function call. Whenever there is an update to this adapter, you either would lose your changes or you wouldn't get it (in case you c&p'd). Had it been marked protected (as it is), you could just have written a pConnectAdapter subclass.

Moreover, when subclassing, you are effectively saying subClass is a parentClass. Thus, you can expect the derived class to have the same functionality as the parentClass. If there is functionality in the parentClass that should not be available in the subClass, then disabling it conceptually belongs to the subClass.

This is why I find it much better practise to default all methods and properties to protected visibility and only mark those methods (not properties though) supposed to allow interaction with my class from another class or script as public, but only a few things private. This way, I give the developer the choice of using my class as I intended it to be used and the option to tweak it. And if he breaks something in the process, it is very likely his fault then, not mine.

Update: since I wrote this four years ago I have come to the conclusion that defaulting things to protected instead of private often leads to suboptimal subclasses. This is because people will start to use whatever you provided as protected. This in turn means you have to consider all these methods as API and may not change them at will. As such, it's better to carefully consider what extensions points you want to provide and keep the everything else private. See http://fabien.potencier.org/article/47/pragmatism-over-theory-protected-vs-private for a similar view.


I typically will start at the lowest level. If you're unsure make it private. Then as needed you can make things protected or public.

The idea being it is not a breaking change to go from private to protected but it could be a breaking change to go the other way.


Don't think of the private/protected/public thing as if a programmer would ever "need" a method. Think of it as if you want to allow them access to it.

If you think they should be allowed to change the DB Connection String then make it public.


I always make all methods private as default. This is to keep the interface clean and easy to maintain.

It is much harder to change or hide an already visible method than to make a private method more visible. At least if you need to be compatible with existing client code.


In other words, how I can know in advance that a client programmer would never ever need to override a method?

If you don't know assume they will need to. If that's fine by you (ie, if you think they should be able to) then use protected; otherwise use private.


Private members are used to encapsulate the inner workings of your class. Use them to hold data that only you want to be able to access. For example, let's say you have a field called _name and a getter/setter named GetName()/SetName(name). Maybe you want to do some syntax checking on name before you allow the SetName to succeed, else you throw an exception. By making _name private, you ensure that this syntax checking will occur before any changes to name can occur (unless you yourself change _name in your own class, in your own code). By making it protected, you're saying to any potential future inheritor of your class, "go ahead and monkey with my field."

In general, protected is used sparingly and only in specialized cases. For example, you might have a protected constructor that exposes some additional construction functionality to child classes.


I typically just make everything private and refactor when I need to call it from a base class.

Except when I feel lazy and do everything protected that isn't definitely dangerous.

0

精彩评论

暂无评论...
验证码 换一张
取 消