התוכנית
להלן רשימת התוכנית המלאה.
זהו פתרון OOD של Java ל"מקרה מבחן של פתרון בעיה" בעמוד 152 של
Turbo Pascal, Fourth Edition, by Nell Dale & Chip Weems.
התוכנית מובאת על מנת להמחיש את הניגוד במבנה של שתי גירסאות של תוכנית זהה:
אחת שנבנתה בהתאם למתודולוגיית תֶכֶן top-down, ואחרת שנבנתה בהתאם למתודולוגיית תֶכֶן מונחה-עצמים.
להלן ניסוח של תיאור הבעיה:
אתה עוסק בבניית עצמית של מסגרות לתמונות. עבור גודל נתון של ציור, עליך לקבוע כמה עץ לקנות עבור המסגרת, את גודל הבד שתרכוש, ואת עלות החומרים. כתוב תוכנית שתבצע את המשימה תוך שימוש במתודולוגיית OOD .
קלט:
אורך ורוחב הציור
עלות העץ בדולר לאינטש
עלות הבד בדולר לרגל
/*File Ood03.java Copyright 1997, R.G.Baldwin This is a Java object-oriented solution to the Problem- Solving Case Study on page 152 of Turbo Pascal, Fourth Edition by Nell Dale and Chip Weems. This sample program is being provided to contrast the structure of two different versions of the program: one designed according to Top-Down Design methodology as provided in the book, and the other designed according to Object-Oriented Design methodology. The description of the problem is paraphrased below: You are learning to make your own painting frames by stretching the canvas over a wooden frame and tacking it to the back of the frame. For a given size of painting, you must determine how much wood to buy for the frame, how large a piece of canvas to purchase, and the cost of the materials. Write a program using OOD methodology that will perform that task. Input: Length and width of the painting, Cost per inch for the wood, and Cost per square foot for the canvas. Output: Prompting messages, Echo of input data, Amount of wood to buy in inches, Dimensions of the canvas in inches, Cost of the wood in dollars, Cost of the canvas in dollars, and Total cost of the materials in dollars. Givens: The required length of the wood to build a frame is twice the sum of the width and the length of the painting assuming no waste. The size of the canvas must be 5 inches greater than the size of the painting in both dimensions in order to allow for wrapping and tacking of the canvas to the wooden frame. The user will provide proper input data so that no error checking on input is required. Solution: The controlling class for the program is named Ood03. It is designed to run as a Java application which means that it requires a main method. An instance of the controlling class is analogous to a painting. Discussion: The required classes, objects, and instance variables were discovered by analyzing the nouns in the description of the problem.. The required methods were discovered by analyzing the verbs and the output requirements in the description of the problem. Required classes, objects, and instance variables: The nouns that were selected to represent classes (and objects) were: Painting Canvas WoodenFrame. The nouns that were selected to represent instance variables (instance objects) of the Painting class were: Canvas WoodenFrame. The nouns that were selected to represent instance variables of the Canvas class were: Margin (the folding margin) Length (the length of the painting) Width (the width of the painting) Cost Per Sq Ft (the cost of the canvas material) The nouns that were selected to represent instance variables of the WoodenFrame class were: Length (the length of the painting) Width (the width of the painting) Cost Per Inch (the cost of the wood) Required methods: The verbs and other aspects of the description of the problem suggested that the Painting class should have the following methods including the main method required by all Java applications: main() getInput() showOutput() getTotalMaterialCost() Note that the Painting class is actually represented by the controlling class which, for disk storage reasons, is named Ood03 instead of Painting. The verbs and other aspects of the description of the problem suggested that the Canvas class should have the following mutator methods: setLength(double length) setWidth(double width) setCostPerSqFt(double costPerSqFt) The description of the problem suggested that the Canvas class should have the following accessor methods: getTotalLength() getTotalWidth() getTotalCost() The verbs and other aspects of the description of the problem suggested that the WoodenFrame class should have the following mutator methods: setLength(double length) setWidth(double width) setCostPerInch(double costPerInch) The description of the problem suggested that the WoodenFrame class should have the following accessor methods: getTotalLengthToBuy() getTotalCost() Relationships among classes and objects: The description of the problem suggested the following relationships among objects instantiated from the classes Ood03, Canvas, and WoodenFrame: Each object of type Ood03 (Painting) contains one Canvas object and one WoodenFrame object. This is a has-a relationship. (A painting has-a Canvas and a painting has-a WoodenFrame.) Behavior of Objects: The behavior of each of the objects of the Canvas, and WoodenFrame classes consists primarily of mutation and access. Mutator methods are used to store information in the instance variables of the objects. Accessor methods are used to calculate and return higher-level representations of the instance variables such as total cost. The behavior of an object of the Ood03 class requires Getting input data from the user, Sending messages to the Canvas and WoodenFrame objects asking them to change their state and store the information obtained from the user, Sending messages to the Canvas and WoodenFrame objects asking them to calculate and return information in the form of higher-level representations of the data stored in their instance variables (such as total cost), and Displaying data provided by those objects for the benefit of the user. The program was tested using JDK 1.1.3 running under Win95. **********************************************************/ import java.io.*; import java.util.*; //=======================================================// public class Ood03{//controlling class //This class represents a painting. It has a WoodenFrame // object and it has a Canvas object, each represented // by an instance variable. It can get user input to // establish its own size in order to pass that // information along to the WoodenFrame object and the // Canvas object. It can display all the important // attributes about itself, including the total cost // of materials required for one instance of itself. //Instance variables private Canvas canvas = new Canvas(); private WoodenFrame woodenFrame = new WoodenFrame(); //-----------------------------------------------------// //Methods //-----------------------------------------------------// //All Java applications require a main method in the // controlling class. public static void main(String[] args){ //Instantiate a new painting object. Ood03 painting = new Ood03(); //Get size information about the painting and unit // cost information for the materials required to // assemble the frame and canvas for the painting. painting.getInput(); //Display information on total material requirements // and total cost. painting.showOutput(); }//end main //-----------------------------------------------------// private void getInput(){ //This method is used to obtain information about the // size of the painting and the unit cost for required // materials. //Prepare to use the class that supports keyboard input EasyIn easy = new EasyIn(); double temp;//temporary double variable //Display a prompt to the user. System.out.println( "Enter length of painting in inches"); //Get the length of the painting from the user. temp = easy.readDouble(); //Send a message to the Canvas object telling it to // change its state to include the length of the // painting. canvas.setLength(temp); //Send a message to the WoodenFrame object telling it // to change its state to include the length of the // painting. woodenFrame.setLength(temp); //Continue getting input information and sending // messages to the Canvas object and the WoodenFrame // object telling them to change their state to // include the new information. System.out.println( "Enter width of painting in inches"); temp = easy.readDouble(); canvas.setWidth(temp); woodenFrame.setWidth(temp); System.out.println("Enter cost per inch for wood"); temp = easy.readDouble(); woodenFrame.setCostPerInch(temp); System.out.println("Enter cost per sq ft for canvas"); temp = easy.readDouble(); canvas.setCostPerSqFt(temp); }//end getInput() //-----------------------------------------------------// private void showOutput(){ //This method, and the method called by this method // named getTotalMaterialCost are used to obtain // information from the Canvas object and the // WoodenFrame object regarding their material // requirements and the cost of that material. The // information so obtained is displayed for the benefit // of the user. //Send a message to the WoodenFrame object asking it // to report on the amount of wood that needs to be // purchased. Display this information for the // benefit of the user. System.out.println("Length of wood to buy is: " + woodenFrame.getTotalLengthToBuy() + " inches"); //Continue sending messages to the WoodenFrame and // Canvas objects asking them to report on some aspect // of their state. Display the information so obtained // for the benefit of the user. System.out.println("Total length of canvas:" + canvas.getTotalLength() + " inches"); System.out.println( "Total width of canvas: " + canvas.getTotalWidth() + " inches"); System.out.println("Total cost of wood is: " + woodenFrame.getTotalCost()); System.out.println("Total cost of canvas: " + canvas.getTotalCost() + " dollars"); //Here, the painting object sends a message to itself // asking itself to report on the total material cost. // This message causes a method to be invoked which // sends messages to the WoodenFrame and Canvas // objects asking them to report on their individual // total costs. The method returns the sum of the // individual costs as the total cost for the project. // The total cost is displayed for the benefit of // the user. System.out.println("Total cost: " + this.getTotalMaterialCost() + " dollars"); }//end showOutput() //-----------------------------------------------------// private double getTotalMaterialCost(){ //Send messages to the WoodenFrame and Canvas objects // asking them to return their total costs. Add these // individual costs and return them as the total // material cost for the project. return (canvas.getTotalCost() + woodenFrame.getTotalCost()); }//end getTotalMaterialCost() //-----------------------------------------------------// }//end class Ood03 //=======================================================// class Canvas{ //This class represents the material used to cover the // wooden frame for a painting. It has length, width, // cost-per-square-foot, and binding margin attributes. // Each of these is represented by an instance // variable. //It uses mutator methods to set the values of the // instance variables. //It does not provide field accessors by which the // values of the instance variables can be read. // However, it knows how to calculate the total material // cost for one instance of itself, and provides // accessors by which higher-level representations of // the instance variables can be obtained: total length, // total width, and total cost. //Instance variables private final double margin = 5.0; private double length; //length of the painting private double width; //width of the painting private double costPerSqFt; //cost of the canvas //-----------------------------------------------------// //Mutator Methods //-----------------------------------------------------// public void setLength(double length){ this.length = length; }//end setLength() //-----------------------------------------------------// public void setWidth(double width){ this.width = width; }//end setWidth() //-----------------------------------------------------// public void setCostPerSqFt(double costPerSqFt){ this.costPerSqFt = costPerSqFt; }//end setCostPerSqFt() //-----------------------------------------------------// //Accessor Methods //-----------------------------------------------------// public double getTotalLength(){ //Total length is the length of the painting plus // the binding margin required to fold the canvas // under the frame and staple it. return (length + margin); }//end getTotalLength() //-----------------------------------------------------// //Total width is as described above. public double getTotalWidth(){ return (width + margin); }//end getTotalWidth() //-----------------------------------------------------// public double getTotalCost(){ return ( (((length+margin) * (width+margin))*costPerSqFt)/144); }//end getTotalCost() //-----------------------------------------------------// }//end class Canvas //=======================================================// class WoodenFrame{ //This class represents the wooden frame that is covered // with canvas for a painting. It has length, width, // and cost-per-inch attributes which are stored in // instance variables. //It uses mutator methods to set the values of the // instance variables. //It does not provide field accessors by which the // values of the instance variables can be read. // However, it knows how to calculate the total material // cost for one instance of itself, and provides // accessors by which higher-level representations of // the instance variables can be obtained: total length // of wood required and total cost. //Instance variables private double length; //of the painting private double width; //of the painting private double costPerInch; //for the wood //-----------------------------------------------------// //Mutator Methods //-----------------------------------------------------// public void setLength(double length){ this.length = length; }//end setLength() //-----------------------------------------------------// public void setWidth(double width){ this.width = width; }//end setWidth() //-----------------------------------------------------// public void setCostPerInch(double costPerInch){ this.costPerInch = costPerInch; }//end setCostPerInch() //-----------------------------------------------------// //Accessor Methods //-----------------------------------------------------// public double getTotalLengthToBuy(){ //The total length of the wood required to build the // frame is twice the sum of the length and the width // of the painting. return (2*(length + width)); }//end getTotalLengthToBuy() //-----------------------------------------------------// public double getTotalCost(){ //The total cost of the wood is the product of the // total length of the wood in inches and the cost // per inch. return ((2*(length + width))*costPerInch); }//end getTotalCost() //-----------------------------------------------------// }//end class WoodenFrame //=======================================================// //Note this is a general purpose class that is used to // service input from the keyboard and was not designed // for this specific program. Rather, it was taken, with // permission by the author, from the book listed below. // Simple input from the keyboard for all primitive types. // Copyright (c) Peter van der Linden, May 5 1997. // Feel free to use this in your programs, as long as this // comment stays intact. // // This is not thread safe, not high performance, and // doesn't service EOF. // It's intended for low-volume easy keyboard input. // An example of use is: // EasyIn easy = new EasyIn(); // int i = easy.readInt(); // reads an int from System.in // See Just Java and Beyond, Third Edition by Peter // van der Linden class EasyIn { static InputStreamReader is = new InputStreamReader( System.in ); static BufferedReader br = new BufferedReader( is ); StringTokenizer st; StringTokenizer getToken() throws IOException { String s = br.readLine(); return new StringTokenizer(s); }//end getToken() boolean readBoolean() { try { st = getToken(); return new Boolean(st.nextToken()).booleanValue(); }catch (IOException ioe) { System.err.println( "IO Exception in EasyIn.readBoolean"); return false; }//end catch }//end readBoolean() byte readByte(){ try { st = getToken(); return Byte.parseByte(st.nextToken()); }catch (IOException ioe) { System.err.println( "IO Exception in EasyIn.readByte"); return 0; }//end catch }//end readByte() short readShort(){ try { st = getToken(); return Short.parseShort(st.nextToken()); }catch (IOException ioe) { System.err.println( "IO Exception in EasyIn.readShort"); return 0; }//end catch }//end readShort() int readInt(){ try { st = getToken(); return Integer.parseInt(st.nextToken()); }catch (IOException ioe) { System.err.println( "IO Exception in EasyIn.readInt"); return 0; }//end catch }//end readInt() long readLong(){ try { st = getToken(); return Long.parseLong(st.nextToken()); }catch (IOException ioe) { System.err.println( "IO Exception in EasyIn.readFloat"); return 0L; }//end catch }//end readLong() float readFloat() { try { st = getToken(); return new Float(st.nextToken()).floatValue(); }catch (IOException ioe) { System.err.println( "IO Exception in EasyIn.readFloat"); return 0.0F; }//end catch }//end readFloat() double readDouble() { try { st = getToken(); return new Double(st.nextToken()).doubleValue(); }catch (IOException ioe) { System.err.println( "IO Exception in EasyIn.readDouble"); return 0.0; }//end catch }//end readDouble() char readChar() { try { String s = br.readLine(); return s.charAt(0); }catch (IOException ioe) { System.err.println( "IO Exception in EasyIn.readChar"); return 0; }//end catch }//end readChar() String readString() { try { return br.readLine(); }catch (IOException ioe) { System.err.println( "IO Exception in EasyIn.readString"); return ""; }//end catch }//end readString }//end class definition //=======================================================// |
התוכנית נבדקה תוך שימוש ב‑1.1.3 JDK שרץ תחת Win95.