Use of getter-setter within class - oop

Should one use under any circumstances getters-setters of a class within the class?

Getters setters are generally used from outside class from inside directly access the fields.
The main advantage/purpose is encapsulation of getter setters,
If your getters setters has some logical code then use it.
for example :
public void setValue(int val){
if(val > 100)
this.val = 0;
else
this.val = val;
}
Also see
why-use-getters-and-setters
More on getters and setters

Yes, getters and setters are useful. Because PHP doesn't support type hinting for simple types like int or string, you cannot force a value to be of the right type.
By using a setter, you always have the possibility to check the value that is set. When a value set to an int property isn't an int, you can choose to typecast it, or raise an error, instead of just accepting the wrong value.
That will make debugging and maintaining your application a lot easier. So it's a good idea to use getters and setters, even if they do not contain much logic other than these checks.

#GolezTrol
There is no PHP badge on topic and you are wrong. What you are describing has nothing to do with setters. You can force type on parameter (in PHP) by using any method not only a setter.
You can write:
setX( X $x ){ ...}
setY( Y $y ){ ...}
or just:
iAmMethodNotASetter( X $x, Y $y){
//20lines of code here end then:
$this->x = $x;
$this->y = $y;
}
Like you see I didn't need setters to enforce type in object properties.
And throwing error in setter after checking variable type is bad idea anyway. It is common error of programmers who transitioned from the language statically typed to dynamically type language.
Setters and geters are CONVENTION and they don't enforce anything!
Today we usually use them for creation of Plain Old Java Objects. (POJO - in php word POPO) So it is just a convetion (standard) for creation of object that can by use between libraries or projects.
You can combine setters with type checking or whatever but it dosn't make them somthing more than they are.
About Encapsulation:
#org.life.java - Jigar Joshi
"The main advantage/purpose is
encapsulation of getter setters, "
#Peter Alexander
"You're supposed to use the getters
and setter almost everywhere,
including inside "the class. If you
don't, then you are potentially
breaking encapsulation" "Getters and
setters are encapsulation"
Wrong, wrong, wrong. Encapsulation has nothing to do with getters and setters and it is very common mistake. I know there is many articles repeated it over and over all upside down...
Getters and setters don't help encapsulation even worse, they may break encapsulation. They do so when you use them to get some data from object instead of asking object to do something for you with its own data.
Encapsulation == object is taking full responsibility for its data and dosn't give it's row data. And getter on private property is nothig more than making that property public in complicated fashion == braking encapsulation.
Chceck paragraph encapsulation: http://en.wikipedia.org/wiki/C%2B%2B or http://en.wikipedia.org/wiki/Encapsulation_%28computer_science%29
Not even one word about setters or getters...

You're supposed to use the getters and setter almost everywhere, including inside the class. If you don't, then you are potentially breaking encapsulation, and even worse, you could invalidate your invariants.
As a simple example in C++:
class BankAccount
{
public:
void withdraw(int amount)
{
m_balance -= amount;
m_withdrawals++;
}
void transfer(BankAcount& other, int amount)
{
m_balance -= amount;
other.m_balance += amount;
}
private:
int m_balance;
int m_withdrawals;
};
See the bug? transfer withdraws money, but it doesn't increment m_withdrawals. This could have been avoided if it simply called withdraw rather than manually decrementing the balance.
The same applies to getters and setters. For example, its quite common to have getters that lazily initialise their values. If another member function tries to access the uninitialised member directly then you're going to get a null pointer dereference.
Essentially, you should always try to use the getters and setters whenever they provide the functionality they want. The more low level things you do, the more low level bugs you are going to have. There's no point writing getters and setters if you aren't going to use them.

Related

Automatically running a selector on instance creation

