1.07k likes | 1.16k Views
FIND THE “ comp ” IN EACH OF THESE TEXTS. alkdfjasdkasldkfjasdlkfjasdkfajsldfkajsldkfjalsdkfjadlfjkdffddfdfasldkfajsdlkfjasldkfjalsdkfjasldfjasldkfjasldkfjaldskjfalsdkjfalskdjfalskdjfalskdjfalksdjfwioer comp uqkeflaksdjfasldkfjasldkfjaslkdjfaiowejrwqeijrqwoejrqoiejfalskdfjaslkdfja.
E N D
FIND THE “comp” IN EACH OF THESE TEXTS alkdfjasdkasldkfjasdlkfjasdkfajsldfkajsldkfjalsdkfjadlfjkdffddfdfasldkfajsdlkfjasldkfjalsdkfjasldfjasldkfjasldkfjaldskjfalsdkjfalskdjfalskdjfalskdjfalksdjfwioercompuqkeflaksdjfasldkfjasldkfjaslkdjfaiowejrwqeijrqwoejrqoiejfalskdfjaslkdfja asdfasldkjfalsdfasdlkfjasdlfksdlfkjcompflsadf HARD EASY ` This parallels debugging.
Importance of Incremental Coding Incremental coding is the practice of testing small portions of your code as you are writing them. Much easierto find bugs with less code to work with at any one time. • You will know exactly when your code stops working as intended. • The TAs will be much happier at hours. • The TAs will not help students track down extremely convoluted bugs that are a result of coding large portions without testing.
Importance of Incremental Coding For more information, see Lab2 (UMLet and Debugging part 1) LiteBrite example: Get Palette and Grid to show up. Test. Try to add colors to the Palette. Test. Get a Lite to show up when you click in the right spot. Test. Finally, get a Lite to show up in the right spot with the right color. TEST. The bulk of time “coding” is actually spent debugging Code and debug incrementally
Debugging! Printlns vs. Debugger Printlines: • When you want to quickly review a history of state changes, e.g., track one or two variables, or flow-of-control • useful when no exception is thrown Eclipse Debugger: • Already have a bunch of printlines cluttering console • You're getting exceptions / infinite loops and don't want to have to force-exit the program with the stop button • You have multiple conditionals, event handlers/listeners, etc., and want to quickly and conveniently check which ones are getting hit • You want to track multiple variables but only note their values once or twice
Generics! (1/3) • Generics allow us to write a collection class A to hold instances of another class B, without regard for what that class B is public ArrayList<ElementType> ()
Generics! (2/3) • Programmers use “generics” to implement a collection class without knowing what specific type of object the user (another programmer) of that collection will want to store • example: Java’s ArrayList’s class file defines an array list of ElementTypes left unspecified, but when users of the ArrayList actually declare and instantiate one, the type must be fully specified (e.g., an ArrayList of Plastics to serve Regina), much the way arrays need types • Java replaces ElementType with Plastics in return types and parameters of any ArrayList method you want to use • but you must keep the literal < > brackets wherever they are used to indicate use of generics!
Generics! (3/3) • Generics allow for generality of using any type while still having compiler do type checking • Think of the “generic” as a specialization of the type ArrayList
java.util.ArrayListMethods (1/5) //Note: only most important methods are shown; see JavaDocs for //full class //Note: literal use of < and > //one of the many constructors for ArrayList class - specialize //it by providing ElementType, just as Array has the type it //stores. Note: < and > are literal - think of them as “of type” public ArrayList<ElementType>() • //returns the object of type ElementType • public ElementType get(int index)
java.util.ArrayListMethods (2/5) //inserts the specified element at the specified position in //this ArrayList public void add(int index, ElementType element) //inserts specified element at end of ArrayList public boolean add(ElementType element) //removes the ElementType at given index public ElementType remove(int index) //returns number of elements stored in ArrayList public int size() //returns true if the ArrayList contains zero elements; false //otherwise public boolean is Empty()
java.util.ArrayListMethods (3/5) • ArrayLists also have methods which access elements by searching (as opposed to using an index) • these methods take a parameter of type Object (superclass from which all Java classes inherit) • But you should never pass in (or get back) anything except an ElementType - using polymorphism here not for generality but to get compile-time type checking
java.util.ArrayListMethods (4/5) //finds first occurrence of specified element public int indexOf(Object elem) //return true if ArrayList contains specified element public boolean contains(Object elem) //remove first occurrence of specified element //if the element isn’t in the ArrayList, returns false and ArrayList remains unmodified public boolean remove(Object elem)
java.util.ArrayListMethods (5/5) • Some other ArrayList notes… • can add object at particular slot or at end • can retrieve an object stored at a particular index and perform operations on it • can use for loop to access all objects in ArrayList • shifting elements in memory for adding/deleting from an ArrayList is done automagically by Java!
Summary of ArrayLists (1/2) • More flexible than arrays for insertion/deletion • dynamically shifting elements and adjusting size in response to insert/delete done automagically • full class with useful methods, eg., • get(int index), add(ElementType element) • add(int index, ElementType element) • indexOf(ElementType elem) //search • remove (int index), size(), isEmpty()
Summary of ArrayLists (2/2) • Can hold a heterogeneous collection of any kind of Object; want homogeneous collections… • So specialize the ArrayList type by adding a “generic” specification to a declaration or instantiation, thereby specifying two classes in one statement: the collection and the type of object it is to hold and return • implementer of ArrayList collection declares constructor with <ElementType> as placeholder public ArrayList<ElementType> (); • user of ArrayList “fills in” ElementType private ArrayList<Plastic> _plastics; … _plastics = new ArrayList<Plastic>(); • Be sure to use literal < > for specialized type!
Example (1/5) public class PlasticsCollection{ /* To declare ArrayList, must specify type of object ArrayList stores. Replace all occurrences of ElementType with Plastic, including where ElementType occurs in literal <> brackets. Could extend ArrayList, but it goes against good design. */ private ArrayList<Plastic> _plastics; public PlasticsCollection(){ // ArrayList initialization - note literal <> _plastics = new ArrayList<Plastic>(); for (int i=0; i<3; i++){ //Add a Plastic at each pass _plastics.add(new Plastic()); } } // class definition continued on next slide
Example(2/5) //Adds a new Plastic at the end public void addPlastic(Plastic plastic){ _plastics.add(plastic); } // If the specified Plastic is in the collection, remove and banish her public void banishPlastic(Plastic plastic){ if (_plastics.contains(plastic)){ _plastics.remove(plastic); } } } //End of Class
Example(3/5) • <Plastic> indicates use of Java generics • now, only Plastic instances can be stored and retrieved from this ArrayList • In PlasticCollection’s constructor, adding a new Plastic works: • _plastics.add(new Plastic()); • However, adding another type to the ArrayList of Plastics won’t work: • _plastics.add(new String(“Yeah!”)); • // Won’t work… parameters needs to be of type Plastic • Exception thrown! • “The method add(Plastic) in the type ArrayList<Plastic> is not applicable for the arguments (String)”
Example(4/5) public class Regina{ private PlasticCollection _plastics; private Plastic _betrayer; public Regina(PlasticCollection plastics, Plastic betrayer){ _plastics = plastics; _betrayer = betrayer; } // Method to act like a queen bee public void ruinLives(Plastic plastic){ this.wearPink(); // method def elided plastic.obey(this) // method def elided this.spreadRumors(); // method def elided } // Method to destroy anyone who betrays her public void banishBetrayer(){ this.distributeBurnBook(); _plastics.banishPlastic(_betrayer); } }
Example(5/5) public class MeanGirls{ private PlasticCollection _plastics; private Regina _regina; public MeanGirls(){ _plastics = new PlasticCollection(); Plastic cady = new Plastic("Cady"); _plastics.add(cady); _regina = new Regina(_plastics, cady); • } // End of constructor public void haveBoringDay(){ regina.doCarCommercial(); regina.goShopping(); } public void haveExcitingDay(){ Plastic karen = new Plastic("Karen"); regina.ruinLives(karen); regina.banishBetrayer(); } } // End of class
Enhanced forLoop (1/2) • Remember for loops from last lecture? • Basic for loop was extended in Java 5 to make iteration over arrays and other collections easier • commonly called for-each or for-in loop • <> here NOT literal, i.e., not for generics • for (<type> <var>: <structure>){ • <loop body> • } • <type>: class of objects stores in the <structure> • <var>: name of the loop counter • <structure>: data structure (array or collection) you’d like to iterate over
Enhanced forLoop (2/2) • Intended to simplify most common form of iteration, when, as name suggests, loop body is applied to each and every member of the collection • But, how do for-each loop and for loop differ? • in a for loop, have access to index at which an item is stored in an array or collection (and hence item itself) • in a for-each loop, we don’t have direct access to the index, but can easily access item (see next example)
for-each vs. forloop (1/2) • Consider this for loop: • //Somewhere in the StudentCollection class • //note: _northShoreStudents is an ArrayList<NorthShoreStudent> • for (int i=0; i<_northShoreStudents.size(); i++){ • if (i % 2 == 0){ //if index ‘i’ is even • //apologize() is defined in NorthShoreStudent • _northShoreStudents.get(i).apologize(); • } • } • In the loop above, we only want to call apologize() on elements at even indices. A for-each loop would not be appropriate in this case. Why? Because we don’t execute apologize() on every element in the ArrayList; we only care about elements at specific indices.
for-each vs. forloop (2/2) • However, if we want to operate on every element in the ArrayList and the loop body does not require element indices, we may use a for-each loop: • //Instead of only even-numbered students, now everyone must apologize! • for (NorthShoreStudent student : _northShoreStudents){ • //notice how don't need to use index to get student from ArrayList • student.apologize(); • } • A great advantage of for-each loops is that they don’t give you ArrayIndexOutOfBoundsExceptions! Why? • Java does the indexing for you. And Java is never wrong!
package Demos.Mainline; //Dummy class to understand Mainline public class App{ public App(){ //constructor elided } //Standard mainline function public static void main(String[] argv){ System.out.println(argv[0]); System.out.println(argv[1]); new App(); } } Understanding Mainline (and optional params) • If we type this in a shell: java Demos.Mainline.App Hello CS15 • We get the output: Hello CS15 • In this example, if we did not pass two or more parameters to the mainline, we’d get an ArrayIndexOutOfBoundsException! • Why? Because array argv’s size is exactly equal to the number of parameters passed to the mainline • You won’t need to use mainline parameters in CS15, but we wanted you to know they exist. You will probably use them in CS32!
Lecture 13 Design Patterns
Overview • Design as trade-offs • Holder Pattern • Proxy Pattern • Delegation
Design in a Nutshell 1/3 • Up to now, focused on how to program • be appropriately lazy: re-use code and ideas • Design Patterns are proven solutions to common problems • used successfully before by others, refined by experience • generally language-independent - learn once, apply everywhere
Design in a Nutshell 2/3 • Increasingly we learn about good design • some designs are better than others • “better” means, for example: • more efficient in space or time required (traditional criteria) • more robust, maintainable/extensible • more reusable, understandable • these are central concerns of Software Engineering • discussed in detail in CSCI0320
Design in a Nutshell 3/3 • There are trade-offs to make everywhere • architect balances aesthetics, functionality, cost • mechanical engineer balances manufacturability, strength, maintainability, cost • Need to defend your trade-offs • no perfect solution, no exact rules • up to now, designs have been rather straight-forward
Designing Takes Experience 1/3 • Experiences is gained by: • doing, using, seeing examples (good and bad) • Rarely find the final design on first try • like writing: you always find a “better” way • we changed some design styles for this year’s CS15 • no one ever stops learning • you never stop practicing music, sports, ... • Malcolm Gladwell’s pop-psych 10,000 hour “rule”in “Outliers” (but a Princeton study disagrees…)
Designing Takes Experience 2/3 • CS15 provides you with supervised practice • typically, TAs have more experience designing than you • but they are still learning from CS15 and other classes • guide you towards “best” design, but there are many others - the larger/more complex the problem, the more choices
Designing Takes Experience 3/3 • But why is experience useful? • know what to do in certain circumstances • recognize problems you’ve solved before • can remember previous solutions and reuse them • i.e., recognizing programming patterns • As a jump-start, why not make a catalogue of good designs you could read and learn from?
Designing Pattern Bibles The two “bibles” of Design Patterns: • The Timeless Way of Building by Christopher Alexander (1979) • design patterns in architecture • Alexander’s patterns in architecture initiated the study of design patterns in software • Design Pattern by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994) (“gang of four”)
Reuse Designs Rather Than Redesign • Libraries are predefined classes you can reuse • components, like architect’s windows • examples: cs015.prj, java.awt, Demos.Cars • like components, no indication on how to use them in a program
Reuse Design Rather Than Redesign • Patterns are more general than libraries • specify some relationships between classes • one pattern may represent many interacting classes • general, so they must be applied to specific problem • no actual code re-use • Progression in abstraction/generality vs. code re-use, from concrete classes to abstract classes, to interfaces (no code-reuse, just contract for methods) to patterns (idea re-use) • Pattern name, abstract, and identify key aspects of a design’s structure
Reuse Rather Than Reinvent/Redesign Example Pattern • Name: Colonial Revival • Abstract: example of 18t-century architecture • Key Aspects: typically white or gray wood, facade shows symmetrically balanced windows centered on door, windows have double-hung sashes and panes
You’ve Already Seen Simple Patterns 1/4 • Constructors • Pattern Name: initialization • Abstract: way to ensure objects have proper internal state before use • Key Aspects: method that first calls super() (parent’s constructor) and then sets up instance’s own instance variables
You’ve Already Seen Simple Patterns 2/4 • Accessor/Mutator methods • Pattern Name: encapsulation • Abstract: keeps other objects from changing an object’s internal state improperly • Key Aspects: use public accessor and mutator methods as appropriate to interact with private or instance variables
You’ve Already Seen Simple Patterns 3/4 • Composite Objects • PatternName: containment • Abstract: models objects that are composed of other objects • Key Aspect: store components as instance variables, initialize them in the constructor through instantiation or association (via parameter passing) and provide access protection through encapsulation ** Note: Containment pattern uses initialization and encapsulation patterns
You’ve Already Seen Simple Patterns 4/4 • Painting • PatternName: delegation • Abstract: have a complex object perform an action by telling each other its components what to do (e.g., painting or moving themselves) • Key Aspect: writing all of the detailed code for each component would clutter the paint or move, etc. method of a complex object. Instead, delegate particulars of painting (or moving, etc.) to individual components
Example: Colorized App Specification: Create a frame with one pentagon, a row of three buttons, and a quit button. One button should be labeled “Red”, the second “Green”, and the third “Blue”. Clicking on a button should set the corresponding color to be the current color for drawing the pentagon: any time the user clicks on the pentagon after clicking a color button, the color of the pentagon should be set to the specified current color. The pentagon should be white by default.
Analyzing the New Specification • Some of this we already know how to do: • creating frames, colors, polygons, buttons • labelling buttons • What don’t we know? • how to model, or hold onto, the “current color” • what objects we must create ourselves vs. what we can take directlyfrom Swing • Let’s define a panel called MainPanel that will hold the shape and the buttons
More Graphical Containment • Let’s create a new graphical containment tree! • Use BorderLayoutfor MainPanel • Note that graphical and logical containment are usually similar, but slightly different (e.g., classes such as listeners and the holder [see slide 51] do not exist graphically) - See next slide for comparison
Graphical vs. Logical Containment Logical Graphical Note: The Colors we use in code technically are never instantiated (we use predefined static constants). So, for containment purposes, we consider them created the first time the Color appears in the code.
What Type of Buttons? 1/2 • We’ll start with buttons - this time for Red, Green and Blue colors • Show we use JButton or JRadioButton? • JButtons are used to perform one-time action • JRadioButtons are used to set semi-permanent choice (choice stays same until explicitly changed by pressing different JRadioButton); also enforce only one choice selected at a time via a ButtonGroup
What Type of Buttons? 2/2 • JRadioButtons are more appropriate for this situation (only want one color at a time for our pentagon) • Want to make a single generic class instead of multiple separate subclasses • each button has same behavior, but differs only in the actual color it sets
Modeling “Specified” Color • How do we model the concept of “specified” color? • i.e., how do we keep track of the last color clicked? • Challenge: Colors are immutable. Once created, a Colorinstance (not instance variable!) models the same color forever • JRadioButtons need to refer to an object instance which is mutable
Modeling “Specified” Color • Colorableis an interface for objects which have mutable color (cars, bouncing balls,...) • two methods: getColor() and setColor() • Remember when you had to think about a very similar problem for LiteBrite?
Modeling “Specified” Color • Solution: Define a mutable object (called ColorHolder) which implements Colorable and models concept of current color • more generic than in LiteBrite, where Palette had its own instance variable for the current color • allows us to “set” and “get” color in one place (our ColorHolder), instead of everywhere that has a color reference