按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
Figure 6…3。 Exposing ExchangeRate as a Visual Basic property
To pletely fool the test; the name of the property must be identical to the name of the
previously declared data member。 So that there is no identifier collision; the data member
ExchangeRate is renamed to _exchangeRate; and the scope changes from public to private。
Properties look like methods without parameters; but have a return value。 Also; each prop
erty must have at least a Get code block or a Set block (it can have both); which are called getters
and setters。 If a property has only a Get code block; you have created a read…only property。 If a
property has only a Set code block; you have created a write…only property。 Within the context
of a property; you can have only the Get or Set keyword。 You cannot add any other code。
The following code will execute the code defined in the Get code block and retrieve the
state from the object to the variable。
value = cls。ExchangeRate
And the following code will execute the code in the Set code block and assign the state
from the variable to the object。
…………………………………………………………Page 165……………………………………………………………
CH A PT E R 6 ■ L E A R N I N G T HE B AS IC S O F O B J E CT OR I E N TE D P R O G R AM M IN G 143
cls。ExchangeRate = value
Each code block has special features。 The Get code block must always return data to the
caller and thus requires the use of the Return keyword。 The Set code block has no requirements
to do anything。 However; if you want to know what data is being passed to the property; you
can use the value parameter。
Understanding the Problems with Properties
Many programmers feel that properties promote bad programming practices。 Properties expose
the internal state of an object。 Looking at the previous source code; you will see that the data
member _exchangeRate has a one…to…one relationship to the property ExchangeRate。 If the caller
assigns the property ExchangeRate; then the private data member _exchangeRate is immediately
assigned。 This exposes the internal state; even though the exposure is indirect。
As an example; say that you want to preheat an oven to a certain temperature to bake
something。 The simplest way to preheat the oven is to monitor the temperature and create a
property Temperature; like this:
Class Oven
Private _temperature As Integer
Public Property Temperature() As Integer
Get
Return _temperature
End Get
Set(ByVal Value As Integer)
_temperature = Value
End Set
End Property
End Class
The class Oven exposes its temperature as a property; which is a direct reference to the vari
able _temperature。 The caller of Oven would periodically ask the oven for its temperature and
decide when the oven has been preheated。
So; is Oven in its current implementation actually a structural class? The user of Oven has
quite a bit of responsibility in that it must periodically query the temperature and decide if the
oven is preheated。 A better implementation is to define a class that takes care of itself。 The caller
would then just need to ask; “Are you ready?” Here’s how that code would look:
Class Oven
Private _temperature As Integer
Public Sub SetTemperature(ByVal temperature As Integer)
_temperature = temperature
End Sub
Public Function AreYouPreheated() As Boolean
' Check if oven temperature matches prescribed temperature
Return False
End Function
End Class
…………………………………………………………Page 166……………………………………………………………
144 CH AP T E R 6 ■ L E A R N IN G T HE B AS IC S O F OB J E CT OR I E N T E D P R O G R AM M IN G
In the modified implementation of Oven; the data member _temperature is not externally
exposed。 And in this situation; the role of the data member _temperature is not to represent the
temperature of the oven; but to act as an upper limit to which the oven should be heated。 The
upper limit is assigned using the SetTemperature() method。 To check the temperature of the
oven; you don’t retrieve the temperature of the oven; but call the AreYouPreheated() method。
The caller receives either a True or False value to indicate whether or not the oven is ready。
The caller of Oven has the responsibility only of setting the upper temperature and asking
if the oven is preheated。 From this example; it would seem that you don’t need properties。
However; you still need properties because Oven in its current form represents an easy…to…use
class that can be integrated at the architectural business…logic level。
The challenge of the developer is to bridge the gap between a raw structural class and the
exposure of an architectural business…logic…level class。 That challenge will be met when the
hotel currency trader and active currency trader are implemented。
Even with these arguments and the distinction between base class and architectural business
logic…level classes; some still naysay properties。 The reason has to do with controlling access。
Suppose you are in a grocery store; waiting at the cash register。 The cashier tallies up the
items; arrives at a total; and asks you to pay。 Do you open your purse or wallet and let the cashier
get the credit card or cash? Along the same lines; why can’t you just place the cash into the cash
register? The answer to these questions is one of trust。 As trustworthy as the cashier and shop