梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈��梓囚徒貧議 Enter 囚辛指欺云慕朕村匈��梓囚徒貧圭�鮗� ● 辛指欺云匈競何��
!!!!隆堋響頼��紗秘慕禰厮宴和肝写偬堋響��
ability to make decisions based on whether an instance would like to be associated with a particular grouping
based on an interface。
Defining the IRemoteControlRoom Interface
Another type of room is one where the lighting is pletely managed by the controller。 The
controller does not seek the input of the room and manages the lighting based on the logic that
seems appropriate to it。
For example�察�a public´viewing area in a museum does not require light at certain times of
day。 When the museum is closed and the cleaners are finished�察�the lights can be turned off。 When
the museum is open�察�the lights are turned on。 This is a simple logic and can be pletely
managed by the controller。
The interface for the controlled room is defined as follows ��in LibLightingSystem���此�
Public Interface IRemoteControlRoom
Inherits IRoom
ReadOnly Property LightLevel�┌� As Double
Sub LightSwitch��ByVal lightState As Boolean��
Sub DimLight��ByVal level As Double��
End Interface
The only input that IRemoteControlRoom provides is information about whether the light is
on�察�off�察�or at a certain level。 This is through the LightLevel property。 The LightLevel property
is read´only�察�because the controller and the light level might bee out of sync。
For example�察�suppose it¨s time for the museum to close�察�and the lights are switched off in
the public´viewing area。 But today�察�the cleaners took a little while longer than usual。 They turn
the lights back on so that they can see what they are doing。 The local device can do one of two
things�此�allow the light to be turned on without the approval of the controller�察�or not allow the
light to be turned on�察�requiring a controller intervention。 The best approach is to allow a local
override and let the cleaners turn on the light。 The LightLevel property is necessary so that the
controller can verify if the state of the light is what the controller expects it to be。
*Note When you are defining a kernel�察�sometimes it is necessary to add functionality into an interface that
verifies the state of the implementation。 Because the kernel is not in control of the implementation�察�the kernel
should not assume the state�察�as the state could change for some reason。 In the case of the lighting system�察 �
the change could be due to a cleaner turning on the light after it was turned off。
´´´´´´´´´´´´´´´´´´´´´´Page 225´´´´´´´´´´´´´´´´´´´´´´´
C H AP TE R 8 * L E AR N IN G AB O U T CO M P O N E N T O R IE N TE D A R CH I TE C TU R E 203
The IRemoteControlRoom methods LightSwitch�┌� and DimLight�┌� turn the light on or off
and set the light to a certain level�察�respectively。 These methods are used to control the state of
the implementation。
Defining the ISensorRoom Interface
Another type of room is one that can be controlled under certain circumstances。 Let¨s go back
to the cleaner example where the cleaner turned on the light。 If the controller notices that the
light is on�察�even though it was turned off�察�should the controller turn off the light�拭�You might say
sure�察�the controller should turn off the light。 However�察�that is not pletely correct。 Imagine
the situation where the cleaner turns on the light and the controller turns it off。 The cleaner would
immediately turn the light back on�察�and the controller would turn it off。 The cleaner would tape
the light switch down so that a constant battle of the light going on and off ensues ��because this
battle is in milliseconds�察�the light remains on��。 A smarter approach would be to allow a timing
of the light。 But how much time!a quarter of an hour�察�a half hour�察�an hour�拭�
Another approach is not to use a time interval�察�but to enhance the interface and allow the
controller to figure out the state。 This enhanced interface�察�called ISensorRoom�察�is defined as
follows ��in LibLightingSystem���此�
Public Interface ISensorRoom
Inherits IRemoteControlRoom
ReadOnly Property IsPersonInRoom�┌� As Boolean
End Interface
The ISensorRoom interface has a single property IsPersonInRoom�察�which is a Boolean prop
erty。 If the property has a value of True�察�then a person is in the room�察�otherwise�察�no person is in
the room。 How the implementation determines whether or not a person is in the room is not
the problem of the kernel。 The kernel assumes the implementation knows how to figure this
out。
*Note As a general rule of thumb�察�the kernel can municate with the implementation only via the inter
face。 The kernel should never assume a certain implementation of an interface。 The kernel should take the
approach that what it sees is what it gets。 Thus�察�if the kernel needs additional information�察�the interface
should be extended during design�察�or another interface should be implemented。 Of course�察�this does not mean
for every piece of state the interface should be extended。 Sometimes�察�you will need to define a specific inter
face�察�such as in the tax application example in the previous chapter �─�ICanadianTaxEngine��。
Now that we¨ve created the interfaces�察�we¨re ready to implement the kernel。
Implementing the Kernel
In this example�察�the kernel will be a single class that contains all of the functionality of the
controller。 This definition means that the individual implementations�察�testing�察�and applica
tions will interact with a single class。
´´´´´´´´´´´´´´´´´´´´´´Page 226´´´´´´´´´´´´´´´´´´´´´´´
204 CH AP T E R 8 * L E A R N IN G AB OU T CO M P O N E N TO R IE N T E D AR C HI TE CT U R E
Here is an example of implementing the light´dimming method using the
LightingController class ��in LibLightingSystem���此�
Public Class LightingController
Public Sub DimLights��ByVal grouping As Object�察�ByVal level As Double��
End Sub
End Class
The user of LightingController would dim a light using this code�此�
Dim controller As LightingController = New LightingController�┌�
Dim grouping As Object = Nothing
controller。DimLights��grouping�察�0。50��
The user code instantiates the type LightingController directly and uses the method
DimLights�┌� directly。 Using classes directly has the cost that the controller code cannot change
without affecting the users�察�as there is a tight coupling between the user code and the kernel。
And this is why I have been writing at length about using interfaces�察�ideas�察�and implementa
tions。 Yet�察�the controller appears to throw all of that out of the window。
The reason for using a class goes back to the previous chapter¨s example and the interfaces
ITaxDeduction and ITaxIne。 That example had only a single implementation of each inter
face�察�and those implementations were not going to change。 As I explained in the previous chapter�察 �
the interfaces could have been represented as classes。 The same logic applies with respect to
the controller。 The controller is not going to change much from a method and property signature
perspective�察�and there is going to be only a single implementation of the controller。 Therefore�察�an
interface is not necessary。 Using a class is pletely acceptable�察�and it¨s the approach we¨re
using in this chapter。 However�察�I¨ll talk about when you might want to implement the kernel as