Directives

Create Loosely Coupled, Highly Specialized Procedures

Visual Basic makes creating procedures easy, but this simplicity masks the art and science of building well-crafted procedures. Visual Basic places few rules on procedures it doesn't limit the number of statements you can place within a procedure, nor does it limit how many tasks can be performed by a procedure. Although Visual Basic doesn't enforce such limitations, you should be self-governing in these areas to create better procedures. In the following sections, I'll describe how to do that.

Make All Procedures Perform Specialized Functions

The first thing to keep in mind is that every procedure should perform a specific function, and it should do so very well. You should avoid creating procedures that perform many different tasks. This frequently requires some forethought because what constitutes a task is not always obvious. For instance, in an inventory management application you might need to create a posting routine to post receipts generated from a purchase order. The steps involved in posting might include

  • Retrieving the ID and cost of a received item

  • Confirming that the ID exists in the master table of inventory items

  • Updating the quantity on hand in the inventory table

  • Updating total, average, and latest costs for the item in the database

  • Updating the FIFO or LIFO records, if FIFO (first in, first out) or LIFO (last in, first out) accounting practices are being used

You can use a number of approaches to code this functionality. You could create a single posting procedure that performs all these actions, or you could create more specialized procedures such as those in the following list:

  • PostPurchaseOrderReceipt (main entry procedure)

  • ValidateItemExistsInMasterInventoryTable

  • UpdateQuantityOnHand

  • UpdateItemCosts

  • UpdateFIFOLIFO

Creating specialized procedures has a number of advantages. First, debugging becomes easier. If you're getting incorrect latest costs on your inventory valuation reports, you'd know to begin your search for bugs in the UpdateItemCosts procedure. If you placed all this code in a single PostPurchaseOrderReceipt procedure, you'd have to wade through the other functionality to get to the cost-related code. When you create specialized procedures, you won't always locate errors in the first procedure in which you look, but you'll reduce the amount of time you spend hunting for them.

Perhaps an even more important advantage of creating specialized procedures is the ease with which you can make planned or unplanned modifications to the code. Continuing to use the example above, let's say that a change within your organization causes certain business rules to change or causes a change in the data storage tier. Consider that you are no longer going to keep inventory in a single location but rather are going to spread it across multiple warehouses. When an item is received in inventory, it must be received in your inventory management application in a specific location. If you've isolated the code that adds the item to inventory the UpdateQuantityOnHand procedure here you'll know exactly where to go to make the changes and you'll affect only a small and specialized area of the code. If instead you placed all the posting-related code in one procedure, adding features would cause the procedure to bloat, making it increasingly more difficult to manage.

There are no hard-and-fast rules as to how to split a process into specialized procedures. You want to create efficiently maintainable procedures, but you don't want to have to keep track of dozens of tiny procedures that would be better utilized as parts of a larger procedure. When in doubt, have someone review your code; it usually helps to get a different perspective. This is an area where experience really improves your skills. Over time, you'll get a feel for how parts of code are maintained and modified.

Make Procedures as Self-Contained as Possible

Besides making procedures as specialized as possible (within reason), you should also make procedures as self-contained as possible. When a procedure relies on calls to other procedures, it's said to be tightly coupled with those other procedures. Tightly coupled procedures make debugging and modifying more difficult because more factors are involved. When you create procedures that rely on few or no calls to other procedures, you create loosely coupled procedures. Loose coupling is superior to tight coupling, but of course it's impossible to make every procedure a self-contained entity. Nonetheless, strive to reduce the coupling of procedures as much as possible.

One way to make procedures more self-contained is to minimize global and module-level variables. Procedures that use global or module-level variables are not self-contained because they rely on data outside of their full control. For more information on controlling the scope of variables and on the evils of global variables, refer to Chapter 5, "Variables."

