Generic Usenet Account said:
A lot has been said in this newsgroup regarding the "evil" set/get
accessor methods. Arthur Riel, (of Vanguard Training), in his class,
"Heuristis for O-O Analysis & Design", says that there is almost never
an excuse for accessor methods.
Accessor methods can become neccessary when you have several properties of a class which are really different views/transformations of the same underlying property. An example already given was polar vs. cartesian coordinates.
Here's another:
class P{
public:
// directory
std::string GetDirectory();
void PutDirectory(const std::string& newDir);
// filename = basename.extension
std::string GetFileName();
void PutFileName(const std::string& newFileName);
// full path
std::string GetFullPath();
void PutFullPath(const std::string& newPath);
// now add BaseName and Extension.
};
// example:
// this/is/the/directory/basename.extension
It may perfect sense to Get/Put any of these five properties independently; depending on what the program intends to do with the information. If it wants to create a sibling file, it can use GetDirectory. If it wants to name a known sibling file according to some convention, it might want to set the extension only. If it wants to name a companion file in a different folder, to set the directory, and so forth.
Personally I prefer dropping the "set" and "get" prefixes from the
method names altogether. For example:
(deleted)
This naming convention is also consistent with the IDL/C++ language
binding, and I wanted to seek your opinion regarding this.
You are talking about the CORBA IDL C++ language binding of course... as opposed to the many other IDL's, such as DCE/RPC, MIDL, MACH, Sun RPC and so forth.
It is time to invoke the concept of Least Surprise. If the code is intended or likely to be mixed with CORBA objects and calls, this would be a good convention to use. If it is intended or likely to be used together with with some other convention, you may wish to use that convention.
Personally I prefer Get/Put as prefixes, because one day you will need an indexed property.
class A{
public:
std::string GetValue(const std::string& name);
void PutValue(const std::string& name, const std::string& value);
};
Some times it is appropriate to use more than one convention:
class B{
public:
long get_Value(const std::string& name, std::string& value) throw();
long put_Value(const std::string& name, const std::string& value) throw();
std::string GetValue(const std::string& name) throw(MyException){
std::string tmp; long lErrCode = get_Value(name, tmp);
if(lErrCode)throw MyException(lErrCode);
return tmp;
}
void PutValue(const std::string& name, const std::string& value) throw(MyException){
long lErrCode = put_Value(name, value);
if(lErrCode)throw MyException(lErrCode);
}
};
This gives more flexibility to the user of the class. The verbosity and duplication involved mean that it is only really appropriate for very small or very stable libraries which are frequently used and thoroughly tested, or of course, for machine-generated code, for example from some sort of IDL.