Objects in my open-source toolkit are all based on the class AbstractObject. I want to add a function into AbstractObject which will create and return object of the exact same class.
This is different from cloning, because the property values are not copied. I thought about calling it duplicate but it is confusing when working with ActiveRecord classes (as duplicate would be used to duplicate record, not object).
form2 = form1->createObjectWithSameClass()
Please suggest a single-word (preferably) name for this. I appreciate your time!
Based on the information here, this sounds like you want another plain object of the same type as a variable in scope, and that type is the only context needed when creating the object.
In that case, this sounds like a valid case for a Factory instead of a method hanging off of an instance. You could do, perhaps:
myFactory.create(form1)
or
myFactory.create(form1.getClass())
EDIT: this is not a direct answer to your question, but because you are concerned with naming, and therefore I assume with clarity of code, one of the big benefits of a pattern is clarity (everyone knows what a Factory is, so they won't be confused by whatever name you end up choosing).
Related
The documentation for objc_duplicateClass reads simply
Used by Foundation's Key-Value Observing. Do not call this function yourself.
with no elaboration or explanation. I read the source, but didn't see anything in it that that gave me any indication for why you shouldn't call it, except a few theories; except that load and initialize don't get called for classes created by objc_duplicateClass?
It seems like you could produce pretty much the same effect by calling objc_allocateClassPair with no extra bytes for additional ivars, and then immediately registering it. So what's special about objc_duplicateClass? Or, to rephrase the question, if, hypothetically, I wanted to build KVO, or something very similar, on top of the objc runtime, would it be safe to to use objc_duplicateClass?
objc_duplicateClass does pretty much what it says on the tin: it produces a new class which is a copy of the class that you give it. This includes copying the methods that the old class had, all of its metadata bits, and even its metaclass.
You couldn't recreate this behavior with objc_allocateClassPair because objc_allocateClassPair registers a new metaclass for the class you create, among other things like initializing the class — it is meant to create a new class. objc_duplicateClass creates a copy; the "new" class is not initialized any further and does not get a new metaclass because the original one already did.
As for why objc_duplicateClass is documented the way that it is: to discourage its use. objc_duplicateClass has some rare use cases, and will almost never be what you want. If you find a need for it, use it, but keep in mind that there are subtleties to the implementation you may not be aware of.
Even I marked the Q as opinion based, I'd like to try an answer:
A. Such a statement usually marks a function (or whatever) to be obsolete and is planned to be removed in future.
B. Indeed, there is no reason for this function. I do not agree with your statement, that registering a new class with zero extra bytes would do the job. because maybe there are extra bytes and you have to copy all instance var descriptions and methods manually.
However, I had to deal with such situations as KVO in the past. I have never used objc_duplicateClass(), because t is much easier and akin of cleaner to create a subclass and then make the instance a member of that subclass. You can do isa-swizzling for that calling object_setClass(id object, Class cls).
Think of a situation, obviously it is yours, that another technology wants to do something like KVO, too. Duplicating a class using objc_duplicateClass() takes not part on future dynamic changes of the original class. Maybe a method is added to it. A duplication would not add this method, too.
So objc_duplicateClass() is not useful and a bad approach.
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
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Public Data members vs Getters, Setters
In what cases should public fields be used, instead of properties or getter and setter methods (where there is no support for properties)? Where exactly is their use recommended, and why, or, if it is not, why are they still allowed as a language feature? After all, they break the Object-Oriented principle of encapsulation where getters and setters are allowed and encouraged.
If you have a constant that needs to be public, you might as well make it a public field instead of creating a getter property for it.
Apart from that, I don't see a need, as far as good OOP principles are concerned.
They are there and allowed because sometimes you need the flexibility.
That's hard to tell, but in my opinion public fields are only valid when using structs.
struct Simple
{
public int Position;
public bool Exists;
public double LastValue;
};
But different people have different thoughts about:
http://kristofverbiest.blogspot.com/2007/02/public-fields-and-properties-are-not.html
http://blogs.msdn.com/b/ericgu/archive/2007/02/01/properties-vs-public-fields-redux.aspx
http://www.markhneedham.com/blog/2009/02/04/c-public-fields-vs-automatic-properties/
If your compiler does not optimize getter and setter invocations, the access to your properties might be more expensive than reading and writing fields (call stack). That might be relevant if you perform many, many invocations.
But, to be honest, I know no language where this is true. At least in both .NET and Java this is optimized well.
From a design point of view I know no case where using fields is recommended...
Cheers
Matthias
Let's first look at the question why we need accessors (getters/setters)? You need them to be able to override the behaviour when assigning a new value/reading a value. You might want to add caching or return a calculated value instead of a property.
Your question can now be formed as do I always want this behaviour? I can think of cases where this is not useful at all: structures (what were structs in C). Passing a parameter object or a class wrapping multiple values to be inserted into a Collection are cases where one actually does not need accessors: The object is merely a container for variables.
There is one single reason(*) why to use get instead of public field: lazy evaluation. I.e. the value you want may be stored in a database, or may be long to compute, and don't want your program to initialize it at startup, but only when needed.
There is one single reason(*) why to use set instead of public field: other fields modifications. I.e. you change the value of other fields when you the value of the target field changes.
Forcing to use get and set on every field is in contradiction with the YAGNI principle.
If you want to expose the value of a field from an object, then expose it! It is completely pointless to create an object with four independent fields and mandating that all of them uses get/set or properties access.
*: Other reasons such as possible data type change are pointless. In fact, wherever you use a = o.get_value() instead of a = o.value, if you change the type returned by get_value() you have to change at every use, just as if you would have changed the type of value.
The main reason is nothing to do with OOP encapsulation (though people often say it is), and everything to do with versioning.
Indeed from the OOP position one could argue that fields are better than "blind" properties, as a lack of encapsulation is clearer than something that pretends to encapsulation and then blows it away. If encapsulation is important, then it should be good to see when it isn't there.
A property called Foo will not be treated the same from the outside as a public field called Foo. In some languages this is explicit (the language doesn't directly support properties, so you've got a getFoo and a setFoo) and in some it is implicit (C# and VB.NET directly support properties, but they are not binary-compatible with fields and code compiled to use a field will break if it's changed to a property, and vice-versa).
If your Foo just does a "blind" set and write of an underlying field, then there is currently no encapsulation advantage to this over exposing the field.
However, if there is a later requirement to take advantage of encapsulation to prevent invalid values (you should always prevent invalid values, but maybe you didn't realise some where invalid when you first wrote the class, or maybe "valid" has changed with a scope change), to wrap memoised evaluation, to trigger other changes in the object, to trigger an on-change event, to prevent expensive needless equivalent sets, and so on, then you can't make that change without breaking running code.
If the class is internal to the component in question, this isn't a concern, and I'd say use fields if fields read sensibly under the general YAGNI principle. However, YAGNI doesn't play quite so well across component boundaries (if I did need my component to work today, I certainly am probably going to need that it works tomorrow after you've changed your component that mine depends on), so it can make sense to pre-emptively use properties.
I'd like to know whether this approach is correct or if their are better ways of doing this.
I have what is basically a Person class which has a number of other classes as variables, each of the custom classes is instantiated by passing the Person ID and then that class retrieves the data it needs using that ID. I expose the variable classes via Properties.
Currently I am instancing the variable classes when I create an instance of the Person class, and the large number of these mean that the time it takes to instantiate the Person class is growing. My idea was to move the instancing of the variable classes to the Propertie declaration and then using an If statement here to instantiate it if it hasn't yet been done.
As I said above is this approach correct or is their a better way of doing this?
Thanks
There is a term for the technique you're describing; it's called "lazy-loaded properties". It should definitely help spread out your load on this object away from a "front-loaded" constructor.
On a different note, it sounds like what you're describing is going to result in a terribly tightly-coupled object model (if you don't have one already) which is likely to have a negative impact on this code's maintainability. However, I don't think that a serious dissertation on that topic and how to work otherwise is really within the scope of this question.
Just to clarify: If you mean instantiating the classes on the getter of their accessor then yes this is a fine approach - referred to as Lazy Loading.
Eg
public Property ChildClass as PersonChildClass
Get
if _childClass is Nothing
_childClass = new PersonChildClass(_personId)
End If
return _childClass
End Get
End Property
Let's say you have a Person object and it has a method on it, promote(), that transforms it into a Captain object. What do you call this type of method/interaction?
It also feels like an inversion of:
myCaptain = new Captain(myPerson);
Edit: Thanks to all the replies. The reason I'm coming across this pattern (in Perl, but relevant anywhere) is purely for convenience. Without knowing any implementation deals, you could say the Captain class "has a" Person (I realize this may not be the best example, but be assured it isn't a subclass).
Implementation I assumed:
// this definition only matches example A
Person.promote() {
return new Captain(this)
}
personable = new Person;
// A. this is what i'm actually coding
myCaptain = personable.promote();
// B. this is what my original post was implying
personable.promote(); // is magically now a captain?
So, literally, it's just a convenience method for the construction of a Captain. I was merely wondering if this pattern has been seen in the wild and if it had a name. And I guess yeah, it doesn't really change the class so much as it returns a different one. But it theoretically could, since I don't really care about the original.
Ken++, I like how you point out a use case. Sometimes it really would be awesome to change something in place, in say, a memory sensitive environment.
A method of an object shouldn't change its class. You should either have a member which returns a new instance:
myCaptain = myPerson->ToCaptain();
Or use a constructor, as in your example:
myCaptain = new Captain(myPerson);
I would call it a conversion, or even a cast, depending on how you use the object. If you have a value object:
Person person;
You can use the constructor method to implicitly cast:
Captain captain = person;
(This is assuming C++.)
A simpler solution might be making rank a property of person. I don't know your data structure or requirements, but if you need to something that is trying to break the basics of a language its likely that there is a better way to do it.
You might want to consider the "State Pattern", also sometimes called the "Objects for States" pattern. It is defined in the book Design Patterns, but you could easily find a lot about it on Google.
A characteristic of the pattern is that "the object will appear to change its class."
Here are some links:
Objects for States
Pattern: State
Everybody seems to be assuming a C++/Java-like object system, possibly because of the syntax used in the question, but it is quite possible to change the class of an instance at runtime in other languages.
Lisp's CLOS allows changing the class of an instance at any time, and it's a well-defined and efficient transformation. (The terminology and structure is slightly different: methods don't "belong" to classes in CLOS.)
I've never heard a name for this specific type of transformation, though. The function which does this is simply called change-class.
Richard Gabriel seems to call it the "change-class protocol", after Kiczales' AMOP, which formalized as "protocols" many of the internals of CLOS for metaprogramming.
People wonder why you'd want to do this; I see two big advantages over simply creating a new instance:
faster: changing class can be as simple as updating a pointer, and updating any slots that differ; if the classes are very similar, this can be done with no new memory allocations
simpler: if a dozen places already have a reference to the old object, creating a new instance won't change what they point to; if you need to update each one yourself, that could add a lot of complexity for what should be a simple operation (2 words, in Lisp)
That's not to say it's always the right answer, but it's nice to have the ability to do this when you want it. "Change an instance's class" and "make a new instance that's similar to that one" are very different operations, and I like being able to say exactly what I mean.
The first interesting part would be to know: why do you want/need an object changes its class at runtime?
There are various options:
You want it to respond differently to some methods for a given state of the application.
You might want it to have new functionality that the original class don't have.
Others...
Statically typed languages such as Java and C# don't allow this to happen, because the type of the object should be know at compile time.
Other programming languages such as Python and Ruby may allow this ( I don't know for sure, but I know they can add methods at runtime )
For the first option, the answer given by Charlie Flowers is correct, using the state patterns would allow a class behave differently but the object will have the same interface.
For the second option, you would need to change the object type anyway and assign it to a new reference with the extra functionality. So you will need to create another distinct object and you'll end up with two different objects.