Beginning Programming All-in-One For Dummies. Wallace Wang
Чтение книги онлайн.
Читать онлайн книгу Beginning Programming All-in-One For Dummies - Wallace Wang страница 28
Modeling means making the parts of a program more intuitive. One of the reasons why assembly language is so hard to understand is because manipulating data in the processor’s registers has nothing to do with solving problems like adding two numbers together. Likewise, dividing a large program into smaller tasks, using structured programming, does nothing to help you understand the actual problem the program is trying to solve.
With modeling, you divide a problem into real-life objects. If you were writing a program to control a car, one object might be the steering mechanism, another object might be the braking mechanism, and a third object might be the electrical system. By making each part of a program (each object) model a real-life object, it can be far easier to understand the purposes of the different parts of a program and how they work together.
For example, suppose you had to write a program to land a rocket on the Moon. This is how you might write this program using structured programming:
Land a rocket on the Moon Launch rocket Guide rocket through space Find a landing area on the Moon Put rocket down on landing area
So far, structured programming seems logical, but what happens when you keep dividing tasks into smaller tasks? Just focusing on the Guide rocket through space
task, you might wind up with the following:
Guide rocket through space Get current coordinates Compare current coordinates with Moon coordinates Adjust direction
Dividing the Adjust direction
task into smaller tasks, you might get this:
Adjust direction Identify current speed and direction Determine angle needed to steer toward the Moon Fire thrusters to change the angle of the rocket
Notice that the deeper you keep dividing tasks, the more removed you get from knowing what the main purpose of the program may be. Just by looking at the task Identify current speed and direction
, you have no idea whether this task involves flying a rocket to the Moon, driving a car down a road, or controlling a walking robot to an electric outlet to recharge its batteries.
The more you divide a larger task into smaller tasks, the harder it can be to understand what problem you're even trying to solve. This gets even worse when you start writing actual program commands.
The two parts of most programs are the commands that tell the computer what to do and the data that the program manipulates. So, if you wrote a program to identify the current speed and direction of a rocket, the commands would tell the computer how to retrieve this information, and the speed and direction would be the actual data the program uses.
Essentially, program commands are separate from the data they manipulate. If one part of a program manipulates data incorrectly, the rest of the program winds up using that contaminated data and you, as the programmer, won’t know which part of the program screwed up the data. This is like sitting in a baseball game, ordering a hot dog from a vendor, and having six people pass your hot dog down to you. When you see fingerprints all over your hot dog, can you tell which person touched your food?
Isolating data
Object-oriented programming avoids the problem of not knowing the purpose of code by combining data and the commands that manipulate them into a single entity called (surprise!) an object. With a well-designed object-oriented program, each object models part of the real-life problem so it’s easier to understand the purpose of the code inside that object.
So, if you were designing a program to launch a rocket to the Moon, object-oriented programming would let you divide the program into objects. One object might be the rocket
, a second object might be the Moon
, and a third object might be the Earth
.
You can also divide a large object into smaller ones. So the rocket
object might be divided into an engine
object and a guidance
object. The engine
object could be further divided into a fuel pump
object, a nozzle
object, and a fuel tank
object.
Suppose you wrote a program to calculate a rocket's trajectory to the Moon, and the engineers suddenly designed the rocket with a more powerful engine? With object-oriented programming, you could just yank the engine
object out of your program, rewrite or replace it, and plug it back into the program again.
In structured programming, modifying the program to reflect a new rocket engine would mean finding the program commands that manipulate the data that represents the engine’s thrust, and then making sure that new data gets fed into the program at the proper location and still works with any other program commands that also handle that same data. (If the explanation in this paragraph sounded confusing and convoluted to you, that just shows you the less-than-intuitive problem of modifying a structured program versus an object-oriented program.)
Simplifying modifications
Besides organizing a large program into logical pieces, objects have another purpose: code reusability. In school, it was always easier to copy someone else’s homework than it was to do it yourself. Similarly, programmers find that it’s easier to copy and reuse somebody else’s program rather than write their own program from scratch.
In structured programming, you could divide a large program into subprograms and then store those subprograms in a separate file. Now you could copy that file to reuse those subprograms in another program.
Copying subprograms makes programming easier, but here are two problems:
What if you copy a subprogram and then later find an error in that subprogram? Now you have to fix that subprogram in every copy. If you made 17 copies of a subprogram, you’d have to fix the same error 17 times in 17 different copies of the same subprogram.
What if you wanted to modify and improve a subprogram? Suppose you find a subprogram that asks the user to type in a password of no more than 10 characters, but you want your program to allow users to type in passwords up to 25 characters. At this point, you could eitherWrite your own password-verifying subprogram from scratch (which would take time).Copy the existing subprogram and modify it (which would take much less time). It’s easier to make a copy of an existing subprogram and then modify the copy. Now you have two copies of (almost) the same subprogram, but uh-oh, suddenly you discover an error in the original subprogram. Once again, you have to correct this error in the original subprogram and also in the modified subprogram. If you made 20 different modifications to a subprogram, you would have the problem of not only correcting the error in every copy of the original subprogram, but also fixing that same error in all your modified versions of that original subprogram.
But after you modify a subprogram, will you remember which subprogram you copied and modified originally? Even worse, you could copy a subprogram and modify it, and then copy your modified subprogram and modify that copy. Do this several times and you’ll wind up with several slightly different versions of the same subprogram, but now you may not have any idea which subprogram you copied originally.
So, now if you find an error in the original subprogram, how can you find and fix that same error in any modified copies of that subprogram?