In Objective-C, is there any way to run a specific selector automatically every time an object is instantiated? (I know about +initialize but I need an instance method).
Specifically, I am writing a custom string class (that inherits from my own root class with a similar interface to NSObject) and I am trying to make it 'play nicely' with Objective-C constant strings. To do this, I have the following class definition (as required by the runtime):
// 1) Required Layout
#interface MYConstantString : MYObject {
//Class isa; inherited from MYObject
char *c_string;
unsigned int length;
}
Now, I want to implement my string class by using a pointer to a C-struct inside the class (this "C object" is already well implemented so I basically just want to wrap it in an Objective-C class). Ideally therefore, my Objective-C class would look like this:
// 2) Desired Laout
#interface MYConstantString : MYObject {
// Class isa;
StringObject *string;
}
And then the class and instance methods would just wrap C function calls using that StringObject.
So because I can't have the desired ivar layout (2), I wish to hack around the required ivar layout (1) to work for me. For example:
- (void)fixup {
// Pseudocode
temp = copystring(c_string);
c_string = (void *)StringObjectNewWithString(temp); // Fudge pointer
length = ... // I can do something else with this.
}
So, to return to the question, is there a way to call -fixup automatically, rather than having to do the following every time I make write an Objective-C constant string?
MYConstantString *str = #"Constant string";
[str fixup];
I know this is an obscene hack, and Objective-C constant string interoperability isn't totally crucial for what I need, but it would be nice to be able to use the #"" syntax and make the code more 'naturally' Objective-C.
I'm guessing you left out an important fact: you're using -fconstant-string-class=MYConstantString when building to have the compiler use your class for constant string objects (#"...").
Given that, then, no. There are two significant problems. First, "instance creation" for constant strings happens at compile time, not run time. The reason that there's a required layout is that the compiler does nothing but lay out the string's data in a data section with a reference to the appropriate class object where the isa pointer goes. It doesn't invoke any custom code. It is not necessarily even aware of such custom code at compile time. A given translation unit may not include the constant string class. The reference to that is resolved at link time.
Second, the constant string instance is almost certainly laid out in a read-only data section. There's a good chance that even calling your -fixup method manually as in your question would encounter an access violation because you'd be modifying read-only memory.
You should consider using a class cluster. Make MYConstantString one concrete subclass of an abstract base class. Make it conform to the required layout and just use the character pointer and length ivars as they are. If it would be convenient to translate to StringObject at various points, do that at those points. Implement other, separate concrete subclasses to use StringObject internally, if desired.
MYConstantString *str = #"Constant string";
That can't work because #"..." is an NSString, and it's not only a problem of layout but of instance sizes. If you want 0-copy or anything like that, what you have to do is have something like:
MYConstantString *str = [MyConstantString stringWithNSString:#"Constant string"];
and let -stringWithNSString: recognize when the passed string is a constant one (I'm pretty sure the concrete class of constant strings is easy to recognize, and probably hasn't changed ever for backward compatibility reasons) and then hack it around to grab the pointer to the bytes and similar things.

Objective-C: Working with static variables

Given the code below, the spaceship (only ever one in the program) checks to see if it can pay for a new part, and 'if (so)', builds it. When the payFor: message is sent, should the iVars be dealt with like below, or should the each transaction be a method like +(void)deduct: (ShipObject *) cost;, or should I use struct and use structure arithmetic?
# implementation Spaceship
+(void) payFor: (ShipObject) *shipObject
{
totalEnergy -= [shipObject energy];
totalCredits -= [shipObject credits];
totalSamples -= [shipObject samples];
}
+(void) buildShipObject: (ShipObject) *shipObject
{
if ([self canBuild: shipObject]) {
[self payFor: shipObject];
...
}
Thanks for any insights!
First, since the methods are class methods, not instance methods, I assume that variables not ivars, but static variables of some sort.
If payments with some, not all, forms of payment are to be allowed (say, only with energy and samples, but not credits) then you should use three different methods. Otherwise, your payFor method is very idiomatic to Objective C. Using C struct should be reserved for the rare situations where Objective C classes no longer provide adequate performance.
Consider making the spaceship a singleton, and use ivars: this may become handy if you decide to introduce more ships in the game, or do something that's easier done with objects (e.g. externalization of object's state).

Property access, style or substance?

There are three different syntax styles for accessing properties of an object:
myProp = value;
self.myProp = value;
[self setMyProp: value];
Are these purely style choices or is there difference in substance?
self.myProp = value;
and
[self setMyProp: value];
are style choices, as they are using accessors to set values. That is, self.myProp essentially is the same as calling [self setMyProp] or [self myProp]. It will implement whatever mechanism you define in the #property tag (retaining, releasing as needed, etc).
However,
myProp = value;
is substantially different as it is simply an assignment. No consideration for releasing myProp's original pointer, retaining the new value, etc.
The first is an direct assignment to the iVar myProp.
The second and third are the same.
You should prefer the second or third, because when you use #synthesize the setter does the memory management for you.
myProp = value;
This is a direct assignment to a C variable. It's not a property access at all.
self.myProp = value;
This is syntactic sugar for:
[self setMyProp: value];
What does that mean? It means that the former is translated by the compiler into the latter before emitting the code for it. That is the only meaning of dot notation. As long as the class declares method myProp and setMyProp: dot notation will work. myProp does not need to be a property in the formal sense (i.e. declared with #property). It also does not need to be synthesized. There does not need to be a single instance variable to back it. As long as the two methods exist at run time (or the getter if you never assign to the property), you can use dot notation. It's orthogonal to Objective-C properties.
So the answer is that, yes, for your second two examples, it is purely a matter of style. Personally, I hate dot notation. It's an unnecessary pollution of the syntax of the language (by which I mean we now have two ways of expressing the sending of messages, one of which looks identical to a completely different language feature). /rant
Your examples #2 and #3 compile identically, but #1 has an important difference -- it does not call the setter. This makes it useful (required) inside the setter or else you will create an infinite loop.
For example, this setter creates an infinite loop:
- (void)setMyProp:(int)value
{
self.myProp = value;
}
The same is possible in the getter.

Java-enum style classes in Objective-C?

I am new to Obj-C so forgive me if this is a stupid question:
How do I implement some in the style of Javas enums? Or to be more precise:
I want a class with some known properties which are fix at compile time and unique per instance. Additionally I only want one instance type.
Let me give an example in Java:
public enum MessageTypes {
DEFAULT("white", "standard", 1),
EXPRESS("red", "expressMessage", 2),
BORADCAST("green", "broadcast", 3);
String color; String tagName; int dbId;
MessageTypes(String color, String tagName, int dbId) {
// you get the idea
}
//some methonds like getEnumByTagName
}
How would you do something like this in Objective-C? Am I missing something? Is this a bad pattern at all?
Thanks in advance!
EDIT: I am sorry, if I did not made myself clear. I know, that obj-c enums are not what I am looking for (as they are only marginally more than a typedef to an int).
I would like to create a set of (kind-of-singleton, immutable) instances of a specific class. The singleton pattern in Apples Dev-Docs is of no use as I want multiple distinct instances of a class each with individual values in their properties.
The goal of that is to have multiple Message types (about 20) that can be assigned to a Message as a property. Each of my Message types has a (fix and predefined) color, attribute-value (in an XML-representation) and a numerical ID.
In Java, I would use an enum as in my code sample. But how do I create different MessageTypes and associate them with their properties in Obj-C?
Creating 20 Sublcasses of MessageType (each with a singleton-instance holding the properties) seems like a lot of work for such a simple task and total overkill.
My current approach is to create a class with an NSArray holding the different instances. Up on first access of a method like +(id)messageTypeForId:NSInteger id_ the NSArray is prepopulated. But this feels totally clumsy and not at all elegant...
Is there a more satisfying approach?
There is not much in the way of a "more satisfying approach".
The normal Cocoa pattern would be to create methods like:
+ (MessageTypes*) sharedDefaultMessageType;
+ (MessageTypes*) sharedExpressMessageType;
+ (MessageTypes*) sharedBroadcastMessageType;
etc
and then implement them something like:
+ (MessageTypes*) sharedDefaultMessageType
{
static MessageTypes* thisMessageType = nil;
if ( !thisMessageType ) {
thisMessageType = [[MessageTypes alloc] initWithColor:#"white" tagName:#"standard" dbId:1];
}
return thisMessageType;
}
Alternatively, storing the shared MessageType* in an NSMutableArray or NSMutableDictionary or precalculating them as you are doing are all equally valid approraches.
Note that the above "template" method could be generated via a macro such that you could write in the .m file:
CREATEMESSAGETYPE( Default, #"white", #"standard", 1 )
CREATEMESSAGETYPE( Express, #"red", #"expressMessage", 2 )
CREATEMESSAGETYPE( Broadcast, #"green", #"broadcast", 3 )
which might be "more satisfying" or more ugly, depending on your point of view.
I think I'd just use a standard C enum:
typedef enum { MT_WHITE, MT_RED, MT_GREEN } MessageType;
Then you just use it as you would any other data type:
#interface Blah {}
-(void) setMessageType:(MessageType)newMessageType;
#end
Enums are not objects in C, and thus not in Objective-C either. They're just user-defined scalars that have a limited set of named values that they can take. You can give an object properties that are enum types, which I think is closest to what you're looking for.
If there's something specific you need to accomplish with this functionality, you might want to edit your post to indicate what that is.
I had the same question more or less but find all the above solutions clumsy stylistically.
In particular when simply using a C enum property on an object you lose the singleton semantics of Java enums. The biggest freedom I have found in the use of Java enums is that the instances of an enum are really singleton subclasses, and so participate in method polymorphism. Even more powerful than enums with unique attributes is enums with polymorphic behaviour.
Given that this is the key feature I am after would an Objective-C class cluster with singleton private subclasses be an approach with the desired behaviour, despite being a bit over the top in implementation cost and complexity?

Null object pattern in Objective-C

In Java, it is very easy to code the following design:
public abstract class Pizza {
public static final Pizza.NULL = new Pizza() {
/* "null" implementations */
}
/* actual/abstract implmentations */
}
What is the preferred method to attain the same efficient scenario in Objective-C? I have been unable to find any documentation on the subject, and I have tried a couple different scenarios with static const, #define etc. but none of them seem to work out as well as the Java method above.
I would like to avoid writing a concrete NullPizza class that has a static method to obtain the singleton instance, as it seems more 'proper' for it to be some final property/field of the highest-level interface. (Pizza, in this case.)
Edit: While I understand how the NULL pattern specifically would be handled due to Obj-C's unique method of handling method calls to 'nil', what about other static common instances, such as Response.YES and Response.NO? (See comments for discussion.)
There is no need for this type of pattern in Objective-C because it is not considered a runtime error to message a nil instance of a class. If the method has a defined return type, there are defined returns from messaging a nil object (e.g., methods that return an integer return 0 when messaging a nil object).
There are two things which can help here. The first is nil, the Objective-C equivalent of the Java NULL pointer - it can actually receive messages and respond to them. It will always return nil if the return value is an object, and 0 if the return value is some primitive type. Therefore if the Null behaviour of your object is "do nothing" you can easily just use nil as the Null value.
The other thing which is helpful is for when you need to store a placeholder or null value in a container object - these usually throw exceptions if you attempt to add nil as a value. Instead you can use the singleton +[NSNull null], which does nothing except act as a "this space intentionally left blank" object.
With these two weapons at your disposal there should be no reason to write a null instance of a custom class :-)
For your Response.YES and Response.NO, I assume you have instances that you do want to change, rather than just making all Response properties read-only.
A common pattern in Cocoa is to have both immutable and mutable versions of a class (NSArray versus NSMutableArray). For your response example, it would make sense to have an immutable Response class that has the static YES and NO methods, and a MutableResponse subclass that exposes setters for those times where you do want objects to change them. Does this cover your second example?
I don't think there is an easy way to provide this implementation. You're asking for something that is a language feature of Java to be implemented in Objective-C - you can do it but you have to write the code that is in the Java runtime yourself - there is nothing to stop you doing this but it's not something the language has built in.
It's a bit like asking "How do I show a Windows style 'one menu per window" UI in Cocoa' - you can do it but it's not provided for free from the framework. Or, "how can I easily implement Objective-C's nil pointer handling in Java?"
If you really want to see this type of functionality I think you should follow the NSArray/NSMutableArray design pattern. Declare a superclass that can handle all of your special cases:
#interface NullPizza : NSObject
{
}
- (BOOL)areYouANullPizza;
#end
and then subclass with your real Pizza and include a newNullPizza class method (which is just syntax sugar):
#interface Pizza : NullPizza
{
}
+ (Pizza*)Null;
#end
#implementation Pizza
+ (Pizza*)newNullPizza
{
return [[NullPizza]alloc init]; // Singleton code left as an exercise.
}
- (BOOL)areYouANullPizza;
{
return NO;
}
#end
Note that if you wanted to implement a +(Pizza*)NULL method on Pizza you should autorelease the new NullPizza you create.
Disclaimer, I typed this code straight into SO. I'd be surprised if it compiles but you get the idea.