• No results found

Summary of Reasons to Create a Routine

7.3 Good Routine Names

393

A good name for a routine clearly describes everything the routine does. Here

394

are guidelines for creating effective routine names.

395

Describe everything the routine does

396

In the routine’s name, describe all the outputs and side effects. If a routine

397

computes report totals and opens an output file, ComputeReportTotals() is not an 398

adequate name for the routine. ComputeReportTotalsAndOpenOutputFile() is an 399

adequate name but is too long and silly. If you have routines with side effects,

400

you’ll have many long, silly names, The cure is not to use less-descriptive

401

routine names; the cure is to program so that you cause things to happen directly

402

rather than with side effects.

403

Avoid meaningless or wishy-washy verbs

404

Some verbs are elastic, stretched to cover just about any meaning. Routine

405

names like HandleCalculation(), PerformServices(), ProcessInput(), and 406

DealWithOutput() don’t tell you what the routines do. At the most, these names 407

tell you that the routines have something to do with calculations, services, input,

408

and output. The exception would be when the verb “handle” was used in the

409

specific technical sense of handling an event.

410

Sometimes the only problem with a routine is that its name is wishy-washy; the

411

routine itself might actually be well designed. If HandleOutput() is replaced with 412

FormatAndPrintOutput(), you have a pretty good idea of what the routine does. 413

In other cases, the verb is vague because the operations performed by the routine

414

are vague. The routine suffers from a weakness of purpose, and the weak name is

415

a symptom. If that’s the case, the best solution is to restructure the routine and

416

any related routines so that they all have stronger purposes and stronger names

417

that accurately describe them.

418

Make names of routines as long as necessary

419

Research shows that the optimum average length for a variable name is 9 to 15

420

characters. Routines tend to be more complicated than variables, and good

421

names for them tend to be longer. Michael Rees of the University of

422

Southampton thinks that an average of 20 to 35 characters is a good nominal

423

length (Rees 1982). An average length of 15 to 20 characters is probably more

424

realistic, but clear names that happened to be longer would be fine.

425

CROSS-REFERENCE For

details on naming variables, see Chapter 11, “The Power of Variable Names.”

CROSS-REFERENCE For

details on creating good variable names, see Chapter 11, “The Power of Variable Names.”

To name a function, use a description of the return value

426

A function returns a value, and the function should be named for the value it

427

returns. For example, cos(), customerId.Next(), printer.IsReady(), and 428

pen.CurrentColor() are all good function names that indicate precisely what the 429

functions return.

430

To name a procedure, use a strong verb followed by an object

431

A procedure with functional cohesion usually performs an operation on an

432

object. The name should reflect what the procedure does, and an operation on an

433

object implies a verb-plus-object name. PrintDocument(), 434

CalcMonthlyRevenues(), CheckOrderlnfo(), and RepaginateDocument() are 435

samples of good procedure names.

436

In object-oriented languages, you don’t need to include the name of the object in

437

the procedure name because the object itself is included in the call. You invoke

438

routines with statements like document.Print(), orderInfo.Check(), and 439

monthlyRevenues.Calc(). Names like document.PrintDocument() are redundant 440

and can become inaccurate when they’re carried through to derived classes. If

441

Check is a class derived from Document, check.Print() seems clearly to be 442

printing a check, whereas check.PrintDocument() sounds like it might be 443

printing a checkbook register or monthly statement—but it doesn’t sound like

444

it’s printing a check.

445

Use opposites precisely

446

Using naming conventions for opposites helps consistency, which helps

447

readability. Opposite-pairs like first/last are commonly understood. Opposite- 448

pairs like FileOpen() and _lclose() (from the Windows 3.1 software developer’s 449

kit) are not symmetrical and are confusing. Here are some common opposites:

450 ● add/remove 451 ● begin/end 452 ● create/destroy 453 ● first/last 454 ● get/put 455 ● get/set 456 ● increment/decrement 457 ● insert/delete 458 ● lock/unlock 459 ● min/max 460 ● next/previous 461 CROSS-REFERENCE For

the distinction between procedures and functions, see Section 7.6, “Special Considerations in the Use of Functions” later in this chapter.

CROSS-REFERENCE For

a similar list of opposites in variable names, see “Common Opposites in Variable Names” in Section 11.1.

● old/new 462 ● open/close 463 ● show/hide 464 ● source/target 465 ● start/stop 466 ● up/down 467

Establish conventions for common operations

468

In some systems, it’s important to distinguish among different kinds of

469

operations. A naming convention is often the easiest and most reliable way of

470

indicating these distinctions.

471

The code on one of my projects assigned each object a unique identifier. We

472

neglected to establish a convention for naming the routines that would return the

473

object identifier, so we had routine names like these:

474 employee.id.Get() 475 dependent.GetId() 476 supervisor() 477 candidate.id() 478

The Employee class exposed its id object, which in turn exposed its Get() 479

routine. The Dependent class exposed a GetId() routine. The Supervisor class 480

made the id its default return value. The Candidate class made use of the fact 481

that the id object’s default return value was the id, and exposed the id object. By 482

the middle of the project, no one could remember which of these routines was

483

supposed to be used on which object, but by that time too much code had been

484

written to go back and make everything consistent. Consequently, every person

485

on the team had to devote an unnecessary amount of gray matter to remembering

486

the inconsequential detail of which syntax was used on which class to retrieve

487

the id. A naming convention for retrieving ids would have eliminated this 488

annoyance.

489