As you're developing your procedures, try to think of each procedure as a black box other routines shouldn't require knowledge of the inner workings of the procedure, nor should the procedure require knowledge of items outside of it. This is why your procedures should rely on parameters rather than global data. When a procedure accepts parameters "through the front door," the parameters become data local to the procedure. (Every procedure has a single entry point, known as the front door, and should contain only one exit point, the back door.) When a procedure uses global or module-level variables, it's accessing data outside of its own confines.

When creating specialized procedures, consider the following guidelines:

  • Put complex processes in specialized procedures. If an application utilizes complex mathematical equations, consider putting each equation into its own procedure. That way other procedures that use the equations won't be burdened with the actual code for that equation. This also makes it easier to debug problems related to the equations, and to replace the equations in the event that more accurate or faster equations are found.

  • Hide data input/output (I/O) in specialized procedures. It might be necessary later to change the way data I/O is handled. For instance, you might modify an application that uses text files so that it uses a database engine such as Microsoft SQL Server. If the application's data I/O functionality is isolated in specialized procedures, it'll be much easier to make the necessary modifications.

  • Isolate areas of code likely to change in specialized procedures. If you know that a certain process might change over time, place the volatile code into specialized procedures to make it easier to modify later and to lessen the likelihood that you'll inadvertently cause problems with other processes.

  • Encapsulate business rules in specialized procedures. Often, business rules fall into the category of code likely to change and should be isolated from the rest of the application. Other procedures shouldn't know the business rules, only the procedures to call to apply the business rules.

Minimize Fan-In and Fan-Out

Fan-in and fan-out, illustrated in Figure 2-1, are technical terms used to describe, respectively, the number of procedures that call a single procedure and the number of procedures called from within a procedure. When a given procedure is called (and therefore relied on) by numerous other procedures, it's said to have a high degree of fan-in, which is good. A procedure with a high degree of fan-in is generally a well-encapsulated procedure, and it supports the concept of code reuse. A procedure that makes calls to numerous other procedures has a high degree of fan-out, which is not so good. A high degree of fan-out means that the procedure relies on many other procedures to get its job done in other words, it's a tightly coupled procedure. This makes debugging more difficult because of the added complexity of following the execution path.

Figure 2-1. A procedure with fan-in and a procedure with fan-out.

graphics/f02ln01.jpg

When maximizing fan-in and minimizing fan-out, you'll have to accept some give-and-take; there's no perfect solution in a given project. If you follow all the principles of creating specialized procedures, you're bound to encounter situations in which some procedures have a high degree of fan-out because they're delegating various tasks to other specialized procedures. Achieving a balance of specialized procedures with loose coupling, strong cohesion, higher fan-in, and lower fan-out is a continuing goal that's never fully met.

Attempt to Alphabetize Procedures Within a Module

In Visual Basic 6, you had the option of working with the code editor in multiple-procedure or single-procedure mode. In Visual Basic .NET, the only option is to work with code in multiple-procedure mode (the best choice anyway, in my opinion). This mode allows you to scroll in the code window and view multiple procedures at one time, as shown in Figure 2-2. Because it's possible to scroll the code window to look for a procedure as well as select a procedure from the procedure drop-down list, having the procedures sorted alphabetically helps you more easily find a particular procedure when scrolling making the scroll bar much more useful.

Figure 2-2. Alphabetizing procedures makes scrolling through a procedure more effective.

graphics/f02ln02.jpg

 

Goals of Designing Modules and Procedures

Your goals when designing modules and procedures should include

  • Creating procedures that are easier to debug and maintain

  • Creating modules that have strong cohesion

  • Creating highly specialized procedures

  • Creating loosely coupled procedures

  • Making procedures as self-contained as possible

  • Increasing fan-in

  • Reducing fan-out

 



Practical Standards for Microsoft Visual Basic. NET
Practical Standards for Microsoft Visual Basic .NET (Pro-Developer)
ISBN: 0735613567
EAN: 2147483647
Year: 2005
Pages: 84

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net