Jader Dias
Jader Dias

Reputation: 90465

How to decide if a method will be private, protected, internal or public?

I am designing a class where some methods won't cause any harm if they are exposed as public. But they can be private as well, since they will be used only from the same class in my project.

Making them public has the following advantages:

  1. Unit Testable without the need of accessors.
  2. Flexibility.

Making them private has the following advantages:

  1. Public documentation simplification.
  2. Some unknown bugs aren't exposed.

Which are the general guidelines in this case?

Upvotes: 5

Views: 1603

Answers (8)

Mark Simpson
Mark Simpson

Reputation: 23365

If you find that it's difficult to thoroughly test a class, then the class may be doing too much. Splitting the class up using composition can make the individual units more testable.

Sometimes it makes sense, other times it does not. Just a thought.

Upvotes: 2

Mehmet Aras
Mehmet Aras

Reputation: 5374

Expose just what's needed for your intended clients and usage scenarios and nothing more. I would not consider unit testing as a client and make changes so that the code not intended for public consumption to begin with is publicly accessible just for the sake of unit testing. If you do, you will clutter up your api, reduce the usability of your api, and make future changes harder and not ideal as there may now be client code that uses what's supposed to be private api.

I would check if you have a better alternatives. For example, you can generate private accessors in Visual Studio 2005 and 2008 that make non-public api of a class publicly available for testing purposes. This may clutter up your unit test code but to me the most important thing is your design and the api you're releasing to your clients including you and your team.

On another note, I would also mention that the unit testing gives you a great opportunity to see how well your design is and how easy it is to consume your api from a client perspective. Armed with frustration, issues, etc during unit test development, you make changes to enhance your api and design to be more simple, beautiful, and usable.

Upvotes: 1

trappedIntoCode
trappedIntoCode

Reputation: 805

Oh, please please read Ch. 06 Of Code Complete 2 by Steve McConnell, if you have access to it. That will answer your question perfectly.

In general, If the Method fits in the overall "Persona" of the class, make it public. More technically, try not to break the abstraction. I would have given an example, but I do not know the context of your work and so examples might be irrelevant.

If you do not need it, there is no need to make a Method public.

For testing, +1 to John sanders.

But I really can not explain you here as Steve has explained in CC2.

I hope its OK to post Book references on Satckoverflow? (Please comment.)

Upvotes: 4

Cerebrus
Cerebrus

Reputation: 25775

I would NEVER make my privates public ! Period.

Upvotes: 1

Andrew Hare
Andrew Hare

Reputation: 351476

The only public members of a type should be a part of the public interface of the type itself. Your goal should be to minimize the interface of the type to the fewest number of members and expose little to none of the underlying implementation.

Upvotes: 3

TheTXI
TheTXI

Reputation: 37875

I am a big fan of only making public what you explicitly want to make public. I like the warm safe cocoon that my class offers me.

Upvotes: 4

John Saunders
John Saunders

Reputation: 161773

Always make everything as private as possible.

For unit testing, I sometimes make a member internal, then use the InternalsVisibleTo attribute in the AssemblyInfo.cs to permit the unit test assembly access to the internal members.

Upvotes: 13

C. K. Young
C. K. Young

Reputation: 223003

In this case, I'd usually make them as private as possible, and then promote their accessibility when the need arises (e.g., code from other classes would benefit from being able to access those methods directly). It's easy to add methods to an API, and much harder to remove them (without breaking other code).

Upvotes: 4

Related Questions