Page 393 - Introduction to Programming with Java: A Problem Solving Approach
P. 393

                9.7 Problem Solving with Class Members and Instance Members in a Linked List Class (Optional) 359
method with an addValue instance method, and the getAllPennies class method with getAllValues class method. When you do this, ask yourself if there might be a better way to allocate the work done by these methods.
Since you have turned the passive penny jars into active human agents, you should ask yourself, “Where is the time-to-spend decision made?” This high-level decision should be made in the driver. So as you tran- sition from the PennyJar program to the FundRaiser program, you need to switch the location of the final spending decisions. That means the GOAL constant should be moved up to the FundRaiser class.
Similarly, you should ask yourself, “Where are the decisions made about individual contributions?” Are they made at the level of the manager in the FundRaiser class, or are they made at the level of individual agents in the Agent class? The donors talk to individual agents, so that information should enter the program through an Agent method, probably the addValue method. Since individual contribution deci- sions are now decentralized, you should coordinate efforts from the top. You should plan to conduct a se- quence of centrally directed publicity campaigns. To carry out each campaign, you should define another class method—addAllValues. In an attempt to get multiple donation pledges, the addAllValues method loops through all of the agents and has each agent call addValue. After each campaign, call the getAllValues class method to see if the total value exceeds the GOAL. If it does, print the total value and quit.
 Use a linked list to access all objects from one point.
In a real fund raiser, you can’t predict how many donors you’ll have. Likewise, in the FundRaiser program, you want to be able to handle an unknown number of donor agents. The trick is to set things up like a “treasure hunt”—a trip in which each intermediate des- tination gives you the next destination. Each agent tells you where the next agent is, until you get the last agent, who tells you that’s all.
         YouA’llpuasegthois stPratDegyFforEthnehgeatAnllcVealrues method as well as for the addAllValues method. Instead of just reading a previously accumulated value from a class variable like allPennies, the getAllValues method will accumulate values from individual agents. This avoids data duplication and eliminates the need for an allValues class variable. It also frees each individual agent from the task of adding the current contribution to an allValues variable in addition to adding it to its own value.
The Agent class still needs one class variable, however—a reference variable that tells class methods where to start their trips. We’ll call this one class reference variable listOfAgents. This variable always contains a reference to the first object to visit. Each object contains an instance reference variable called nextAgent, which refers to the next object to visit. In the last object in the list, the nextAgent reference variable contains null. This says the trip is done. This structure is called a linked list, and the single class reference variable, listOfAgents, points to the object at the head of the list.
Initially, there are no objects in the list, and the value in the listOfAgents variable is null. The constructor for each new Agent object inserts that object at the head of the Agent class’s linked list, using this algorithm:
set this agent’s nextAgent to listOfAgents set listOfAgents to this agent
This means that the first object visited in a trip through all the objects is the last object constructed, and the last object visited is the first object constructed. In other words, the visitation sequence is opposite to the construction sequence.
Figure 9.7 shows a UML class diagram for the program. As usual, the driver class (FundRaiser) has a main method. It also has a class constant, GOAL, which establishes the stopping criterion. The Agent class has a constructor, two public class methods (getAllValues and addAllValues), and two private instance methods (getValue and addValue). Notice that the two public class methods























































































   391   392   393   394   395