Related
Reflection can be used to access just about any object's internals, which is kind of not cool. I tried to list the legitimate uses of it, but in the end only serialization came to my mind.
What other (legitimate) uses can you find to using reflection in order to access otherwise inaccessible members?
EDIT I mean stuff you can't do if you don't have reflection.
Unit testing comes to mind. If you want to test a private method but not expose it or use the InternalsVisibleToAttribute.
One is persisting objects to a DB. E.g. Hibernate does use reflection, and in some cases e.g. the object's ID might be a private member, with private setter/getter, because it is of no use in the Java domain. However it is needed in the DB, so Hibernate sets/gets it in the background, and uses it for determining object identity.
Another is writing the initial unit tests for badly designed legacy code, where you can't just start refactoring since you have no unit tests to safeguard yourself. In such cases, if other means (described in Working Effectively with Legacy Code) can't help you, reflection may be the last resort to start working towards maintainable code.
I guess one big area where it is used is in the context of managed environment, that is, when an framework or environment is supposed to provide some facilities and might require to access to private data.
Public/private access modifier is a concern at the application design level and a field shouldn't be turned public for the sake of making a framework happy. Examples include then framework like Hibernate which manages object persistence, dependency injection framework which can inject data in private field, or more generally application server which work regardless of the access modifier.
Even more generally, this fall into the umbrella of meta-programming. Some code inspects and modifies other objects dynamically without knowing their structure upfront.
Profiling or monitoring can be useful reasons to use reflection to private members and functions. For example, if you want to know how often a database connection is actually made, you can monitor access to a private SqlConnection.
This can better be done with AOP, but, if trying to get AOP to be acceptable is too difficult politically, then reflection can help out while you are in development.
You can also use reflection to invoke the methods based upon input type parameter ( like enum), thus essentially replacing a switch statement.
for example:
enter code here
public class Test
{
public enum Status
{
Add,
Delete,
Update
}
public void Save(Status status)
{
//use reflection to obtain corresponding method
MethodInfo method = this.GetType().GetMethod(status.ToString(),BindingFlags.NonPublic | BindingFlags.Instance);
//Invoke method here
}
//you don't want to expose these methods
private void Add()
{
}
private void Delete()
{
}
private void Update()
{
}
}
Debugging and profiling come to mind immediately -- they need to be able to get a more complete view of the internals of objects.
Garbage collection is another -- yes, the JVM has a garbage collector built in, but someone has to write that code and while most JVMs aren't written in java, there's no reason they couldn't be.
This is quite a controversial topic, and before you say "no", is it really, really needed?
I have been programming for about 10 years, and I can't honestly say that I can recall a time where inheritance solved a problem that couldn't be solved another way. On the other hand I can recall many times when I used inheritance, because I felt like I had to or because I though I was clever and ended up paying for it.
I can't really see any circumstances where, from an implementation stand point, aggregation or another technique could not be used instead of inheritance.
My only caveat to this is that we would still allow inheritance of interfaces.
(Update)
Let's give an example of why it's needed instead of saying, "sometimes it's just needed." That really isn't helpful at all. Where is your proof?
(Update 2 Code Example)
Here's the classic shape example, more powerful, and more explicit IMO, without inheritance. It is almost never the case in the real world that something really "Is a" of something else. Almost always "Is Implemented in Terms of" is more accurate.
public interface IShape
{
void Draw();
}
public class BasicShape : IShape
{
public void Draw()
{
// All shapes in this system have a dot in the middle except squares.
DrawDotInMiddle();
}
}
public class Circle : IShape
{
private BasicShape _basicShape;
public void Draw()
{
// Draw the circle part
DrawCircle();
_basicShape.Draw();
}
}
public class Square : IShape
{
private BasicShape _basicShape;
public void Draw()
{
// Draw the circle part
DrawSquare();
}
}
I blogged about this as a wacky idea a while ago.
I don't think it should be removed, but I think classes should be sealed by default to discourage inheritance when it's not appropriate. It's a powerful tool to have available, but it's like a chain-saw - you really don't want to use it unless it's the perfect tool for the job. Otherwise you might start losing limbs.
The are potential language features such as mix-ins which would make it easier to live without, IMO.
Inheritance can be rather useful in situations where your base class has a number of methods with the same implementation for each derived class, to save every single derived class from having to implement boiler-plate code. Take the .NET Stream class for example which defines the following methods:
public virtual int Read(byte[] buffer, int index, int count)
{
}
public int ReadByte()
{
// note: this is only an approximation to the real implementation
var buffer = new byte[1];
if (this.Read(buffer, 0, 1) == 1)
{
return buffer[0];
}
return -1;
}
Because inheritance is available the base class can implement the ReadByte method for all implementations without them having to worry about it. There are a number of other methods like this on the class which have default or fixed implementations. So in this type of situation it's a very valuable thing to have, compared with an interface where your options are either to make everyone re-implement everything, or to create a StreamUtil type class which they can call (yuk!).
To clarify, with inheritance all I need to write to create a DerivedStream class is something like:
public class DerivedStream : Stream
{
public override int Read(byte[] buffer, int index, int count)
{
// my read implementation
}
}
Whereas if we're using interfaces and a default implementation of the methods in StreamUtil I have to write a bunch more code:
public class DerivedStream : IStream
{
public int Read(byte[] buffer, int index, int count)
{
// my read implementation
}
public int ReadByte()
{
return StreamUtil.ReadByte(this);
}
}
}
So it's not a huge amount more code, but multiply this by a few more methods on the class and it's just unnecessary boiler plate stuff which the compiler could handle instead. Why make things more painful to implement than necessary? I don't think inheritance is the be-all and end-all, but it can be very useful when used correctly.
Of course you can write great programs happily without objects and inheritance; functional programmers do it all the time. But let us not be hasty. Anybody interested in this topic should check out the slides from Xavier Leroy's invited lecture about classes vs modules in Objective Caml. Xavier does a beautiful job laying out what inheritance does well and does not do well in the context of different kinds of software evolution.
All languages are Turing-complete, so of course inheritance isn't necessary. But as an argument for the value of inheritance, I present the Smalltalk blue book, especially the Collection hierarchy and the Number hierarchy. I'm very impressed that a skilled specialist can add an entirely new kind of number (or collection) without perturbing the existing system.
I will also remind questioner of the "killer app" for inheritance: the GUI toolkit. A well-designed toolkit (if you can find one) makes it very, very easy to add new kinds of graphical interaction widgets.
Having said all that, I think that inheritance has innate weaknesses (your program logic is smeared out over a large set of classes) and that it should be used rarely and only by skilled professionals. A person graduating with a bachelor's degree in computer science barely knows anything about inheritance---such persons should be permitted to inherit from other classes at need, but should never, ever write code from which other programmers inherit. That job should be reserved for master programmers who really know what they're doing. And they should do it reluctantly!
For an interesting take on solving similar problems using a completely different mechanism, people might want to check out Haskell type classes.
I wish languages would provide some mechanisms to make it easier to delegate to member variables. For example, suppose interface I has 10 methods, and class C1 implements this interface. Suppose I want to implement class C2 that is just like a C1 but with method m1() overridden. Without using inheritance, I would do this as follows (in Java):
public class C2 implements I {
private I c1;
public C2() {
c1 = new C1();
}
public void m1() {
// This is the method C2 is overriding.
}
public void m2() {
c1.m2();
}
public void m3() {
c1.m3();
}
...
public void m10() {
c1.m10();
}
}
In other words, I have to explicitly write code to delegate the behavior of methods m2..m10 to the member variable m1. That's a bit of a pain. It also clutters the code up so that it's harder to see the real logic in class C2. It also means that whenever new methods are added to interface I, I have to explicitly add more code to C1 just to delegate these new methods to C1.
I wish languages would allow me to say: C1 implements I, but if C1 is missing some method from I, automatically delegate to member variable c1. That would cut down the size of C1 to just
public class C2 implements I(delegate to c1) {
private I c1;
public C2() {
c1 = new C1();
}
public void m1() {
// This is the method C2 is overriding.
}
}
If languages allowed us to do this, it would be much easier to avoid use of inheritance.
Here's a blog article I wrote about automatic delegation.
Inheritance is one of those tools that can be used, and of course can be abused, but I think languages have to have more changes before class-based inheritance could be removed.
Let's take my world at the moment, which is mainly C# development.
For Microsoft to take away class-based inheritance, they would have to build in much stronger support for handling interfaces. Things like aggregation, where I need to add lots of boiler-plate code just to wire up an interface to an internal object. This really should be done anyway, but would be a requirement in such a case.
In other words, the following code:
public interface IPerson { ... }
public interface IEmployee : IPerson { ... }
public class Employee : IEmployee
{
private Person _Person;
...
public String FirstName
{
get { return _Person.FirstName; }
set { _Person.FirstName = value; }
}
}
This would basically have to be a lot shorter, otherwise I'd have lots of these properties just to make my class mimic a person good enough, something like this:
public class Employee : IEmployee
{
private Person _Person implements IPerson;
...
}
this could auto-create the code necessary, instead of me having to write it. Just returning the internal reference if I cast my object to an IPerson would do no good.
So things would have to be better supported before class-based inheritance could be taken off the table.
Also, you would remove things like visibility. An interface really just have two visibility settings: There, and not-there. In some cases you would be, or so I think, forced to expose more of your internal data just so that someone else can more easily use your class.
For class-based inheritance, you can usually expose some access points that a descendant can use, but outside code can't, and you would generally have to just remove those access points, or make them open to everyone. Not sure I like either alternative.
My biggest question would be what specifically the point of removing such functionality would be, even if the plan would be to, as an example, build D#, a new language, like C#, but without the class-based inheritance. In other words, even if you plan on building a whole new language, I still am not entirely sure what the ultimate goal would be.
Is the goal to remove something that can be abused if not in the right hands? If so, I have a list a mile long for various programming languages that I would really like to see addresses first.
At the top of that list: The with keyword in Delphi. That keyword is not just like shooting yourself in the foot, it's like the compiler buys the shotgun, comes to your house and takes aim for you.
Personally I like class-based inheritance. Sure, you can write yourself into a corner. But we can all do that. Remove class-based inheritance, I'll just find a new way of shooting myself in the foot with.
Now where did I put that shotgun...
Have fun implementing ISystemObject on all of your classes so that you have access to ToString() and GetHashcode().
Additionally, good luck with the ISystemWebUIPage interface.
If you don't like inheritance, my suggestion is to stop using .NET all together. There are way too many scenarios where it saves time (see DRY: don't repeat yourself).
If using inheritance is blowing up your code, then you need to take a step back and rethink your design.
I prefer interfaces, but they aren't a silver bullet.
For production code I almost never use inheritance. I go with using interfaces for everything (this helps with testing and improves readability i.e. you can just look at the interface to read the public methods and see what is going on because of well-named methods and class names). Pretty much the only time I would use inheritance would be because a third party library demands it. Using interfaces, I would get the same effect but I would mimic inheritance by using 'delegation'.
For me, not only is this more readable but it is much more testable and also makes refactoring a whole lot easier.
The only time I can think of that I would use inheritance in testing would be to create my own specific TestCases used to differentiate between types of tests I have in my system.
So I probably wouldn't get rid of it but I choose not to use it as much as possible for the reasons mentioned above.
No. Sometimes you need inheritance. And for those times where you don't -- don't use it. You can always "just" use interfaces (in languages that have them) and ADPs without data work like interfaces in those languages that don't have them. But I see no reason to remove what is sometimes a necessary feature just because you feel it isn't always needed.
No. Just because it's not often needed, doesn't mean it's never needed. Like any other tool in a toolkit, it can (and has been, and will be) misused. However, that doesn't mean it should never be used. In fact, in some languages (C++), there is no such thing as an 'interface' at the language level, so without a major change, you couldn't prohibit it.
No, it is not needed, but that does not mean it does not provide an overall benefit, which I think is more important than worrying about whether it is absolutely necessary.
In the end, almost all modern software language constructs amount to syntactic sugar - we could all be writing assembly code (or using punch cards, or working with vacuum tubes) if we really had to.
I find inheritance immensely useful those times that I truly want to express an "is-a" relationship. Inheritance seems to be the clearest means of expressing that intent. If I used delegation for all implementation re-use, I lose that expressiveness.
Does this allow for abuse? Of course it does. I often see questions asking how the developer can inherit from a class but hide a method because that method should not exist on the subclass. That person obviously misses the point of inheritance, and should be pointed toward delegation instead.
I don't use inheritance because it is needed, I use it because it is sometimes the best tool for the job.
I guess I have to play the devil's advocate. If we didn't have inheritance then we wouldn't be able to inherit abstract classes that uses the template method pattern. There are lots of examples where this is used in frameworks such as .NET and Java. Thread in Java is such an example:
// Alternative 1:
public class MyThread extends Thread {
// Abstract method to implement from Thread
// aka. "template method" (GoF design pattern)
public void run() {
// ...
}
}
// Usage:
MyThread t = new MyThread();
t.start();
The alternative is, in my meaning, verbose when you have to use it. Visual clutteer complexity goes up. This is because you need to create the Thread before you can actually use it.
// Alternative 2:
public class MyThread implements Runnable {
// Method to implement from Runnable:
public void run() {
// ...
}
}
// Usage:
MyThread m = new MyThread();
Thread t = new Thread(m);
t.start();
// …or if you have a curious perversion towards one-liners
Thread t = new Thread(new MyThread());
t.start();
Having my devil's advocate hat off I guess you could argue that the gain in the second implementation is dependency injection or seperation of concerns which helps designing testable classes. Depending on your definition of what an interface is (I've heard of at least three) an abstract class could be regarded as an interface.
Needed? No. You can write any program in C, for example, which doesn't have any sort of inheritance or objects. You could write it in assembly language, although it would be less portable. You could write it in a Turing machine and have it emulated. Somebody designed a computer language with exactly one instruction (something like subtract and branch if not zero), and you could write your program in that.
So, if you're going to ask if a given language feature is necessary (like inheritance, or objects, or recursion, or functions), the answer is no. (There are exceptions - you have to be able to loop and do things conditionally, although these need not be supported as explicit concepts in the language.)
Therefore, I find questions of this sort useless.
Questions like "When should we use inheritance" or "When shouldn't we" are a lot more useful.
a lot of the time I find myself choosing a base class over an interface just because I have some standard functionality. in C#, I can now use extension methods to achieve that, but it still doesn't achieve the same thing for several situations.
Is inheritance really needed? Depends what you mean by "really". You could go back to punch cards or flicking toggle switches in theory, but it's a terrible way to develop software.
In procedural languages, yes, class inheritance is a definite boon. It gives you a way to elegantly organise your code in certain circumstances. It should not be overused, as any other feature should not be overused.
For example, take the case of digiarnie in this thread. He/she uses interfaces for nearly everything, which is just as bad as (possibly worse than) using lots of inheritance.
Some of his points :
this helps with testing and improves readability
It doesn't do either thing. You never actually test an interface, you always test an object, that is, an instantiation of a class. And having to look at a completely different bit of code helps you understand the structure of a class? I don't think so.
Ditto for deep inheritance hierarchies though. You ideally want to look in one place only.
Using interfaces, I would get the same effect but I would mimic inheritance by using
'delegation'.
Delegation is a very good idea, and should often be used instead of inheritance (for example, the Strategy pattern is all about doing exactly this). But interfaces have zero to do with delegation, because you cannot specify any behaviour at all in an interface.
also makes refactoring a whole lot easier.
Early commitment to interfaces usually makes refactoring harder, not easier, because there are then more places to change. Overusing inheritance early is better (well, less bad) than overusing interfaces, as pulling out delegate classes is easier if the classes being modified do not implement any interfaces. And it's quite often from those delegates than you get useful interfaces.
So overuse of inheritance is a bad thing. Overuse of interfaces is a bad thing. And ideally, a class will neither inherit from anything (except maybe "object" or the language equivalent), nor implement any interfaces. But that doesn't mean either feature should be removed from a language.
If there is a framework class that does almost exactly what you want, but a particular function of its interface throws a NotSupported exception or for some other reason you only want to override one method to do something specific to your implementation, it's much easier to write a subclass and override that one method rather than write a brand new class and write pass-throughs for each of the other 27 methods in the class.
Similarly, What about Java, for example, where every object inherits from Object, and therefore automatically has implementations of equals, hashcode, etc. I don't have to re-implement them, and it "just works" when I want to use the object as a key in a hashtable. I don't have to write a default passthrough to a Hashtable.hashcode(Object o) method, which frankly seems like it's moving away from object orientation.
My initial thought was, You're crazy. But after thinking about it a while I kinda agree with you. I'm not saying remove Class Inheritance fully (abstract classes with partial implementation for example can be useful), but I have often inherited (pun intended) badly written OO code with multi level class inheritance that added nothing, other than bloat, to the code.
Note that inheritance means it is no longer possible to supply the base class functionality by dependency injection, in order to unit test a derived class in isolation of its parent.
So if you're deadly serious about dependency injection (which I'm not, but I do wonder whether I should be), you can't get much use out of inheritance anyway.
Here's a nice view at the topic:
IS-STRICTLY-EQUIVALENT-TO-A by Reg Braithwaite
I believe a better mechanism for code re-use which is sometimes achieved through inheritance are traits. Check this link (pdf) for a great discussion on this, including the distinction between traits and mixins, and why traits are favored.
There's some research that introduces traits into C# (pdf).
Perl has traits through Moose::Roles. Scala traits are like mixins, as in Ruby.
The question is, "Should inheritance (of non-interface types) be removed from programming languages?"
I say, "No", as it will break a hell of a lot of existing code.
That aside, should you use inheritance, other than inheritance of interfaces? I'm predominantly a C++ programmer and I follow a strict object model of multiple inheritance of interfaces followed by a chain of single inheritance of classes. The concrete classes are a "secret" of a component and it's friends, so what goes on there is nobodies business.
To help implement interfaces, I use template mixins. This allows the interface designer to provide snippets of code to help implement the interface for common scenarios. As a component developer I feel like I can go mixin shopping to get the reusable bits without being encumbered by how the interface designer thought I should build my class.
Having said that, the mixin paradigm is pretty much unique to C++. Without this, I expect that inheritance is very attractive to the pragmatic programmer.
I was confused when I first started to see anti-singleton commentary. I have used the singleton pattern in some recent projects, and it was working out beautifully. So much so, in fact, that I have used it many, many times.
Now, after running into some problems, reading this SO question, and especially this blog post, I understand the evil that I have brought into the world.
So: How do I go about removing singletons from existing code?
For example:
In a retail store management program, I used the MVC pattern. My Model objects describe the store, the user interface is the View, and I have a set of Controllers that act as liason between the two. Great. Except that I made the Store into a singleton (since the application only ever manages one store at a time), and I also made most of my Controller classes into singletons (one mainWindow, one menuBar, one productEditor...). Now, most of my Controller classes get access the other singletons like this:
Store managedStore = Store::getInstance();
managedStore.doSomething();
managedStore.doSomethingElse();
//etc.
Should I instead:
Create one instance of each object and pass references to every object that needs access to them?
Use globals?
Something else?
Globals would still be bad, but at least they wouldn't be pretending.
I see #1 quickly leading to horribly inflated constructor calls:
someVar = SomeControllerClass(managedStore, menuBar, editor, sasquatch, ...)
Has anyone else been through this yet? What is the OO way to give many individual classes acces to a common variable without it being a global or a singleton?
Dependency Injection is your friend.
Take a look at these posts on the excellent Google Testing Blog:
Singletons are pathologic liars (but you probably already understand this if you are asking this question)
A talk on Dependency Injection
Guide to Writing Testable Code
Hopefully someone has made a DI framework/container for the C++ world? Looks like Google has released a C++ Testing Framework and a C++ Mocking Framework, which might help you out.
It's not the Singleton-ness that is the problem. It's fine to have an object that there will only ever be one instance of. The problem is the global access. Your classes that use Store should receive a Store instance in the constructor (or have a Store property / data member that can be set) and they can all receive the same instance. Store can even keep logic within it to ensure that only one instance is ever created.
My way to avoid singletons derives from the idea that "application global" doesn't mean "VM global" (i.e. static). Therefore I introduce a ApplicationContext class which holds much former static singleton information that should be application global, like the configuration store. This context is passed into all structures. If you use any IOC container or service manager, you can use this to get access to the context.
There's nothing wrong with using a global or a singleton in your program. Don't let anyone get dogmatic on you about that kind of crap. Rules and patterns are nice rules of thumb. But in the end it's your project and you should make your own judgments about how to handle situations involving global data.
Unrestrained use of globals is bad news. But as long as you are diligent, they aren't going to kill your project. Some objects in a system deserve to be singleton. The standard input and outputs. Your log system. In a game, your graphics, sound, and input subsystems, as well as the database of game entities. In a GUI, your window and major panel components. Your configuration data, your plugin manager, your web server data. All these things are more or less inherently global to your application. I think your Store class would pass for it as well.
It's clear what the cost of using globals is. Any part of your application could be modifying it. Tracking down bugs is hard when every line of code is a suspect in the investigation.
But what about the cost of NOT using globals? Like everything else in programming, it's a trade off. If you avoid using globals, you end up having to pass those stateful objects as function parameters. Alternatively, you can pass them to a constructor and save them as a member variable. When you have multiple such objects, the situation worsens. You are now threading your state. In some cases, this isn't a problem. If you know only two or three functions need to handle that stateful Store object, it's the better solution.
But in practice, that's not always the case. If every part of your app touches your Store, you will be threading it to a dozen functions. On top of that, some of those functions may have complicated business logic. When you break that business logic up with helper functions, you have to -- thread your state some more! Say for instance you realize that a deeply nested function needs some configuration data from the Store object. Suddenly, you have to edit 3 or 4 function declarations to include that store parameter. Then you have to go back and add the store as an actual parameter to everywhere one of those functions is called. It may be that the only use a function has for a Store is to pass it to some subfunction that needs it.
Patterns are just rules of thumb. Do you always use your turn signals before making a lane change in your car? If you're the average person, you'll usually follow the rule, but if you are driving at 4am on an empty high way, who gives a crap, right? Sometimes it'll bite you in the butt, but that's a managed risk.
Regarding your inflated constructor call problem, you could introduce parameter classes or factory methods to leverage this problem for you.
A parameter class moves some of the parameter data to it's own class, e.g. like this:
var parameterClass1 = new MenuParameter(menuBar, editor);
var parameterClass2 = new StuffParameters(sasquatch, ...);
var ctrl = new MyControllerClass(managedStore, parameterClass1, parameterClass2);
It sort of just moves the problem elsewhere though. You might want to housekeep your constructor instead. Only keep parameters that are important when constructing/initiating the class in question and do the rest with getter/setter methods (or properties if you're doing .NET).
A factory method is a method that creates all instances you need of a class and have the benefit of encapsulating creation of the said objects. They are also quite easy to refactor towards from Singleton, because they're similar to getInstance methods that you see in Singleton patterns. Say we have the following non-threadsafe simple singleton example:
// The Rather Unfortunate Singleton Class
public class SingletonStore {
private static SingletonStore _singleton
= new MyUnfortunateSingleton();
private SingletonStore() {
// Do some privatised constructing in here...
}
public static SingletonStore getInstance() {
return _singleton;
}
// Some methods and stuff to be down here
}
// Usage:
// var singleInstanceOfStore = SingletonStore.getInstance();
It is easy to refactor this towards a factory method. The solution is to remove the static reference:
public class StoreWithFactory {
public StoreWithFactory() {
// If the constructor is private or public doesn't matter
// unless you do TDD, in which you need to have a public
// constructor to create the object so you can test it.
}
// The method returning an instance of Singleton is now a
// factory method.
public static StoreWithFactory getInstance() {
return new StoreWithFactory();
}
}
// Usage:
// var myStore = StoreWithFactory.getInstance();
Usage is still the same, but you're not bogged down with having a single instance. Naturally you would move this factory method to it's own class as the Store class shouldn't concern itself with creation of itself (and coincidentally follow the Single Responsibility Principle as an effect of moving the factory method out).
From here you have many choices, but I'll leave that as an exercise for yourself. It is easy to over-engineer (or overheat) on patterns here. My tip is to only apply a pattern when there is a need for it.
Okay, first of all, the "singletons are always evil" notion is wrong. You use a Singleton whenever you have a resource which won't or can't ever be duplicated. No problem.
That said, in your example, there's an obvious degree of freedom in the application: someone could come along and say "but I want two stores."
There are several solutions. The one that occurs first of all is to build a factory class; when you ask for a Store, it gives you one named with some universal name (eg, a URI.) Inside that store, you need to be sure that multiple copies don't step on one another, via critical regions or some method of ensuring atomicity of transactions.
Miško Hevery has a nice article series on testability, among other things the singleton, where he isn't only talking about the problems, but also how you might solve it (see 'Fixing the flaw').
I like to encourage the use of singletons where necessary while discouraging the use of the Singleton pattern. Note the difference in the case of the word. The singleton (lower case) is used wherever you only need one instance of something. It is created at the start of your program and is passed to the constructor of the classes that need it.
class Log
{
void logmessage(...)
{ // do some stuff
}
};
int main()
{
Log log;
// do some more stuff
}
class Database
{
Log &_log;
Database(Log &log) : _log(log) {}
void Open(...)
{
_log.logmessage(whatever);
}
};
Using a singleton gives all of the capabilities of the Singleton anti-pattern but it makes your code more easily extensible, and it makes it testable (in the sense of the word defined in the Google testing blog). For example, we may decide that we need the ability to log to a web-service at some times as well, using the singleton we can easily do that without significant changes to the code.
By comparison, the Singleton pattern is another name for a global variable. It is never used in production code.
Almost every Java book I read talks about using the interface as a way to share state and behaviour between objects that when first "constructed" did not seem to share a relationship.
However, whenever I see architects design an application, the first thing they do is start programming to an interface. How come? How do you know all the relationships between objects that will occur within that interface? If you already know those relationships, then why not just extend an abstract class?
Programming to an interface means respecting the "contract" created by using that interface. And so if your IPoweredByMotor interface has a start() method, future classes that implement the interface, be they MotorizedWheelChair, Automobile, or SmoothieMaker, in implementing the methods of that interface, add flexibility to your system, because one piece of code can start the motor of many different types of things, because all that one piece of code needs to know is that they respond to start(). It doesn't matter how they start, just that they must start.
Great question. I'll refer you to Josh Bloch in Effective Java, who writes (item 16) why to prefer the use of interfaces over abstract classes. By the way, if you haven't got this book, I highly recommend it! Here is a summary of what he says:
Existing classes can be easily retrofitted to implement a new interface. All you need to do is implement the interface and add the required methods. Existing classes cannot be retrofitted easily to extend a new abstract class.
Interfaces are ideal for defining mix-ins. A mix-in interface allows classes to declare additional, optional behavior (for example, Comparable). It allows the optional functionality to be mixed in with the primary functionality. Abstract classes cannot define mix-ins -- a class cannot extend more than one parent.
Interfaces allow for non-hierarchical frameworks. If you have a class that has the functionality of many interfaces, it can implement them all. Without interfaces, you would have to create a bloated class hierarchy with a class for every combination of attributes, resulting in combinatorial explosion.
Interfaces enable safe functionality enhancements. You can create wrapper classes using the Decorator pattern, a robust and flexible design. A wrapper class implements and contains the same interface, forwarding some functionality to existing methods, while adding specialized behavior to other methods. You can't do this with abstract methods - you must use inheritance instead, which is more fragile.
What about the advantage of abstract classes providing basic implementation? You can provide an abstract skeletal implementation class with each interface. This combines the virtues of both interfaces and abstract classes. Skeletal implementations provide implementation assistance without imposing the severe constraints that abstract classes force when they serve as type definitions. For example, the Collections Framework defines the type using interfaces, and provides a skeletal implementation for each one.
Programming to interfaces provides several benefits:
Required for GoF type patterns, such as the visitor pattern
Allows for alternate implementations. For example, multiple data access object implementations may exist for a single interface that abstracts the database engine in use (AccountDaoMySQL and AccountDaoOracle may both implement AccountDao)
A Class may implement multiple interfaces. Java does not allow multiple inheritance of concrete classes.
Abstracts implementation details. Interfaces may include only public API methods, hiding implementation details. Benefits include a cleanly documented public API and well documented contracts.
Used heavily by modern dependency injection frameworks, such as http://www.springframework.org/.
In Java, interfaces can be used to create dynamic proxies - http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Proxy.html. This can be used very effectively with frameworks such as Spring to perform Aspect Oriented Programming. Aspects can add very useful functionality to Classes without directly adding java code to those classes. Examples of this functionality include logging, auditing, performance monitoring, transaction demarcation, etc. http://static.springframework.org/spring/docs/2.5.x/reference/aop.html.
Mock implementations, unit testing - When dependent classes are implementations of interfaces, mock classes can be written that also implement those interfaces. The mock classes can be used to facilitate unit testing.
I think one of the reasons abstract classes have largely been abandoned by developers might be a misunderstanding.
When the Gang of Four wrote:
Program to an interface not an implementation.
there was no such thing as a java or C# interface. They were talking about the object-oriented interface concept, that every class has. Erich Gamma mentions it in this interview.
I think following all the rules and principles mechanically without thinking leads to a difficult to read, navigate, understand and maintain code-base. Remember: The simplest thing that could possibly work.
How come?
Because that's what all the books say. Like the GoF patterns, many people see it as universally good and don't ever think about whether or not it is really the right design.
How do you know all the relationships between objects that will occur within that interface?
You don't, and that's a problem.
If
you already know those relationships,
then why not just extend an abstract
class?
Reasons to not extend an abstract class:
You have radically different implementations and making a decent base class is too hard.
You need to burn your one and only base class for something else.
If neither apply, go ahead and use an abstract class. It will save you a lot of time.
Questions you didn't ask:
What are the down-sides of using an interface?
You cannot change them. Unlike an abstract class, an interface is set in stone. Once you have one in use, extending it will break code, period.
Do I really need either?
Most of the time, no. Think really hard before you build any object hierarchy. A big problem in languages like Java is that it makes it way too easy to create massive, complicated object hierarchies.
Consider the classic example LameDuck inherits from Duck. Sounds easy, doesn't it?
Well, that is until you need to indicate that the duck has been injured and is now lame. Or indicate that the lame duck has been healed and can walk again. Java does not allow you to change an objects type, so using sub-types to indicate lameness doesn't actually work.
Programming to an interface means respecting the "contract" created by
using that interface
This is the single most misunderstood thing about interfaces.
There is no way to enforce any such contract with interfaces. Interfaces, by definition, cannot specify any behaviour at all. Classes are where behaviour happens.
This mistaken belief is so widespread as to be considered the conventional wisdom by many people. It is, however, wrong.
So this statement in the OP
Almost every Java book I read talks about using the interface as a way
to share state and behavior between objects
is just not possible. Interfaces have neither state nor behaviour. They can define properties, that implementing classes must provide, but that's as close as they can get. You cannot share behaviour using interfaces.
You can make an assumption that people will implement an interface to provide the sort of behaviour implied by the name of its methods, but that's not anything like the same thing. And it places no restrictions at all on when such methods are called (eg that Start should be called before Stop).
This statement
Required for GoF type patterns, such as the visitor pattern
is also incorrect. The GoF book uses exactly zero interfaces, as they were not a feature of the languages used at the time. None of the patterns require interfaces, although some can use them. IMO, the Observer pattern is one in which interfaces can play a more elegant role (although the pattern is normally implemented using events nowadays). In the Visitor pattern it is almost always the case that a base Visitor class implementing default behaviour for each type of visited node is required, IME.
Personally, I think the answer to the question is threefold:
Interfaces are seen by many as a silver bullet (these people usually labour under the "contract" misapprehension, or think that interfaces magically decouple their code)
Java people are very focussed on using frameworks, many of which (rightly) require classes to implement their interfaces
Interfaces were the best way to do some things before generics and annotations (attributes in C#) were introduced.
Interfaces are a very useful language feature, but are much abused. Symptoms include:
An interface is only implemented by one class
A class implements multiple interfaces. Often touted as an advantage of interfaces, usually it means that the class in question is violating the principle of separation of concerns.
There is an inheritance hierarchy of interfaces (often mirrored by a hierarchy of classes). This is the situation you're trying to avoid by using interfaces in the first place. Too much inheritance is a bad thing, both for classes and interfaces.
All these things are code smells, IMO.
It's one way to promote loose coupling.
With low coupling, a change in one module will not require a change in the implementation of another module.
A good use of this concept is Abstract Factory pattern. In the Wikipedia example, GUIFactory interface produces Button interface. The concrete factory may be WinFactory (producing WinButton), or OSXFactory (producing OSXButton). Imagine if you are writing a GUI application and you have to go look around all instances of OldButton class and changing them to WinButton. Then next year, you need to add OSXButton version.
In my opinion, you see this so often because it is a very good practice that is often applied in the wrong situations.
There are many advantages to interfaces relative to abstract classes:
You can switch implementations w/o re-building code that depends on the interface. This is useful for: proxy classes, dependency injection, AOP, etc.
You can separate the API from the implementation in your code. This can be nice because it makes it obvious when you're changing code that will affect other modules.
It allows developers writing code that is dependent on your code to easily mock your API for testing purposes.
You gain the most advantage from interfaces when dealing with modules of code. However, there is no easy rule to determine where module boundaries should be. So this best practice is easy to over-use, especially when first designing some software.
I would assume (with #eed3s9n) that it's to promote loose coupling. Also, without interfaces unit testing becomes much more difficult, as you can't mock up your objects.
Why extends is evil. This article is pretty much a direct answer to the question asked. I can think of almost no case where you would actually need an abstract class, and plenty of situations where it is a bad idea. This does not mean that implementations using abstract classes are bad, but you will have to take care so you do not make the interface contract dependent on artifacts of some specific implementation (case in point: the Stack class in Java).
One more thing: it is not necessary, or good practice, to have interfaces everywhere. Typically, you should identify when you need an interface and when you do not. In an ideal world, the second case should be implemented as a final class most of the time.
There are some excellent answers here, but if you're looking for a concrete reason, look no further than Unit Testing.
Consider that you want to test a method in the business logic that retrieves the current tax rate for the region where a transaction occurrs. To do this, the business logic class has to talk to the database via a Repository:
interface IRepository<T> { T Get(string key); }
class TaxRateRepository : IRepository<TaxRate> {
protected internal TaxRateRepository() {}
public TaxRate Get(string key) {
// retrieve an TaxRate (obj) from database
return obj; }
}
Throughout the code, use the type IRepository instead of TaxRateRepository.
The repository has a non-public constructor to encourage users (developers) to use the factory to instantiate the repository:
public static class RepositoryFactory {
public RepositoryFactory() {
TaxRateRepository = new TaxRateRepository(); }
public static IRepository TaxRateRepository { get; protected set; }
public static void SetTaxRateRepository(IRepository rep) {
TaxRateRepository = rep; }
}
The factory is the only place where the TaxRateRepository class is referenced directly.
So you need some supporting classes for this example:
class TaxRate {
public string Region { get; protected set; }
decimal Rate { get; protected set; }
}
static class Business {
static decimal GetRate(string region) {
var taxRate = RepositoryFactory.TaxRateRepository.Get(region);
return taxRate.Rate; }
}
And there is also another other implementation of IRepository - the mock up:
class MockTaxRateRepository : IRepository<TaxRate> {
public TaxRate ReturnValue { get; set; }
public bool GetWasCalled { get; protected set; }
public string KeyParamValue { get; protected set; }
public TaxRate Get(string key) {
GetWasCalled = true;
KeyParamValue = key;
return ReturnValue; }
}
Because the live code (Business Class) uses a Factory to get the Repository, in the unit test you plug in the MockRepository for the TaxRateRepository. Once the substitution is made, you can hard code the return value and make the database unneccessary.
class MyUnitTestFixture {
var rep = new MockTaxRateRepository();
[FixtureSetup]
void ConfigureFixture() {
RepositoryFactory.SetTaxRateRepository(rep); }
[Test]
void Test() {
var region = "NY.NY.Manhattan";
var rate = 8.5m;
rep.ReturnValue = new TaxRate { Rate = rate };
var r = Business.GetRate(region);
Assert.IsNotNull(r);
Assert.IsTrue(rep.GetWasCalled);
Assert.AreEqual(region, rep.KeyParamValue);
Assert.AreEqual(r.Rate, rate); }
}
Remember, you want to test the business logic method only, not the repository, database, connection string, etc... There are different tests for each of those. By doing it this way, you can completely isolate the code that you are testing.
A side benefit is that you can also run the unit test without a database connection, which makes it faster, more portable (think multi-developer team in remote locations).
Another side benefit is that you can use the Test-Driven Development (TDD) process for the implementation phase of development. I don't strictly use TDD but a mix of TDD and old-school coding.
In one sense, I think your question boils down to simply, "why use interfaces and not abstract classes?" Technically, you can achieve loose coupling with both -- the underlying implementation is still not exposed to the calling code, and you can use Abstract Factory pattern to return an underlying implementation (interface implementation vs. abstract class extension) to increase the flexibility of your design. In fact, you could argue that abstract classes give you slightly more, since they allow you to both require implementations to satisfy your code ("you MUST implement start()") and provide default implementations ("I have a standard paint() you can override if you want to") -- with interfaces, implementations must be provided, which over time can lead to brittle inheritance problems through interface changes.
Fundamentally, though, I use interfaces mainly due to Java's single inheritance restriction. If my implementation MUST inherit from an abstract class to be used by calling code, that means I lose the flexibility to inherit from something else even though that may make more sense (e.g. for code reuse or object hierarchy).
One reason is that interfaces allow for growth and extensibility. Say, for example, that you have a method that takes an object as a parameter,
public void drink(coffee someDrink)
{
}
Now let's say you want to use the exact same method, but pass a hotTea object. Well, you can't. You just hard-coded that above method to only use coffee objects. Maybe that's good, maybe that's bad. The downside of the above is that it strictly locks you in with one type of object when you'd like to pass all sorts of related objects.
By using an interface, say IHotDrink,
interface IHotDrink { }
and rewrting your above method to use the interface instead of the object,
public void drink(IHotDrink someDrink)
{
}
Now you can pass all objects that implement the IHotDrink interface. Sure, you can write the exact same method that does the exact same thing with a different object parameter, but why? You're suddenly maintaining bloated code.
Its all about designing before coding.
If you dont know all the relationships between two objects after you have specified the interface then you have done a poor job of defining the interface -- which is relatively easy to fix.
If you had dived straight into coding and realised half way through you are missing something its a lot harder to fix.
You could see this from a perl/python/ruby perspective :
when you pass an object as a parameter to a method you don't pass it's type , you just know that it must respond to some methods
I think considering java interfaces as an analogy to that would best explain this . You don't really pass a type , you just pass something that responds to a method ( a trait , if you will ).
I think the main reason to use interfaces in Java is the limitation to single inheritance. In many cases this lead to unnecessary complication and code duplication. Take a look at Traits in Scala: http://www.scala-lang.org/node/126 Traits are a special kind of abstract classes, but a class can extend many of them.
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 5 years ago.
Improve this question
One of the biggest advantages of object-oriented programming is encapsulation, and one of the "truths" we've (or, at least, I've) been taught is that members should always be made private and made available via accessor and mutator methods, thus ensuring the ability to verify and validate the changes.
I'm curious, though, how important this really is in practice. In particular, if you've got a more complicated member (such as a collection), it can be very tempting to just make it public rather than make a bunch of methods to get the collection's keys, add/remove items from the collection, etc.
Do you follow the rule in general? Does your answer change depending on whether it's code written for yourself vs. to be used by others? Are there more subtle reasons I'm missing for this obfuscation?
It depends. This is one of those issues that must be decided pragmatically.
Suppose I had a class for representing a point. I could have getters and setters for the X and Y coordinates, or I could just make them both public and allow free read/write access to the data. In my opinion, this is OK because the class is acting like a glorified struct - a data collection with maybe some useful functions attached.
However, there are plenty of circumstances where you do not want to provide full access to your internal data and rely on the methods provided by the class to interact with the object. An example would be an HTTP request and response. In this case it's a bad idea to allow anybody to send anything over the wire - it must be processed and formatted by the class methods. In this case, the class is conceived of as an actual object and not a simple data store.
It really comes down to whether or not verbs (methods) drive the structure or if the data does.
As someone having to maintain several-year-old code worked on by many people in the past, it's very clear to me that if a member attribute is made public, it is eventually abused. I've even heard people disagreeing with the idea of accessors and mutators, as that's still not really living up to the purpose of encapsulation, which is "hiding the inner workings of a class". It's obviously a controversial topic, but my opinion would be "make every member variable private, think primarily about what the class has got to do (methods) rather than how you're going to let people change internal variables".
Yes, encapsulation matters. Exposing the underlying implementation does (at least) two things wrong:
Mixes up responsibilities. Callers shouldn't need or want to understand the underlying implementation. They should just want the class to do its job. By exposing the underlying implementation, you're class isn't doing its job. Instead, it's just pushing the responsibility onto the caller.
Ties you to the underlying implementation. Once you expose the underlying implementation, you're tied to it. If you tell callers, e.g., there's a collection underneath, you cannot easily swap the collection for a new implementation.
These (and other) problems apply regardless of whether you give direct access to the underlying implementation or just duplicate all the underlying methods. You should be exposing the necessary implementation, and nothing more. Keeping the implementation private makes the overall system more maintainable.
I prefer to keep members private as long as possible and only access em via getters, even from within the very same class. I also try to avoid setters as a first draft to promote value style objects as long as it is possible. Working with dependency injection a lot you often have setters but no getters, as clients should be able to configure the object but (others) not get to know what's acutally configured as this is an implementation detail.
Regards,
Ollie
I tend to follow the rule pretty strictly, even when it's just my own code. I really like Properties in C# for that reason. It makes it really easy to control what values it's given, but you can still use them as variables. Or make the set private and the get public, etc.
Basically, information hiding is about code clarity. It's designed to make it easier for someone else to extend your code, and prevent them from accidentally creating bugs when they work with the internal data of your classes. It's based on the principle that nobody ever reads comments, especially ones with instructions in them.
Example: I'm writing code that updates a variable, and I need to make absolutely sure that the Gui changes to reflect the change, the easiest way is to add an accessor method (aka a "Setter"), which is called instead of updating data is updated.
If I make that data public, and something changes the variable without going through the Setter method (and this happens every swear-word time), then someone will need to spend an hour debugging to find out why the updates aren't being displayed. The same applies, to a lesser extent, to "Getting" data. I could put a comment in the header file, but odds are that no-one will read it till something goes terribly, terribly wrong. Enforcing it with private means that the mistake can't be made, because it'll show up as an easily located compile-time bug, rather than a run-time bug.
From experience, the only times you'd want to make a member variable public, and leave out Getter and Setter methods, is if you want to make it absolutely clear that changing it will have no side effects; especially if the data structure is simple, like a class that simply holds two variables as a pair.
This should be a fairly rare occurence, as normally you'd want side effects, and if the data structure you're creating is so simple that you don't (e.g a pairing), there will already be a more efficiently written one available in a Standard Library.
With that said, for most small programs that are one-use no-extension, like the ones you get at university, it's more "good practice" than anything, because you'll remember over the course of writing them, and then you'll hand them in and never touch the code again. Also, if you're writing a data structure as a way of finding out about how they store data rather than as release code, then there's a good argument that Getters and Setters will not help, and will get in the way of the learning experience.
It's only when you get to the workplace or a large project, where the probability is that your code will be called to by objects and structures written by different people, that it becomes vital to make these "reminders" strong. Whether or not it's a single man project is surprisingly irrelevant, for the simple reason that "you six weeks from now" is as different person as a co-worker. And "me six weeks ago" often turns out to be lazy.
A final point is that some people are pretty zealous about information hiding, and will get annoyed if your data is unnecessarily public. It's best to humour them.
C# Properties 'simulate' public fields. Looks pretty cool and the syntax really speeds up creating those get/set methods
Keep in mind the semantics of invoking methods on an object. A method invocation is a very high level abstraction that can be implemented my the compiler or the run time system in a variety of different ways.
If the object who's method you are invoking exists in the same process/ memory map then a method could well be optimized by a compiler or VM to directly access the data member. On the other hand if the object lives on another node in a distributed system then there is no way that you can directly access it's internal data members, but you can still invoke its methods my sending it a message.
By coding to interfaces you can write code that doesn't care where the target object exists or how it's methods are invoked or even if it's written in the same language.
In your example of an object that implements all the methods of a collection, then surely that object actually is a collection. so maybe this would be a case where inheritance would be better than encapsulation.
It's all about controlling what people can do with what you give them. The more controlling you are the more assumptions you can make.
Also, theorectically you can change the underlying implementation or something, but since for the most part it's:
private Foo foo;
public Foo getFoo() {}
public void setFoo(Foo foo) {}
It's a little hard to justify.
Encapsulation is important when at least one of these holds:
Anyone but you is going to use your class (or they'll break your invariants because they don't read the documentation).
Anyone who doesn't read the documentation is going to use your class (or they'll break your carefully documented invariants). Note that this category includes you-two-years-from-now.
At some point in the future someone is going to inherit from your class (because maybe an extra action needs to be taken when the value of a field changes, so there has to be a setter).
If it is just for me, and used in few places, and I'm not going to inherit from it, and changing fields will not invalidate any invariants that the class assumes, only then I will occasionally make a field public.
My tendency is to try to make everything private if possible. This keeps object boundaries as clearly defined as possible and keeps the objects as decoupled as possible. I like this because when I have to rewrite an object that I botched the first (second, fifth?) time, it keeps the damage contained to a smaller number of objects.
If you couple the objects tightly enough, it may be more straightforward just to combine them into one object. If you relax the coupling constraints enough you're back to structured programming.
It may be that if you find that a bunch of your objects are just accessor functions, you should rethink your object divisions. If you're not doing any actions on that data it may belong as a part of another object.
Of course, if you're writing a something like a library you want as clear and sharp of an interface as possible so others can program against it.
Fit the tool to the job... recently I saw some code like this in my current codebase:
private static class SomeSmallDataStructure {
public int someField;
public String someOtherField;
}
And then this class was used internally for easily passing around multiple data values. It doesn't always make sense, but if you have just DATA, with no methods, and you aren't exposing it to clients, I find it a quite useful pattern.
The most recent use I had of this was a JSP page where I had a table of data being displayed, defined at the top declaratively. So, initially it was in multiple arrays, one array per data field... this ended in the code being rather difficult to wade through with fields not being next to eachother in definition that would be displayed together... so I created a simple class like above which would pull it together... the result was REALLY readable code, a lot more so than before.
Moral... sometimes you should consider "accepted bad" alternatives if they may make the code simpler and easier to read, as long as you think it through and consider the consequences... don't blindly accept EVERYTHING you hear.
That said... public getters and setters is pretty much equivalent to public fields... at least essentially (there is a tad more flexibility, but it is still a bad pattern to apply to EVERY field you have).
Even the java standard libraries has some cases of public fields.
When I make objects meaningful they are easier to use and easier to maintain.
For example: Person.Hand.Grab(howquick, howmuch);
The trick is not to think of members as simple values but objects in themselves.
I would argue that this question does mix-up the concept of encapsulation with 'information hiding'
(this is not a critic, since it does seem to match a common interpretation of the notion of 'encapsulation')
However for me, 'encapsulation' is either:
the process of regrouping several items into a container
the container itself regrouping the items
Suppose you are designing a tax payer system. For each tax payer, you could encapsulate the notion of child into
a list of children representing the children
a map of to takes into account children from different parents
an object Children (not Child) which would provide the needed information (like total number of children)
Here you have three different kinds of encapsulations, 2 represented by low-level container (list or map), one represented by an object.
By making those decisions, you do not
make that encapsulation public or protected or private: that choice of 'information hiding' is still to be made
make a complete abstraction (you need to refine the attributes of object Children and you may decide to create an object Child, which would keep only the relevant informations from the point of view of a tax payer system)
Abstraction is the process of choosing which attributes of the object are relevant to your system, and which must be completely ignored.
So my point is:
That question may been titled:
Private vs. Public members in practice (how important is information hiding?)
Just my 2 cents, though. I perfectly respect that one may consider encapsulation as a process including 'information hiding' decision.
However, I always try to differentiate 'abstraction' - 'encapsulation' - 'information hiding or visibility'.
#VonC
You might find the International Organisation for Standardization's, "Reference Model of Open Distributed Processing," an interesting read. It defines: "Encapsulation: the property that the information contained in an object is accessible only through interactions at the interfaces supported by the object."
I tried to make a case for information hiding's being a critical part of this definition here:
http://www.edmundkirwan.com/encap/s2.html
Regards,
Ed.
I find lots of getters and setters to be a code smell that the structure of the program is not designed well. You should look at the code that uses those getters and setters, and look for functionality that really should be part of the class. In most cases, the fields of a class should be private implementation details and only the methods of that class may manipulate them.
Having both getters and setters is equal to the field being public (when the getters and setters are trivial/generated automatically). Sometimes it might be better to just declare the fields public, so that the code will be more simple, unless you need polymorphism or a framework requires get/set methods (and you can't change the framework).
But there are also cases where having getters and setters is a good pattern. One example:
When I create the GUI of an application, I try to keep the behaviour of the GUI in one class (FooModel) so that it can be unit tested easily, and have the visualization of the GUI in another class (FooView) which can be tested only manually. The view and model are joined with simple glue code; when the user changes the value of field x, the view calls setX(String) on the model, which in turn may raise an event that some other part of the model has changed, and the view will get the updated values from the model with getters.
In one project, there is a GUI model which has 15 getters and setters, of which only 3 get methods are trivial (such that the IDE could generate them). All the others contain some functionality or non-trivial expressions, such as the following:
public boolean isEmployeeStatusEnabled() {
return pinCodeValidation.equals(PinCodeValidation.VALID);
}
public EmployeeStatus getEmployeeStatus() {
Employee employee;
if (isEmployeeStatusEnabled()
&& (employee = getSelectedEmployee()) != null) {
return employee.getStatus();
}
return null;
}
public void setEmployeeStatus(EmployeeStatus status) {
getSelectedEmployee().changeStatusTo(status, getPinCode());
fireComponentStateChanged();
}
In practice I always follow only one rule, the "no size fits all" rule.
Encapsulation and its importance is a product of your project. What object will be accessing your interface, how will they be using it, will it matter if they have unneeded access rights to members? those questions and the likes of them you need to ask yourself when working on each project implementation.
I base my decision on the Code's depth within a module.
If I'm writting code that is internal to a module, and does not interface with the outside world I don't encapsulate things with private as much because it affects my programmer performance (how fast I can write and rewrite my code).
But for the objects that server as the module's interface with user code, then I adhere to strict privacy patterns.
Certainly it makes a difference whether your writing internal code or code to be used by someone else (or even by yourself, but as a contained unit.) Any code that is going to be used externally should have a well defined/documented interface that you'll want to change as little as possible.
For internal code, depending on the difficulty, you may find it's less work to do things the simple way now, and pay a little penalty later. Of course Murphy's law will ensure that the short term gain will be erased many times over in having to make wide-ranging changes later on where you needed to change a class' internals that you failed to encapsulate.
Specifically to your example of using a collection that you would return, it seems possible that the implementation of such a collection might change (unlike simpler member variables) making the utility of encapsulation higher.
That being said, I kinda like Python's way of dealing with it. Member variables are public by default. If you want to hide them or add validation there are techniques provided, but those are considered the special cases.
I follow the rules on this almost all the time. There are four scenarios for me - basically, the rule itself and several exceptions (all Java-influenced):
Usable by anything outside of the current class, accessed via getters/setters
Internal-to-class usage typically preceded by 'this' to make it clear that it's not a method parameter
Something meant to stay extremely small, like a transport object - basically a straight shot of attributes; all public
Needed to be non-private for extension of some sort
There's a practical concern here that isn't being addressed by most of the existing answers. Encapsulation and the exposure of clean, safe interfaces to outside code is always great, but it's much more important when the code you're writing is intended to be consumed by a spatially- and/or temporally-large "user" base. What I mean is that if you plan on somebody (even you) maintaining the code well into the future, or if you're writing a module that will interface with code from more than a handful of other developers, you need to think much more carefully than if you're writing code that's either one-off or wholly written by you.
Honestly, I know what wretched software engineering practice this is, but I'll oftentimes make everything public at first, which makes things marginally faster to remember and type, then add encapsulation as it makes sense. Refactoring tools in most popular IDEs these days makes which approach you use (adding encapsulation vs. taking it away) much less relevant than it used to be.