computer science 209 the strategy pattern i: comparisons and layouts
TRANSCRIPT
Computer Science 209
The Strategy Pattern I:
Comparisons and Layouts
The Context of the Strategy Pattern
• I want to supply an algorithm or set of algorithms to be run in the context of a server’s class
• Example: I want to sort elements in a list according to several different fields (title, author, ISBN, etc.)
Solution of the Strategy Pattern
• I implement an interface whose methods specify the algorithms I want to be run in the server’s class
• The server provides one or more methods that accept parameters of my interface type
• The server runs the algorithms in that interface by running the appropriate methods on the parameter objects that I have passed to it
Example: Comparator
• I supply a comparison algorithm for a distinct ordering of elements by– Creating a class that implements Comparator– Implementing the compare method– Passing an instance of that class to the server
• The server, such as Collections.sort, applies my algorithm by running my object’s compare method with the collection’s elements
Distinct Responsibilities<<Interface>>Comparator
a Comparatorobject
<<Interface>>List
a Listobject
Collections.sort(aList, aComparator)
The sort method implements the sorting strategy
The Comparator object implements the comparison strategy in the method Compare
Comparable and compareTopublic interface Comparable<T>{
// Returns 0 if receiver equals other // Returns < 0 if receiver is less than other // Returns > 0 if receiver is greater than other public int compareTo(T other);}
public class Student implements Comparable<Student>{
public int compareTo(Student other){ return name.compareTo(other.name); }}
Students are by default used in contexts wherein they are ordered by name.
Multiple Orderings
• A client might ask for a list of students sorted by average grade or another list of students sorted by highest grade
• compareTo provides just one, default ordering
• Use a Comparator<T> object other orderings
Using a Comparator
public static <T> void sort(List<T> list, Comparator<? super T> c)
A second Collections.sort method expects an object whose class implements the Comparator<T> interface.
The sort method uses the comparator object’s compare method to sort the list.
Using a ComparatorList<Student> list = new ArrayList<Student>();
Student s1 = new Student("Ken", 4);Student s2 = new Student("Simon", 4);
list.add(s1);list.add(s2);
Collections.sort(list, new ComparatorByHighScore());
Collections.sort(list, new ComparatorByAverageScore());
Each comparator object specifies a distinct ordering for comparisons.
public interface Comparator<T>{
// Returns 0 if obj1 equals obj2 // Returns < 0 if obj1 is less than obj2 // Returns > 0 if obj1 is greater than obj2 public int compare(T obj1, T obj2);}
import java.util.Comparator;
public class ComparatorByHighScore implements Comparator<Student>{
public int compare(Student s1, Student s2){ return s1.getHighScore() - s2.getHighScore(); }}
Comparator<T> and compare
Comparator<T> and comparepublic interface Comparator<T>{
// Returns 0 if obj1 equals obj2 // Returns < 0 if obj1 is less than obj2 // Returns > 0 if obj1 is greater than obj2 public int compare(T obj1, T obj2);}
import java.util.Comparator;
public class ComparatorByAverageScore implements Comparator<Student>{
public int compare(Student s1, Student s2){ return s1.getAverage() - s2.getAverage(); }}
Using Comparators
• We need a new comparator class for each new possible ordering
• We might need to use each comparator just once in our code
• Lots of new named classes add clutter to our system
Anonymous Classes
• An anonymous class is a class without a name
• It’s usually defined at the point where it’s instantiated
• An anonymous class is like inline code – it’s written at the place where it needs to be used and there is just one such place
Format for Creating an Anonymous Class
new <interface name> (){
<implementations of methods required by the interface>
}
Creates an instance of an anonymous class that can be used wherever an object of the interface type is expected.
Example: Compare by AverageComparator<Student> comp1 = new Comparator<Student>(){ public int compare(Student s1, Student s2){ return s1.getAverage() - s2.getAverage(); }};
Collections.sort(list, comp1);
Create the comparator and assign it to a variable.
Then use the variable/comparator to sort the list.
Example: Compare by TitleCollections.sort(list, new Comparator<Student>(){ public int compare(Student s1, Student s2){ return s1.getAverage() - s2.getAverage(); }});
You don’t even need the extra variable.
Just create the comparator when it’s needed.
Components, Containers, and Layouts
• Some GUI components are primitives, such as buttons and fields
• Others are containers in which components can be placed, such as frames and panels (panels can be nested recursively)
• The manner of organizing components can vary with the container and with the application
Layout Managers
• Components are added to a container under the influence of a layout manager
• The default layout manager for frames and dialogs is BorderLayout
• The default layout manager for panels and applets is FlowLayout
The Layout Strategy
• The different layout managers implement the LayoutManager interface
• A container calls methods in this interface to lay out the components
• The user of the container supplies an instance of this interface for a particular type of layout
• Strategy pattern!
Common Layouts
FlowLayout Wrap around effect
BorderLayout 5 distinct areas
GridLayout Two-dimensional grid of equal-sized areas
GridBagLayout Allows stretching of cells across rows and columns
Grid Layouts
public GridExample(){ Container c = getContentPane(); c.setLayout(new GridLayout(2, 2)); c.add(new JButton("One")); c.add(new JButton("Two")); c.add(new JButton("Three")); c.add(new JButton("Four"));}
Cells are filled in row major order
Components stretch to fill their cells