John Gunnarsson wrote:
> I'm using accessors and mutators for primitive datatypes such as integers
> and string, but what about an object, thats my main concern. If I have an
> accessor/mutator for the object field aswell, I always reterive/set the
> whole state of that object field, where I would prefere to change invoke
> that objects mutator to change only a part of the object state. With the
> classic design if mutator you must replace the entire object which in my
> view is not what I want.
> 
> I tried to find info on this on the web but didn't find any useful info
> regarding this specific problem, but I will have a look at the links folder.
> 
> 
> //John
>>> class Address
>>> {
>>> public:
>>> string getCity();
>>> string setCity(string const &city);
>>>
>>> int getId();
>>> void setId(int const &id);
>>> private:
>>> string name;
>>> int id;
>>>
>>> };
>>>
>>>
>>> class Order
>>> {
>>> public:
>>> /*
>>> what to do here? implement get/set functions for the fields
>> below,
>>> or it it okay to declare the payer and shipto members here?
>>> */
>>>
>>> private:
>>> Address payer;
>>> Address shipto;
>>> };
>>>
>>> //John

Hello John,

The only time where making variables public is useful is when the class 
would only contain get/set type methods.  That is, you plan on using a 
class solely for putting a bunch of data into.  The time to make the 
variables private is when you need program logic to modify one or more 
variables.  Of course, if you need to make a couple variables private, 
it is best to make all of them private.

It also helps to know what type of application you are making.  For 
quick-n-dirty applications, I'd probably just use 'public's.  Larger 
applications will need private variables and public functions just to 
help protect the programmer from breaking stuff.  Most "pure data 
storage" classes, I would make public just to keep programming simple.

As an example, BString is not a data storage class (it does provide 
access to the raw data, but that's considered a dangerous operation) so 
the variables are private.  But if I were to load in a set of records 
from a database and I wanted to store them all in memory for later 
analysis, I would probably make all members of the new class public 
because I would be using that class solely for in-memory data storage. 
The database stuff would involve high-level functions like SQLExecute(), 
Connect(), and Disconnect().  There would be private variables that no 
one is supposed to directly touch and there is programmatic logic that 
manipulates those variables (indirectly through the high-level functions 
I mentioned).

That's my view:  Make data access as easy as possible without 
sacrificing application stability.  If your get/set method is just 
retrieving/assigning values from/to a private variable, then what's the 
point?  There's no real protection involved.  Your example shows 
setCity()/getCity() and implies it changes 'name'.  So, make the 
variable's name 'City' (I'd prefer MxCity to indicate a member 
variable), make it public, and eliminate the set/get methods.  Same with 
ID.  A scenario that would involve making variables private would be:

class Order
{
public:
   Order();

   int SetPaymentInfo(const Address &Payer, const Address &ShipTo, const 
CCInfo &CreditCard);
   int SetMerchantInfo(BString MerchantID, BString MerchantEmail, 
BString MerchantSSLCert = "");
   int ProcessOrder(BString &Result);

private:
   Address MxPayer, MxShipTo;
   CCInfo MxCreditCard;
   BString MxMerchantID, MxMerchantEmail, MxMerchantSSLCert;
};

Notice how high-level everything is.  A payment is defined by a group of 
three different class instances:  Payer, ShipTo, and CreditCard.  A 
merchant is defined by their ID, e-mail, and an optional SSL 
certificate.  ProcessOrder() takes all the information provided by the 
other two functions and attempts to resolve the payment with the payment 
processor.  Errors and other messages are stored in Result.

It is also important to note that while classes are going to be copied, 
the function ProcessOrder() is going to take significant amounts of 
time.  Payments can take 30-60 seconds to process (usually less, but it 
is lengthy).  Copying a couple classes and chucking data around isn't 
going to be noticeable in comparison.

-- 
Thomas Hruska
CubicleSoft President
Ph: 517-803-4197

*NEW* VerifyMyPC 2.2
Change tracking and management tool.
Reduce tech. support times from 2 hours to 5 minutes.

Free for personal use, $10 otherwise.
http://www.CubicleSoft.com/VerifyMyPC/

Reply via email to