I am a newbie in Objective C and I was wondering what is
the best way to define an immutable class in Objective-C (like NSString for example).
I want to know what are the basic rules one has to follow to make a class immutable.
I think that :
setters shouldn't be provided
if properties are used, they should be readonly
to "disable" Key Value Coding , accessInstanceVariablesDirectly must be override and return NO
Did I forget something ?
Thanks
The first and foremost thing you should do is to include usage comments in your .h file that explain that this is an immutable class, along with the class's purpose and general usage guidance. Far too often people go to great lengths to try to "enforce" with the compiler what could be achieved by just informing the caller.
You should certainly not provide public setters or readwrite properties if you intend the class to be immutable (but of course you should provide private setters so that you can use accessors within the class; you should always avoid, even internally, messing with ivars directly except in a few places). I guess you could add your accessInstanceVariablesDirectly override if you saw this as a likely error on the part of the caller.
But the key to understanding Objective-C is to understand and embrace the fact that the caller is not the enemy. The called code does not need to be "protected" from the caller. The caller needs to be protected from likely error. Everyone is on the same side here; caller and called want the program to work.
The caller is the customer and should be treated as such. The customer is not always right, but the customer is always the customer. Sometimes that means protecting the customer from himself if there is an easy mistake he might make. NSAssert() is particularly useful for that. And providing public setters to an immutable class is almost tricking the caller into making a mistake, so that would be bad for everyone.
In any case, you shouldn't make your class overly complex to try to enforce immutability. The caller can almost (*) always violate encapsulation by accessing the struct directly (object->ivar). The caller would be foolish to do so, but you would be even more foolish to try to prevent it. Note the immutability, hide your setters and mark your properties readonly, and in almost all cases you should be fine.
(*) Yes, it's possible to even more hide your data by nesting a private struct/object as an ivar, but then the caller can still modify the data with pointer arithmetic so it's still not "enforced." Always ask yourself what problem you're really trying to solve.
I believe they way I'd accomplish this is to have the header file contain only the publicly needed information. The rest would go in to the source file to limit possible override exposure.
Since Objective-C apparently has no definitive way of defining a class as final (sealed, etc), everything you'd be able to do isn't really all encompassing.
I've long ago came to the conclusion that you really can't use Objective-C like you'd use Java, C++ or C#. Objective-C is simply too different. In fact I believe there are drastic paradigm differences such as static vs. dynamic method dispatch/calls.
The reason I mention this is because perhaps no class in Objective-C is truly final. Perhaps this is by language design and not something you should try to get around. If you do, you'd ultimately needlessly complicate your code.
Related
When writing getter/setters in classes, should the setters be private methods?
It might seem a bit redundant to have to write another method to set a variable but it seems like that might allow for a more maintainable code structure.
Setter is a method that is suppose to allow modifying internal state of an object without exposing that object directly. We can later include validation or other logic inside setter.
If your setter is private, you are missing the point. It's like having a door in your house that is always closed and doesn't even allow opening. Also inside the class you can simply access the field directly, why would you use a setter there?
Of course the real question is: should we have setters at all? The typical class these days holds a bunch of fields, auto-generated getters/setters and no logic. This is hardly a class. It's just a structure with awkward way of accessing elements. But that's not what you are asking for.
In General, I don't recommend "private" access for any member, maybe "protected". Usually, you or other programmer may require it in a descendant class.
Long Boring Descriptive Answer
Now, for accessors ("getters & setters"), its also depends on the syntax and implementation of properties on the programming language.
For Example, C++, or Java, I consider not have "real properties", and accesors, maybe required to have the same scope as the properties. (Unless using a template for properties).
C# & Delphi (Lazarus) have properties implemented, but, I don't like the way C# declare the accesors.
There are cases, where you may want a property not to be public, maybe "protected" or "package protected", and its accesors, the same access than the property.
I just work in some code in Object Pascal. Most properties where "public", and its accesors "protected", but, want to migrate that code to c++ or Java, so, I make the accesors "public", as well.
Quick Short Answer
Same access as the property, but, depends on the syntax of properties.
They should be public, if the intent is to allow them to be manipulated from an external object. That is the point of POJO implementation. (http://en.wikipedia.org/wiki/Plain_Old_Java_Object)
If you're looking to implement some other pattern, perhaps looking at the docs on Java Access Modifiers should be your first stop (http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
Usually you want setters/getters to be public, because that's what they are for: giving access to data, you don't want to give others direct access to because you don't want them to mess with your implementation dependent details - that's what encapsulation is about.
However there might be some cases where you want to restrict access to your data just to instances of the same class, but you still want to retain some control over the access to the data for whatever reason (bookkeeping, locking etc.) - in that case having private (or protected) setters/getters makes sense (from both code reuse and safety POV). However, you can't rely on the compiler to catch you doing something wrong then.
In terms of good Objective-C coding practices, if I create a function that has no state, is it better to write it as a static method of some class or as a C function?
For example, I have a special filepath retrieval method that checks the Caches directory before proceeding to the main NSBundle. I currently have it as a static method under an otherwise empty Utils class. Should this be a C function instead?
The reason I've chosen to use a static method (for now) is that a) it's consistent with Objective-C syntax, and b) the class helps to categorize the method. However, I feel like I'm cheating a little, since I could easily fill up my Util class with these stateless static methods and end up with an ugly "shell class", whose sole purpose would be to hold them.
What convention do you use? Is one "better" than the other, by some objective metric? Thank you!
If you can think of an existing class of which this might make a good method, you can inject your method into it by making an Objective-C category. This keeps your two reasons for using a static method while not polluting the class space with an extra class.
For example:
#interface NSString (MyStringCategories)
- (NSString*) myCoolMethod;
#end
// [StringCategories.m]
#import "StringCategories.h"
#implementation NSString (MyStringCategories)
- (NSString*) myCoolMethod {
// do cool stuff here
return whateverYouLike;
}
#end
Now you can send myCoolMethod to any string. Cool!
In your particular case, it sounds like a method on NSBundle might be an appropriate architecture. And don't forget, it can be a class method, so you don't need to instantiate anything in order to call your method.
This is quite a difficult question to answer because for a lot of people the answer will depend on what their personal preferences and tastes are. I personally think that if you have a function that is a function, i.e. it has nothing to do with an object, it has no internal state etc. pp. please let it be a function and do not try to wrap everything you possibly can into an object just because you are using an OO language and you can.
In order to keep my answer short let me refer to a (imo) quite good book:
http://www.gotw.ca/publications/c++cs.htm
I know that this is for C++, but there are quite a few insights that can be shared with other languages (esp. Objective-C and Objective-C++) especially from the part called "Class Design and Inheritance". There you will find an item titeled "Prefer writing nonmember nonfriend functions".
Bottom line: "Nonmember nonfriend functions improve encapsulation by minimizing dependencies[...] They also break apart monolithic classes[...] [and] improve genericity[...]".
I think there is quite some truth in that item.
If there's no class to clearly bind it to, then I use a function. I also use functions for these utility bits because they can be stripped if not used or referenced. In that regard, it's also helpful to use a function because a link error is better than a runtime error (in the even the .m was accidentally omitted from the build, or if was referenced from another externally updated method). One problem with ObjC symbols is that they do not get stripped, so they naturally carry a high amount of dependency -- all the objc methods and classes, and required category methods must exist in the final binary. That's not an issue with really small programs or libraries, but it quickly gains weight with medium/large systems and libraries.
Everything does not need to be declared in an #interface - especially with larger systems where all those declarations will really turn your interdependencies into spaghetti. Compared to methods, functions are faster, smaller, may be optimized better by the compiler or during linking, and may be stripped if not referenced.
If you need polymorphism, it just belongs in a class for organization or convenience, then a class or instance method is often a better choice.
I also minimize declaring category methods for the same reasons. When you're using functions, you can easily write a wrapper method where you need it and get the best of both worlds.
I'm a little unclear as to how far to take the idea in making all members within a class private and make public methods to handle mutations. Primitive types are not the issue, it's encapsulated object that I am unclear about. The benefit of making object members private is the ability to hide methods that do not apply to the context of class being built. The downside is that you have to provide public methods to pass parameters to the underlying object (more methods, more work). On the otherside, if you want to have all methods and properties exposed for the underlying object, couldn't you just make the object public? What are the dangers in having objects exposed this way?
For example, I would find it useful to have everything from a vector, or Array List, exposed. The only downside I can think of is that public members could potentially assigned a type that its not via implicit casting (or something to that affect). Would a volitile designation reduce the potential for problems?
Just a side note: I understand that true enapsulation implies that members are private.
What are the dangers in having objects exposed this way?
Changing the type of those objects would require changing the interface to the class. With private objects + public getters/setters, you'd only have to modify the code in the getters and setters, assuming you want to keep the things being returned the same.
Note that this is why properties are useful in languages such as Python, which technically doesn't have private class members, only obscured ones at most.
The problem with making instance variables public is that you can never change your mind later, and make them private, without breaking existing code that relies on directly public access to those instance vars. Some examples:
You decide to later make your class thread-safe by synchronizing all access to instance vars, or maybe by using a ThreadLocal to create a new copy of the value for each thread. Can't do it if any thread can directly access the variables.
Using your example of a vector or array list - at some point, you realize that there is a security flaw in your code because those classes are mutable, so somebody else can replace the contents of the list. If this were only available via an accessor method, you could easily solve the problem by making an immutable copy of the list upon request, but you can't do that with a public variable.
You realize later that one of your instance vars is redundant and can be derived based on other variables. Once again, easy if you're using accessors, impossible with public variables.
I think that it boils down to a practical point - if you know that you're the only one who will be using this code, and it pains you to write accessors (every IDE will do it for you automatically), and you don't mind changing your own code later if you decide to break the API, then go for it. But if other people will be using your class, or if you would like to make it easier to refactor later for your own use, stick with accessors.
Object oriented design is just a guideline. Think about it from the perspective of the person who will be using your class. Balance OOD with making it intuitive and easy to use.
You could run into issues depending on the language you are using and how it treats return statements or assignment operators. In some cases it may give you a reference, or values in other cases.
For example, say you have a PrimeCalculator class that figures out prime numbers, then you have another class that does something with those prime numbers.
public PrimeCalculator calculatorObject = new PrimeCalculator();
Vector<int> primeNumbers = calculatorObject.PrimeNumbersVector;
/* do something complicated here */
primeNumbers.clear(); // free up some memory
When you use this stuff later, possibly in another class, you don't want the overhead of calculating the numbers again so you use the same calculatorObject.
Vector<int> primes = calculatorObject.PrimeNumbersVector;
int tenthPrime = primes.elementAt(9);
It may not exactly be clear at this point whether primes and primeNumbers reference the same Vector. If they do, trying to get the tenth prime from primes would throw an error.
You can do it this way if you're careful and understand what exactly is happening in your situation, but you have a smaller margin of error using functions to return a value rather than assigning the variable directly.
Well you can check the post :
first this
then this
This should solve your confusion . It solved mine ! Thanks to Nicol Bolas.
Also read the comments below the accepted answer (also notice the link given in the second last comment by me ( in the first post) )
Also visit the wikipedia post
I recently read that getters/setters are evil and I have to say it makes sense, yet when I started learning OOP one of the first things I learned was "Encapsulate your fields" so I learned to create class give it some fields, create getters, setters for them and create constructor where I initialize these fields. And every time some other class needs to manipulate this object (or for instance display it) I pass it the object and it manipulate it using getters/setters. I can see problems with this approach.
But how to do it right? For instance displaying/rendering object that is "data" class - let's say Person, that has name and date of birth. Should the class have method for displaying the object where some Renderer would be passed as an argument? Wouldn't that violate principle that class should have only one purpose (in this case store state) so it should not care about presentation of this object.
Can you suggest some good resources where best practices in OOP design are presented? I'm planning to start a project in my spare time and I want it to be my learning project in correct OOP design..
Allen Holub made a big splash with "Why getter and setter methods are evil" back in 2003.
It's great that you've found and read the article. I admire anybody who's learning and thinking critically about what they're doing.
But take Mr. Holub with a grain of salt.
This is one view that got a lot of attention for its extreme position and the use of the word "evil", but it hasn't set the world on fire or been generally accepted as dogma.
Look at C#: they actually added syntactic sugar to the language to make get/set operations easier to write. Either this confirms someone's view of Microsoft as an evil empire or contradicts Mr. Holub's statement.
The fact is that people write objects so that clients can manipulate state. It doesn't mean that every object written that way is wrong, evil, or unworkable.
The extreme view is not practical.
"Encapsulate your fields" so I learned to create class give it some fields, create getters, setters
Python folks do not do this. Yet, they are still doing OO programming. Clearly, fussy getters and setters aren't essential.
They're common, because of limitations in C++ and Java. But they don't seem to be essential.
Python folks use properties sometimes to create a getter and setter functions that look like a simple attribute.
The point is that "Encapsulation" is a Design strategy. It has little or nothing to do with the implementation. You can have all public attributes, and still a nicely encapsulated design.
Also note that many people worry about "someone else" who "violates" the design by directly accessing attributes. I suppose this could happen, but then the class would stop working correctly.
In C++ (and Java) where you cannot see the source, it can be hard to understand the interface, so you need lots of hints. private methods, explicit getters and setters, etc.
In Python, where you can see all the source, it's trivial to understand the interface. We don't need to provide so many hints. As we say "Use the source, Luke" and "We're all adults here." We're all able to see the source, we don't need to be fussy about piling on getters and setters to provide yet more hints as to how the API works.
For instance displaying/rendering object that is "data" class - let's say Person, that has name and date of birth. Should the class have method for displaying the object where some Renderer would be passed as an argument?
Good idea.
Wouldn't that violate principle that class should have only one purpose (in this case store state) so it should not care about presentation of this object.
That's why the Render object is separate. Your design is quite nice.
No reason why a Person object can't call a general-purpose renderer and still have a narrow set of responsibilities. After all the Person object is responsible for the attributes, and passing those attributes to a Renderer is well within it's responsibilities.
If it's truly a problem (and it can be in some applications), you can introduce Helper classes. So the PersonRenderer class does Rendering of Person data. That way a change to Person also requires changes to PersonRenderer -- and nothing else. This is the Data Access Object design pattern.
Some folks will make the Render an internal class, contained within Person, so it's Person.PersonRenderer to enforce some more serious containment.
If you have getters and setters, you don't have encapsulation. And they are not necessary. Consider the std::string class. This has quite a complicated internal representation, yet has no getters or setters, and only one element of the representation is (probably) exposed simply by returning its value (i.e. size()). That's the kind of thing you should be aiming for.
The basic concept of why they are considered to be evil is, that a class/object should export function and not state. The state of an object is made of its members. Getters and Setters let external users read/modify the state of an object without using any function.
Hence the idea, that except for DataTransferObjects for which you might have Getters and a constructor for setting the state, the members of an objects should only be modified by calling a functionality of an object.
Why do you think getters are evil? See a post with answers proving the opposite:
Purpose of private members in a class
IMHO it contains a lot of what can rightfully be called "OOP best practices".
Update: OK, reading the article you are referring to, I understand more clearly what the issue is. And it's a whole different story from what the provocative title of the article suggests. I haven't yet read the full article, but AFAIU the basic point is that one should not unnecessarily publish class fields via mindlessly added (or generated) getters and setters. And with this point I fully agree.
By designing carefully and focusing on what you must do rather than how
you'll do it, you eliminate the vast majority of getter/setter methods in
your program. Don't ask for the information you need to do the work;
ask the object that has the information to do the work for you.
So far so good. However, I don't agree that providing a getter like this
int getSomeField();
inherently compromises your class design. Well it does, if you haven't designed your class interface well. Then, of course, it might happen that you realize too late that the field should be a long rather than an int, and changing it would break 1000 places in client code. IMHO in such case the designer is to blame, not the poor getter.
In some languages, like C++, there's the concept of friend. Using this concept you can make implementation details of a class visible to only a subset of other classes (or even functions). When you use Get/Set indiscriminately you give everyone access to everything.
When used sparingly friend is an excellent way of increasing encapsulation.
Assume you have many entity classes in your designs, and suppose they have a base class like Data. Adding different getter and setter methods for concrete implementations will pollute the client code that uses these entities like lots of dynamic_casts, to call required getter and setter methods.
Therefore, getter and setter methods may remain where they are, but you should protected client code. My recommendation would be to apply Visitor pattern or data collector for these cases.
In other words, ask yourself why do I need these accessor methods, how do I manipulate these entities? And then apply these manipulations in Visitor classes to keep client code clean, also extend the functionality of entity classes without polluting their code.
In the following paper concerning endotesting you'll find a pattern to avoid getters (in some circumstances) using what the author calls 'smart handlers'. It has a lot in common with how Holub approaches avoiding some getters.
http://www.mockobjects.com/files/endotesting.pdf
Anything that is public is part of the API of the class. Changing these parts may break other stuff, relying on that. A public field, that is not only connected with an API, but with internal representation, can be risky. Example: You save data in a field as an array. This array is public, so the data can be changed from other classes. Later you decide to switch to a generic List. Code that use this field as an array is broken.
I'm learning Objective-C, and have a C/C++ background.
In object-oriented C++, you always need to declare your method before you define (implement) it, even if it is declared in the parent class.
In procedural-style C, IIRC, you can get away with just defining a function so long as it is only called from something else in the same compilational unit (ie. the same file) that came later on in the file (well, provided you don't declare it elsewhere with "extern").
Now, in Objective-C, it appears that you only need to declare selectors in the header file if they are going to be used by something external, and that you can make up selectors in your .m file just fine, and call them within the .m file. Also, it appears that delegate methods or inherited methods are never (re)defined.
Am I on the right track? When do you need to define a selector in Objective-C?
For Objective-C methods, the general practice is to put methods you wish to expose in the #interface section of the header file so other code can include only the .h and know how to interact with your code. Order-based "lazy declaration" works just like functions in C — you don't have to declare a method prototype unless you have a dependency that can't be resolved by ordering, but you can add method prototypes inside the #implementation if needed.
So yes, you're on the right track. Don't repeat the method prototype for inherited methods — the compiler finds it in the parent's header file. Delegate methods may be defined as prototypes in a category (tacked onto a class) and implemented as desired, but the delegate does not need to provide a method prototype, since it is already defined. (It still can if it wants to for clarity, etc.)
Since you're just learning Objective-C, the rest of this answer is much more detail than you asked for. You have been warned. ;-)
When you statically type a variable (e.g. MyClass* instead of id) the compiler will warn you when you try to call a method that a class doesn't advertise that it implements, whether it does or not. If you dynamically type the variable, the compiler won't stop you from calling whatever you like, and you'll only get runtime errors if you call something that doesn't exist. As far as the language is concerned, you can call any method that a class implements without errors at runtime — there is no way to restrict who can call a method.
Personally, I think this is actually a good thing. We get so used to encapsulation and protecting our code from other code that we sometimes treat the caller as a devious miscreant rather than a trustworthy coworker or customer. I find it's quite pleasant to code with a mindset of "you do your job and I do mine" where everyone respects boundaries and takes care of their own thing. You might say that the "attitude" of Objective-C is one of community trust, rather than of strict enforcement. For example, I'm happy to help anyone who comes to my desk, but would get really annoyed if someone messed with my stuff or moved things around without asking. Well-designed code doesn't have to be paranoid or sociopathic, it just has to work well together. :-)
That said, there are many approaches for structuring your interfaces, depending on the level of granularity you want/need in exposing interfaces to users. Any methods you declare in the public header are essentially fair game for anyone to use. Hiding method declarations is a bit like locking your car or house — it probably won't keep everyone out, but (1) it "keeps honest people honest" by not tempting them with something they shouldn't be messing with, and (2) anyone who does get in will certainly know they weren't supposed to, and can't really complain of negative consequences.
Below are some conventions I use for file naming, and what goes in each file — starting from a .m file at the bottom, each file includes the one above it. (Using a strict chain of includes will prevent things like duplicate symbol warnings.) Some of these levels only apply to larger reusable components, such as Cocoa frameworks. Adapt them according to your needs, and use whatever names suit you.
MyClass.h — Public API (Application Programming Interface)
MyClass_Private.h — Company-internal SPI (System Programming Interface)
MyClass_Internal.h — Project-internal IPI (Internal Programming Interface)
MyClass.m — Implementation, generally of all API/SPI/IPI declarations
MyClass_Foo.m — Additional implementation, such as for categories
API is for everyone to use, and is publicly supported (usually in Foo.framework/Headers). SPI exposes additional functionality for internal clients of your code, but with the understanding that support may be limited and the interface is subject to change (usually in Foo.framework/PrivateHeaders). IPI consists of implementation-specific details that should never be used outside the project itself, and these headers are not included in the framework at all. Anyone who chooses to use SPI and IPI calls does so at their own risk, and usually to their detriment when changes break their code. :-)
Declaring the methods in the header file will only stop compiler warnings. Objective-C is a dynamic language, so you can call a method (send a message) to an object whether or not that method is declared externally.
Also, if you define a method in the .m file above any code that calls it (lazy declaration) then that won't generate any warnings. However the same thing applies, you can send a message to an object without it being declared.
Of course - this means that there are no private methods in Objective-C. Any method that a class implements can be called.
Personal preference. If it's a public method (i.e one used externally). declare it in the .h and define in the .m. If you want to limit it's visibility, or at least indicate that it is a private method, use categories/class extensions in the .m file. Although lots of example code uses the lazy declaration method.
Objective-C treats functions as "messages" and as such, you can send a "message" to any object - even one that doesn't explicitly state in its interface that it can accept. As a result, there are no such things as private members in Obj-C.
This can be very powerful, but is a source of confusion for new Obj-C programmers - especially those coming from C++, Java or C#. Here are the basic rules of thumb:
You should define all public methods in your #interface so that consumers know what messages you expect to handle.
You should define #private methods in your #interface to avoid compiler messages and avoid having to order the methods in your #implementation.
You should use protocols when implementing a particular convention of methods for your class.
Much of this is personal preference, however it helps to avoid annoying compiler warnings and keeps your code organized. and easy to understand.