Скачиваний:
64
Добавлен:
15.03.2015
Размер:
4.31 Mб
Скачать

Chapter 4 • A GUIDED TOUR THROUGH C#: PART II 105

Tip

The order in which the methods of a class are defined is arbitrary and has no relation to when you can call those methods in your source code and when they will be executed. Accordingly, you could change the order in which the Sum and Product definitions appear in the definition of the

SimpleCalculator class.

The Math Class: A Useful Member of the .NET Framework

Line 20 is similar in concept to lines 18 and 19. However, here we utilize the Math class (instead of Sum and Product) of the System namespace in the .NET Framework class library to find the greater of two numbers using the Max method.

20:Console.WriteLine(“The maximum number is: “ + Math.Max(x, y));

The Math class contains many useful math-related methods, such as trigonometry and logarithms.

Tip

It is permissible to spread one long statement over several lines as long as no tokens are separated into smaller pieces of text. However, if not thoughtfully done, breaking up statements into several lines can easily obscure the readability of the source code. To avoid this problem, choose logical breaking points, such as after an operator or after a comma. When statements are separated into more than one line, indent all successive lines.

For example, we might decide that line 20 of Listing 4.1 is too long

20:Console.WriteLine(“The maximum number is: “ + Math.Max(x, y));

and break it up after the concatenation operator (+) so that Math.Max(x,y)); is moved down to the next line and indented

20:Console.WriteLine(“The maximum number is: “ + Math.Max(x, y));

Analogous to line 20, Math.Min(x, y) in line 21 finds the smaller of x and y.

21:Console.WriteLine(“The minimum number is: “ + Math.Min(x, y));

This ends our tour through Listing 4.1.

Simplifying Your Code with Methods

We have already discussed how the construction of an object-oriented program can be simplified by breaking it down into suitable classes. The following case study looks at how the design of an individual class can be simplified by breaking its functionality down into suitable methods. It exemplifies and stresses the importance of thinking in terms of building blocks on the method level also.

106 C# PRIMER PLUS

Methods As Building Blocks: Encapsulating Your Helper Methods with the private

keyword.

We can expect the internal parts of each class in a program to be less complex than the overall program, but the programmer is still often confronted with individual classes of relatively high complexity. Fortunately, it is possible to reduce this complexity by dividing its functionality into methods. Let’s look at an example.

Notice that this discussion is relevant to step 2c (Identification of methods in each class) and step 2d (Internal method design) of the Software Design phase in the Software Development Process presented in Chapter 2.

Consider a map represented in your source code by a class called Map. One of the services of this class is to calculate the distance between a list of 6 specified locations (here referred to as L1, L2, L3, L4, L5, and L6) on the map. Every location in the map constitutes a set of 2 coordinates (x and y), where L1 has the coordinates (x1, y1), L2 has the coordinates (x2, y2), and so on. The distance between two locations, say L1 (x1, y1) and L2 (x2, y2), can be calculated by using Pythagoras’s formula:

distance =

which can be used to calculate the distance of a path beginning at L1 and going through L2, L3 and on to L6. The formula for this calculation is

Total distance =

L1 to L2 + L2 to L3 + L3 to L4 + L4 to L5 + L5 to L6 =

We can implement this distance calculation in two ways:

By using just one method, without any attempt to break up the problem into a couple of simpler methods.

By thinking in terms of methods as building blocks, we can divide the functionality into several methods.

To keep the examples simple, I will only provide the very important parts of the C# code.

Let’s have a closer look at each implementation.

Chapter 4 • A GUIDED TOUR THROUGH C#: PART II 107

• By using only one method:

totalDistance =

Math.Sqrt(Math.Pow(x1-x2,2) + Math.Pow(y1-y2,2)) + Math.Sqrt(Math.Pow(x2-x3,2) + Math.Pow(y2-y3,2)) + Math.Sqrt(Math.Pow(x3-x4,2) + Math.Pow(y3-y4,2)) + Math.Sqrt(Math.Pow(x4-x5,2) + Math.Pow(y4-y5,2)) + Math.Sqrt(Math.Pow(x5-x6,2) + Math.Pow(y5-y6,2));

where Math.Sqrt(x) calculates the square root of x and Math.Pow(a, b) raises a to the power of b.

This coding nightmare is one statement spread over six lines of source code. Let’s try to simplify this massive statement.

• Breaking down the functionality into two methods:

Because we are repeatedly calculating distances between two locations, we can separate the functionality into two methods—a helper method calculating distances between two locations and a method calculating the total distance between the six locations. We will simply call our helper method Distance and let it contain four formal parameters a1, b1 (representing the first location) a2, b2 (representing the second location). When Distance is called, it returns the distance between the location arguments sent to it.

We can now write the calculation in only four lines of code.

TotalDistance =

Distance(x1,y1,x2,y2) + Distance(x2,y2,x3,y3) +

Distance(x3,y3,x4,y4) + Distance(x4,y4,x5,y5) +

Distance(x5,y5,x6,y6);

In this way, we were able to obtain a significant reduction in the complexity of this calculation. Another advantage is that we don’t have to remember Pythagoras’s formula and try to get it right numerous times; instead, we simply need to call the Distance method.

Note

By implementing a class called Location to represent specific locations in the form of objects, naming these location objects L1, L2, and so on will reduce the previous statement to

TotalDistance =

Distance(L1,L2) + Distance(L2,L3) +

Distance(L3,L4) + Distance(L4,L5) +

Distance(L5,L6);

Indeed, this is a much simpler and self-documenting statement. To understand and construct this type of statement, we need to put more meat into your understanding for methods and OOP.

If none of our other objects in the program are interested in a Distance method, we need to make things less complex when looking at the class from the outside. As a result, we declare this helper method to be private.

108 C# PRIMER PLUS

As we attempt to reduce the complexity of the individual class by breaking its complicated tasks into subtasks, we also create the need for private methods.

Tip

A method attempting to solve several tasks is likely to be overly complex and should probably be broken down into smaller, simpler methods. So don’t be afraid of creating many small methods.

A method that accomplishes one clear task is said to be cohesive.

A good guideline for whether you have created a set of cohesive methods is the ease with which you can name each method. Methods with one distinct task are easier to name than multipurpose methods.

Summary

This chapter presented you with another C# source code example with the ability to perform simple calculations. Many essential constructs and concepts were extracted from this program to extend the knowledge you gained from the previous chapter.

The following are the important elements covered in this chapter:

A variable of type int can be used to store whole numbers and can take part in standard arithmetic calculations.

Namespaces help programmers keep their classes organized and accessible to other programmers for reuse purposes.

The System namespace in the .NET Framework class library contains many fundamental classes.

Use comments to describe the overall intent of the source code instead of merely restating what the code does.

A string value consisting of digits that form a whole number can be converted to a value of type int. Conversely, a value of type int can also be converted to a value of type string.

A method is defined by writing its method header (which includes access modifier, return type, name and formal parameters), by indicating its method body with {} and by writing the statements of the method inside the method body.

A method call must include the name of the called method and an argument list that matches the formal parameter list of the called method. When a method is called, the values held by the arguments are assigned to the formal parameters of the called method. A method can return a value, in which case, the method call can be regarded as holding this value just after the method called returns.

When positioned between two numeric values, the + operator will perform a standard arithmetic addition but, if positioned between two strings, will perform a string concatenation.