嗔秤戻幣�哉膵�云利匈嬉蝕湊蛸賜�塋床四衲���萩晦編報炎嘔囚^泡仟 ̄云利匈��
VB2008貫秘壇欺娼宥(PDF鯉塀哂猟井)-及44何蛍
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何! 泌惚云慕短嗤堋響頼���誅卒亮茂�俊彭堋響��辛聞喘貧圭 "辺茄欺厘議箝誓匂" 孔嬬 才 "紗秘慕禰" 孔嬬��
´´´´´´´´´´´´´´´´´´´´´´Page 246´´´´´´´´´´´´´´´´´´´´´´´
224 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
is correct。 For example�察�if LightingController indicated to turn the light off even though a
person is in the room�察�then PublicRoom would not ask why the light is being turned off。
*Note When you are designing a kernel´like architecture�察�the implementations are realizations of ideas and
should never question the controller。 The implementations might not be aware of a bigger picture and thus
might prevent an algorithm from functioning properly。 Of course�察�the exception to this rule is if the decision
would cause physical damage or cause the program to crash。 In that case�察�the implementation should throw
an exception�察�indicating that the decision is faulty。
Instantiating PublicRoom and PrivateRoom
As described in the previous chapter�察�when you are developing ponents�察�you want to separate
the interfaces from the implementations。 This gives you the flexibility to change the imple
mentation in an assembly without requiring the users of the assembly to repile their code。
To instantiate the implementations�察�you need a factory�察�and the museum with its PrivateRoom
and PublicRoom implementations is no different。 However�察�a builder method that assembles a
building of potential PrivateRoom and PublicRoom binations will be offered with the museum。
The builder method is useful because it predefines a canned building that has all the room
groupings and rooms properly added。
*Note Think of a builder method as a way of creating a predefined structure�察�thus saving users from having
to do that themselves。 A builder method is only a starting point�察�and you should be able to manipulate the
structure afterward for fine´tuning purposes。
The following is the implementation of the museum factory�察�which is added to the project
Museum。
Public Module FactoryRooms
Public Function CreateBuilding�┌� As LightingController
Dim controller As New LightingController�┌�
Dim publicAreas As Object = _
controller。AddRoomGrouping�─�public viewing areas;��
Dim privateAreas As Object = _
controller。AddRoomGrouping�─�private viewing areas;��
controller。AddRoomToGrouping��publicAreas�察�New PublicRoom�┌���
controller。AddRoomToGrouping��privateAreas�察�New PrivateRoom�┌���
Return controller
End Function
´´´´´´´´´´´´´´´´´´´´´´Page 247´´´´´´´´´´´´´´´´´´´´´´´
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 225
Public Function CreatePrivateRoom�┌� As IRoom
Return New PrivateRoom�┌�
End Function
Public Function CreatePublicRoom�┌� As IRoom
Return New PublicRoom�┌�
End Function
End Module
The implementation has three methods�此�CreateBuilding�┌��察�CreatePrivateRoom�┌��察�and
CreatePublicRoom�┌��察� The fact that CreatePrivateRoom�┌� and PrivateRoom�┌� have similar naming is
purely coincidental。 The method could just as well have been called CreateNonControlledRoom�┌�。
The CreatePrivateRoom�┌� and CreatePublicRoom�┌� methods are intended to define method
identifiers that users can understand。 What is instantiated in the method must return an IRoom
instance。
The CreateBuilding�┌� method is a builder method�察�and it returns a LightingController
instance。 It is fine to return a LightingController instance�察�because it is a globally defined type
and can serve as a basis for the builder method。 In the implementation of the builder method�察 �
the room groupings and rooms are instantiated and added to the LightingController instance。
This is the work that the builder should save the end user。 Additionally�察�by providing a builder
method�察�you avoid creating museum structures that have glaring errors in their structures。
*Note Factory types serve to instantiate types and define builder methods�察�but can also be used to perform
generic structural operations。 Let¨s say that in your museum there is a wing�察�which contains three public
rooms and a private room。 You could define a builder method that creates a wing�察�and the wing is added to
an already created building。 The general idea behind the factory type is to avoid errors and centralize repeated
instantiations。
Learning More About Private Classes and
Object Initialization
In this chapter�察�you learned how to apply interfaces�察�implementations�察�and ponents in a
kernel´type situation。 This is very much the type of programming that you will encounter as
you continue using Visual Basic。 Here�察�I will provide a few more details about using private
classes and initializing objects with nested data types。
Private Classes
The RoomGrouping and Room classes are defined in the LibLightingController project and are
private to the library。 This is because RoomGrouping and Room are classes only LightingController
needs to support its functionality。 The declaration of each class is internal to the assembly�察 �
which is good�察�but it still means that some developers could use the classes within the kernel
assembly for their own purposes。 Sometimes that is a desirable feature�察�sometimes it is not。
´´´´´´´´´´´´´´´´´´´´´´Page 248´´´´´´´´´´´´´´´´´´´´´´´
226 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
In the case of LightingController�察�another approach is to declare the classes in the
context of LightingController�察�as follows�此�
Public Class LightingController
Private Class RoomGrouping
End Class
Private Class Room
End Class
End Class
The Room and RoomGrouping classes are declared within the class�察�and their declarations are
Private。 This means that only LightingController can instantiate and use the classes�察�and
there can never be the situation where another class will instantiate the types。 In the case of
LightingController�察�this would have been a better solution。
Private classes are also used in the factory context。 For example�察�imagine the situation
where you don¨t ever want anyone but the factory to instantiate a room。 A possible IRoom decla
ration and factory could be as follows�此�
Public Module Factory
Private Class MyRoom �此�Implements IRoom
End Class
Public Function CreateMyRoom�┌� As IRoom
Return New MyRoom�┌�
End Function
End Module
In this implementation of MyRoom�察�you can be sure that only Factory can ever instantiate
MyRoom�察�and you can always be sure that the only way to manipulate MyRoom is through the IRoom
interface。 All too often�察�developers bee lazy and instantiate types within the assembly�察�and
switch to the implementation type whenever the interface does not have the methods or prop
erties that they want。
Object Initialization with Nested Data Types
In this chapter�察�you saw how to use object initialization to assign data members in lieu of a
constructor。 Object initialization also works using nested data types。 Consider the situation
where a type references another type。 Using object initialization�察�you can instantiate and
assign multiple levels of objects。
Suppose you had this source code�此�
Class MyType
Private _dataMember As Integer
Public Property DataMember�┌� As Integer
Get
Return _dataMember
End Get
´´´´´´´´´´´´´´´´´´´´´´Page 249´´´´´´´´´´´´´´´´´´´´´´´
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 227
Set ��ByVal value as Integer��
_dataMember = value
End Set
End Property
End Class
Class EmbeddedMyType
Private _embedded As MyType
Public Property MyTypeProperty�┌� As MyType
Get
Return _embedded
End Get
Set ��ByVal value As MyType��
_embedded = value
End Get
End Property
End Class
The type EmbeddedMyType has a property that references MyType。 If you were to instantiate
EmbeddedMyType�察�you would probably also want to instantiate and assign the property MyType。
You can do that with object initialization�察�like this�此�
Dim cls As EmbeddedMyType = _
New EmbeddedMyType�┌� With �� _
。MyTypeProperty = _
New MyType�┌� With ��。DataMember = 10����
The Important Stuff to Remember
In this chapter�察�you learned about writing a kernel�察�using Visual Basic default properties�察�and
the implementing enumeration functionality。 The main items to remember are as follows�此�
o A kernel is a ponent´oriented architecture where you are not in control of certain
implementations。 ponents make it possible to modularize a development process
so that separate teams have their own tasks。
o Interfaces are contracts between modules�察�and you test against the interface�察�not the
implementation。
o Placeholder interfaces are used to make it simpler to group object instances。
o Default properties are structural�察�and thus they serve as a tool to help you acplish a
task quicker。
o Default properties make it possible for your type to behave like an array。
o To iterate something that does not support iteration�察�you add enumeration function
ality�察�which implies implementing the IEnumerable and IEnumerator interfaces。
´´´´´´´´´´´´´´´´´´´´´´Page 250´´´´´´´´´´´´´´´´´´´´´´´
228 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
Some Things for You to Do
The following are some exercises that will help you apply the concepts you learned in this chapter。
1。 The LightingController。AddRoomGrouping�┌� method has a mistake。 Write some tests to
find the error�察�and then fix the code and rerun your tests to verify that the error has
been fixed。
2。 The TestInsert�┌� test method is one example of an insertion test�察�but not all variations
have been tested。 Write another test method that implements the remaining variation��s��
that need to be tested。
3。 The declarations of RoomGrouping and Room are not optimal。 Fix the declarations。
4。 Implement a general collection class based on the experience of using the class in the
class LightingController。 Hint�此�look at how the linked list for Room is declared and figure
out a way to abstract that into some general collection class。
5。 When the method LightingController。AddRoom�┌� is called�察�the method is tested internally
to see if the handle is of type RoomGrouping。 Can you think of a more defensive pro
gramming technique to make sure that the code someone else passes to the kernel will
not cause the kernel to fail�拭�Hint�此�think about the methods to turn on or off the lights
and think of what could go wrong。
´´´´´´´´´´´´´´´´´´´´´´Page 251´´´´´´´´´´´´´´´´´´´´´´´
C H A P T E R 9
* * *
Learning About Lists�察�Delegates�察 �
and Lambda Expressions
One of the most mon pieces of code that you will write is code that manages many object
instances。 In the previous examples�察�many object instances were managed using an array。 In
Chapter 8�察�you learned that a linked list used in conjunction with a default property could make a
plain´vanilla object look like a collection。 This chapter introduces the collection classes�察 �
which provide an easy way to manage a set of object instances。 Think of a collection object as
an infinite sack where things can be added�察�iterated through�察�and retrieved。
The chapter begins with a discussion of how to manage collections。 Then we will look at
different ways of iterating the data using a delegate。 Finally�察�we will look at lambda expressions
and closures to illustrate another way of processing data。
The project structure used in this chapter is a single console application。 As we will not be
building an overall application�察�but rather a set of sample code snippets�察�no tests or libraries
are involved。
Managing Collections
When you have a collection�察�what you actually have is an object that happens to point to many
other objects。
Visual Basic provides collection classes for managing collections。 Visual Basic 2005 intro
duced a different approach to collections�察�which solved many of the problems that came up
in earlier Visual Basic versions。 Here�察�we¨ll look at managing collections both before and after
Visual Basic 2005�察�which will help you to understand how collections are used。
Managing a Collection Before Visual Basic 2005
Before Visual Basic 2005�察�the main collection classes were stored in the namespace System。
Collections ��and�察�of course�察�these classes are still available for you to use��。 The following are
some of the classes and interfaces in that namespace�此�
229
´´´´´´´´´´´´´´´´´´´´´´Page 252´´´´´´´´´´´´´´´´´´´´´´´
230 CH AP T E R 9 * L E A R N IN G AB OU T L I ST S�察 �D E L E G A T E S�察 �A N D L A M B DA E X P R E S SI ON S
o ArrayList�此�A general collection that manages all of the referenced objects using an
internal array。 This class manages the problem of increasing the size of an array。
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何!
梁椣戻幣�� 梁心弌傍議揖扮窟燕得胎��傍竃徭失議心隈才凪万弌誌育断蛍�輌臆惨軼僑〃�燕慕得珊辛參資誼持蛍才将刮襲潜��範寔亟圻幹慕得 瓜寡追葎娼得辛參資誼寄楚署衛、持蛍才将刮襲潜填��