Presentation is loading. Please wait.

Presentation is loading. Please wait.

Multiple Inheritance & Factories Prasun Dewan Comp 114.

Similar presentations


Presentation on theme: "Multiple Inheritance & Factories Prasun Dewan Comp 114."— Presentation transcript:

1 Multiple Inheritance & Factories Prasun Dewan Comp 114

2 Topics Covered Multiple inheritance –Extending more than one type Factories –Class creating objects More on facades –Compose objects Can be used independently –We use them together here Factory methods –Abstract method instead of class

3 Problem A modification to the course problem. Want to gather statistics on how many times a user requested a course –How many times matchTitle() successfully matched a course

4 Course Interface package courseTree; public interface Course extends TreeNode { public String getTitle(); public String getDepartment(); public int getNumber(); public void init (String theTitle, String theDept); }

5 Logged Course Interface package courseTree; public interface LoggedCourse extends Course { public int getNumberOfQueries(); }

6 Course abstract class package courseTree; public abstract class ACourse implements Course { String title, dept; public ACourse (String theTitle, String theDept) { init (theTitle, theDept); } public ACourse () {} public void init (String theTitle, String theDept) { title = theTitle; dept = theDept; } public String getTitle() {return title;} public String getDepartment() {return dept;} public Course matchTitle(String theTitle) { if ( title.equals(theTitle))return this; elsereturn null; }

7 ALoggedCourse abstract class package courseTree; public abstract class ALoggedCourse extends ACourse implements LoggedCourse { int numberOfQueries = 0; public ALoggedCourse (String theTitle, String theDept) { super (theTitle, theDept); } public ALoggedCourse () { } public int getNumberOfQueries() { return numberOfQueries; } public Course matchTitle(String theTitle) { Course course = super.matchTitle(theTitle); if (course != null) numberOfQueries++; return course; }

8 Regular Course Interface package courseTree; public interface RegularCourse extends Course { public void init (String theTitle, String theDept, int theCourseNum); }

9 Logged Regular Course Interface package courseTree; public interface LoggedRegularCourse extends ??? { … }

10 Logged Regular Course Interface package courseTree; public interface LoggedRegularCourse extends LoggedCourse { public void init (String theTitle, String theDept, int theCourseNum); } package courseTree; public interface LoggedRegularCourse extends RegularCourse { public int getNumberOfQueries(); }

11 Duplication package courseTree; public interface LoggedRegularCourse extends LoggedCourse { public void init (String theTitle, String theDept, int theCourseNum); } package courseTree; public interface RegularCourse extends Course { public void init (String theTitle, String theDept, int theCourseNum); }

12 package courseTree; public interface LoggedRegularCourse extends RegularCourse { public int getNumberOfQueries(); } Duplication package courseTree; public interface LoggedCourse extends Course { public int getNumberOfQueries(); }

13 Single Interface Inheritance package courseTree; public interface LoggedRegularCourse extends LoggedCourse { public void init (String theTitle, String theDept, int theCourseNum); } public interface RegularCourse extends Course { public void init (String theTitle, String theDept, int theCourseNum); } public interface Course extends TreeNode { public String getTitle(); public String getDepartment(); public int getNumber(); public void init (String theTitle, String theDept); } public interface LoggedCourse extends Course { public int getNumberOfQueries(); } Course LoggedCourse RegularCourse LoggedRegularCourse

14 Alternative Single Inheritance package courseTree; public interface LoggedRegularCourse extends RegularCourse { public int getNumberOfQueries(); } public interface RegularCourse extends Course { public void init (String theTitle, String theDept, int theCourseNum); } public interface Course extends TreeNode { public String getTitle(); public String getDepartment(); public int getNumber(); public void init (String theTitle, String theDept); } public interface LoggedCourse extends Course { public int getNumberOfQueries(); } Course LoggedCourse RegularCourse LoggedRegularCourse

15 Multiple Interface Inheritance package courseTree; public interface LoggedRegularCourse extends LoggedCourse, RegularCourse{} package courseTree; public interface RegularCourse extends Course { public void init (String theTitle, String theDept, int theCourseNum); } package courseTree; public interface LoggedCourse extends Course { public int getNumberOfQueries(); } empty interface

16 Multiple Interface Inheritance public interface LoggedRegularCourse extends RegularCourse {} public interface RegularCourse extends Course { public void init (String theTitle, String theDept, int theCourseNum); } public interface Course extends TreeNode { public String getTitle(); public String getDepartment(); public int getNumber(); public void init (String theTitle, String theDept); } public interface LoggedCourse extends Course { public int getNumberOfQueries(); } Course LoggedCourse RegularCourse LoggedRegularCourse

17 Old Regular Course Class public class ARegularCourse extends ACourse implements RegularCourse { int courseNum ; public ARegularCourse (String theTitle, String theDept, int theCourseNum) { init (theTitle, theDept, theCourseNum); } public ARegularCourse () {} public void init (String theTitle, String theDept, int theCourseNum) { super.init (theTitle, theDept); courseNum = theCourseNum; } public int getNumber() { return courseNum; }

18 New Regular Course Class public class ALoggedRegularCourse extends ALoggedCourse implements LoggedRegularCourse { int courseNum ; public ALoggedRegularCourse (String theTitle, String theDept, int theCourseNum) { init (theTitle, theDept, theCourseNum); } public ALoggedRegularCourse () {} public void init (String theTitle, String theDept, int theCourseNum) { super.init (theTitle, theDept); courseNum = theCourseNum; } public int getNumber() { return courseNum; } Code duplication and not making sure ALoggedRegularCourse is a ARegularCourse!

19 Single Class Inheritance public interface LoggedRegularCourse extends ALoggedCourse { public int getNumber() {…}; public void init (String theTitle, String theDept, int theCourseNum) {…}; } public class ARegularCourse extends ACourse { public int getNumber() {…}; public void init (String theTitle, String theDept, int theCourseNum); } public class ACourse implements Course { public String getTitle() {…} public String getDepartment() {…}; public void init (String theTitle, String theDept) {…}; public Course matchTitle (String theTitle) {…}; } public class ALoggedCourse extends ACourse { public int getNumberOfQueries() {…}; public Course matchTitle (String theTitle) {…}; } ACourse ALoggedCourse ARegularCourse ALoggedRegularCourse

20 Multiple Class Inheritance? public class LoggedRegularCourse extends ALoggedCourse, ARegularCourse { } public class ARegularCourse extends ACourse { public int getNumber() {…}; public void init (String theTitle, String theDept, int theCourseNum); } public class ACourse implements Course { public String getTitle() {…} public String getDepartment() {…}; public void init (String theTitle, String theDept) {…}; public Course matchTitle (String theTitle) {…}; } public class ALoggedCourse extends ACourse { public int getNumberOfQueries() {…}; public Course matchTitle (String theTitle) {…}; } ACourse ALoggedCourse ARegularCourse ALoggedRegularCourse

21 Multiple Class Inheritance? public class ALoggedRegularCourse extends ALoggedCourse, ARegularCourse implements LoggedRegularCourse {} public abstract class ALoggedCourse extends ACourse implements LoggedCourse { … public Course matchTitle(String theTitle) { Course course = super.matchTitle(theTitle); if (course != null) numberOfQueries++; return course; } public class ARegularCourse extends ACourse implements RegularCourse {…} public abstract class ACourse implements Course { … public Course matchTitle(String theTitle) { if ( title.equals(theTitle))return this; elsereturn null; } Two different implementations with same header inherited

22 Multiple inheritance rules Allow interfaces to inherit multiple times –Only headers are inherited Do not allow classes to inherit multiple times (Java) –Could inherit multiple bodies with same header –Can be confusing to programmers Other solutions –Allow multiple inheritance if ambiguity does not arise –If ambiguity arises indicate which implementation is used (C++) ALoggedCourse.matchTitle() vs ARegularCourse.matchTitle() –Choose one or none of the bodies if problem arises Based on order in extends clause? extends ALoggedCourse, ARegularCourse

23 Multiple Interface Inheritance public interface LoggedRegularCourse extends RegularCourse, LoggedCourse{ } public interface RegularCourse extends Course { public void init (String theTitle, String theDept, int theCourseNum); } public interface Course extends TreeNode { public String getTitle(); public String getDepartment(); public int getNumber(); public void init (String theTitle, String theDept); } public interface LoggedCourse extends Course { public int getNumberOfQueries(); } Course LoggedCourse RegularCourse LoggedRegularCourse Same method headers added twice, no problem

24 Multiple Interface Inheritance public interface LoggedRegularCourse extends RegularCourse, LoggedCourse { } public interface RegularCourse extends Course { public void init (String theTitle, String theDept, int theCourseNum); } public interface Course extends TreeNode { public String getTitle(); public String getDepartment(); public int getNumber(); public void init (String theTitle, String theDept); } public interface LoggedCourse extends Course { public int getNumberOfQueries(); public void init (String theTitle, String theDept); } Course LoggedCourse RegularCourse LoggedRegularCourse Equal method headers inherited twice Interface: set of method headers Addition: removes duplicates

25 Multiple Interface Inheritance public interface LoggedRegularCourse extends RegularCourse, LoggedCourse { } public interface RegularCourse extends Course { public void init (String theTitle, String theDept, int theCourseNum); } public interface Course extends TreeNode { public String getTitle(); public String getDepartment(); public int getNumber(); public void init (String theTitle, String theDept); } public interface LoggedCourse extends Course { public int getNumberOfQueries(); public LoggedCourse init (String theTitle, String theDept); } Course LoggedCourse RegularCourse LoggedRegularCourse Method headers differ only in return type Overloading ambiguity, multiple inheritance not allowed

26 Single inheritance => reduced polymorphsism? public class ALoggedRegularCourse extends ALoggedCourse implements LoggedRegularCourse { … } void print (ARegularCourse course) {…} ALoggedRegularCourse introProg = new ALoggedRegularRegularCourse(); …. print(introProg); LoggedRegularCourse introProg = new ALoggedRegularRegularCourse(); …. print(introProg); void print (RegularCourse course) {…} Code Duplication & ALoggedRegularCourse is not ARegularCourse! Classes as types Interfaces as types

27 Single inheritance => reduced polymorphism? Yes, if classes used to type variables Interfaces offer solution to lack of multiple (class) inheritance in Java Most programmers do not realise other uses. In text books, interfaces introduced and used only in problems requiring multiple inheritance

28 Implementing Single Interface public class ALoggedRegularCourse extends ALoggedCourse implements LoggedRegularCourse { int courseNum ; public ALoggedRegularCourse (String theTitle, String theDept, int theCourseNum) { init (theTitle, theDept, theCourseNum); } public ALoggedRegularCourse () {} public void init (String theTitle, String theDept, int theCourseNum) { super.init (theTitle, theDept); courseNum = theCourseNum; } public int getNumber() { return courseNum; } package courseTree; public interface LoggedRegularCourse extends LoggedCourse, RegularCourse{}

29 Implementing Multiple Interfaces public class ALoggedRegularCourse extends ALoggedCourse implements LoggedCourse, RegularCourse { int courseNum ; public ALoggedRegularCourse (String theTitle, String theDept, int theCourseNum) { init (theTitle, theDept, theCourseNum); } public ALoggedRegularCourse () {} public void init (String theTitle, String theDept, int theCourseNum) { super.init (theTitle, theDept); courseNum = theCourseNum; } public int getNumber() { return courseNum; }

30 Multiple interfaces => Casting LoggedCourse introProg = new ALoggedRegularRegularCourse(); …. print((RegularCourse)introProg); …. appendToLog(introProg); public class ALoggedRegularCourse extends ALoggedCourse implements LoggedCourse, RegularCourse { …. } RegularCourse introProg = new ALoggedRegularRegularCourse(); …. print(introProg); …. appendToLog((LoggedCourse)introProg); void print (RegularCourse course) {…} void appendToLog (LoggedCourse course) {…}

31 Single interface LoggedregularCourse introProg = new ALoggedRegularRegularCourse(); …. print (introProg); …. appendToLog(introProg); void print (RegularCourse course) {…} void appendToLog (LoggedCourse course) {…} public class ALoggedRegularCourse extends ALoggedCourse implements LoggedRegularCourse { …. }

32 Single interface and overloading LoggedRegularCourse introProg = new ALoggedRegularRegularCourse(); …. print ((RegularCourse)introProg); …. appendToLog((LoggedCourse)introProg); void print (RegularCourse course) {…} void print (LoggedCourse course) {…} public class ALoggedRegularCourse extends ALoggedCourse implements LoggedRegularCourse { …. }

33 Implementing multiple interfaces vs. Single Interface Different interfaces evolved independently –TreeNode, LeafOnly, CompositeOnly –LoggedCourse, RegularCourse Uniting them creates empty interface Does not require casting to use different interfaces of same object Modulo overloading problems –These arise whenever an object can be typed in multiple ways. –A compile time issue – these casts are needed only at compile time and do not lead to runtime errors.

34 Switching between different course configurations Want both logged and non-logged versions based on users –Logged course has overhead –Some university may decide logging gives misleading /useless information How to write programs that can easily switch between the two kinds of courses

35 package courseTree; public class ACourseList implements CourseList, TreeNode { final int MAX_SIZE = 50; TreeNode[] contents = new TreeNode[MAX_SIZE]; int size = 0; public int size() {return size;} public TreeNode elementAt (int index) {return contents[index];} boolean isFull() {return size == MAX_SIZE;} public void addElement(TreeNode element) { if (isFull()) System.out.println("Adding item to a full collection"); else { contents[size] = element; size++; } public Course matchTitle (String theTitle) { for (int courseIndex = 0; courseIndex < size; courseIndex++) { Course course = contents[courseIndex].matchTitle(theTitle); if ( course != null) return course; } return null; } ACourseList Using interfaces as types Oblivious to actual classes

36 Main Class package main; … public class ACourseDisplayer{ static CourseList courses = new ACourseList(); public static void main(String[] args){ fillCourses(); //Do I/O … }... static void fillCourses() { CourseList prog = new ACourseList(); prog.addElement (new ARegularCourse ("Intro. Prog.", "COMP", 14)); prog.addElement (new ARegularCourse ("Found. of Prog.", "COMP", 114)); courses.addElement(prog); courses.addElement (new AFreshmanSeminar("Comp. Animation", "COMP")); courses.addElement (new AFreshmanSeminar("Lego Robots", "COMP")); }

37 Code Duplication package main; … public class ACourseDisplayer{ static CourseList courses = new ACourseList(); public static void main(String[] args){ fillCourses(); //Do I/O … }... static void fillCourses() { CourseList prog = new ACourseList(); prog.addElement (new ALoggedRegularCourse ("Intro. Prog.", "COMP", 14)); prog.addElement (new ALoggedRegularCourse ("Found. of Prog.", "COMP", 114)); courses.addElement(prog); courses.addElement (new ALoggedFreshmanSeminar("Comp. Animation", "COMP")); courses.addElement (new ALoggedFreshmanSeminar("Lego Robots", "COMP")); }

38 Code Inconsistency package main; … public class ACourseDisplayer{ static CourseList courses = new ACourseList(); public static void main(String[] args){ fillCourses(); //Do I/O … }... static void fillCourses() { CourseList prog = new ACourseList(); prog.addElement (new ALoggedRegularCourse ("Intro. Prog.", "COMP", 14)); prog.addElement (new ALoggedRegularCourse ("Found. of Prog.", "COMP", 114)); courses.addElement(prog); courses.addElement (new AFreshmanSeminar("Comp. Animation", "COMP")); courses.addElement (new AFreshmanSeminar("Lego Robots", "COMP")); } Adding logged regular course and unlogged freshman seminar

39 Switching between classes How to make main and other classes instantiating course objects oblivious to which course set is used? How to make sure incompatible courses are not added to course list –AFreshmanSeminar –ALoggedRegularCourse

40 Factory class Creates a set of related objects Different factory classes for different configurations –ACourseFactory –ALoggedCourseFactory Factory classes providing alternative configurations implement the same interface –CourseFactory

41 Common Factory Interface package factories; import courseTree.RegularCourse; import courseTree.FreshmanSeminar; public interface CourseFactory { public RegularCourse getRegularCourse(); public FreshmanSeminar getFreshmanSeminar(); }

42 ACourseFactory package factories; import courseTree.RegularCourse; import courseTree.FreshmanSeminar; import courseTree.ARegularCourse; import courseTree.AFreshmanSeminar; public class ACourseFactory implements CourseFactory { public RegularCourse getRegularCourse() { return new ARegularCourse(); } public FreshmanSeminar getFreshmanSeminar() { return new AFreshmanSeminar(); } Parameterless constructors Factory user will call init()

43 ALoggedCourseFactory package factories; import courseTree.RegularCourse; import courseTree.FreshmanSeminar; import courseTree.ALoggedRegularCourse; import courseTree.ALoggedFreshmanSeminar; public class ALoggedCourseFactory implements CourseFactory{ public RegularCourse getRegularCourse() { return new ALoggedRegularCourse(); } public FreshmanSeminar getFreshmanSeminar() { return new ALoggedFreshmanSeminar(); }

44 Original Main Class package main; … public class ACourseDisplayer{ static CourseList courses = new ACourseList(); public static void main(String[] args){ fillCourses(); //Do I/O … }... static void fillCourses() { CourseList prog = new ACourseList(); prog.addElement (new ARegularCourse ("Intro. Prog.", "COMP", 14)); prog.addElement (new ARegularCourse ("Found. of Prog.", "COMP", 114)); … }

45 New Main Class package main; … public class AFactoryBasedCourseDisplayer{ static CourseList courses = new ACourseList(); public static void main(String[] args){ fillCourses(); //Do I/O … }... static void fillCourses() { CourseFactory courseFactory = new ACourseFactory(); CourseList prog = new ACourseList(); RegularCourse introProg = courseFactory.getRegularCourse (); introProg.init("Intro. Prog.", "COMP", 14); RegularCourse foundProg = courseFactory.getRegularCourse (); foundProg.init(“Found. Prog.", "COMP", 114); … }

46 New Main Class for logged courses package main; … public class AFactoryBasedCourseDisplayer{ static CourseList courses = new ACourseList(); public static void main(String[] args){ fillCourses(); //Do I/O … }... static void fillCourses() { CourseFactory courseFactory = new ALoggedCourseFactory(); CourseList prog = new ACourseList(); RegularCourse introProg = courseFactory.getRegularCourse (); introProg.init("Intro. Prog.", "COMP", 14); RegularCourse foundProg = courseFactory.getRegularCourse (); foundProg.init(“Found. Prog.", "COMP", 114); … }

47 Factory Transparent Main? Same main and other course users for different configurations? Need FactorySelector Class –Only class changed to select different configurations Main and other classes call factory selector class

48 Factory Selector Interface package factories; public interface CourseFactorySelector { public CourseFactory getCourseFactory(); }

49 Factory Selector Class package factories; public class ACourseFactorySelector implements CourseFactorySelector { public CourseFactory getCourseFactory() { //return new ACourseFactory(); return new ALoggedCourseFactory(); }

50 Main Class with Factory Selector package main; … public class AFactoryBasedCourseDisplayer{ static CourseList courses = new ACourseList(); public static void main(String[] args){ fillCourses(); //Do I/O … }... static void fillCourses() { CourseFactory courseFactory = (new CourseFactorySelector()).getCourseFactory(); CourseList prog = new ACourseList(); RegularCourse introProg = courseFactory.getRegularCourse (); introProg.init("Intro. Prog.", "COMP", 14); RegularCourse foundProg = courseFactory.getRegularCourse (); foundProg.init(“Found. Prog.", "COMP", 114); … }

51 Different Selection package factories; public class ACourseFactorySelector { public CourseFactory getCourseFactory() { return new ACourseFactory(); //return new ALoggedCourseFactory(); } No change to main and other users needed!

52 ALoggedCourseFactory package factories; import courseTree.RegularCourse; import courseTree.FreshmanSeminar; import courseTree.ALoggedRegularCourse; import courseTree.ALoggedFreshmanSeminar; public class ALoggedCourseFactory implements CourseFactory{ public RegularCourse getRegularCourse() { return new ALoggedRegularCourse(); } public FreshmanSeminar getFreshmanSeminar() { return new ALoggedFreshmanSeminar(); } Classes that need logged courses must cast

53 Logged Factory Interface package factories; import courseTree.LoggedRegularCourse; import courseTree.LoggedFreshmanSeminar; public interface LoggedCourseFactory extends CourseFactory { public LoggedRegularCourse getLoggedRegularCourse(); public LoggedFreshmanSeminar getLoggedFreshmanSeminar(); }

54 ALoggedCourseFactory package factories; import courseTree.RegularCourse; import courseTree.FreshmanSeminar; import courseTree.LoggedRegularCourse; import courseTree.LoggedFreshmanSeminar; import courseTree.ALoggedRegularCourse; import courseTree.ALoggedFreshmanSeminar; public class ALoggedCourseFactory implements LoggedCourseFactory { public RegularCourse getRegularCourse() { return new ALoggedRegularCourse(); } public FreshmanSeminar getFreshmanSeminar() { return new ALoggedFreshmanSeminar(); } public LoggedRegularCourse getLoggedRegularCourse() { return new ALoggedRegularCourse(); } public LoggedFreshmanSeminar getLoggedFreshmanSeminar() { return new ALoggedFreshmanSeminar(); }

55 Factory Pattern Factory Interface Factory Class 1Factory Class 2 implements

56 Alternative Factory Pattern Abstract Factory Class Factory Class 1Factory Class 2 extends

57 Classes vs. Factory We also called a class a factory –It defines blueprints for its instances Factory in factory pattern is really a broker that orders objects for you. Factory selector decides between different kinds of brokers Analogy –I ask my IT department to get me a 4lb laptop –They decide to go to the IBM CCI “factory” –CCI factory specifies matching computer and accessories –These are then ordered from the real IBM factory Car Analogy –Dealership selling you cars and accessories that go with them.

58 Factory Uses Should we always instantiate via factories? Factories add overhead –Factory interfaces, classes –Factory selector interfaces, classes Define when you need them –Need to switch transparently between alternates BMISpreadsheet and AnotherBMISpreadsheet –Need to ensure matching objects are created ALoggedFreshmanSeminar and ALoggedRegularCourse

59 Factory uses Multiple toolkits provide same kind of widgets with different look and feel/implementations. Package java.awt –TextField, Button, Panel Package javax.swing –JTextField, JButton, JPanel Could define a common factory interface –getTextField(), getButton(), getPanel() SwingFactory and AWTFactory classes implement interface FactorySelector switches between two classes to change implementation

60 Factory Uses Multiple implementation of AWT toolkit for each window system. –Microsoft Windows. –X Windows

61 Factories and Interfaces Factories allow us to switch between alternative objects providing same methods –FreshmanSeminar and LoggedFreshmanSeminar –JTextField and TextField Alternative objects must be united by a common interface Otherwise common factory interface cannot be defined. Desired toolkit factory interface –getTextField(), getButton(), getPanel() JTextField and TextField do not define a common text field interface Though they provide common methods –getText(), setText() Moral: define interfaces!

62 ObjectEditor Factory Example package bus.uigen.view; import java.awt.Container; public interface PanelFactory { public Container createPanel (); }

63 ObjectEditor Factory Selector Example package bus.uigen.view; import java.awt.Container; public class PanelSelector { //static PanelFactory factory = new SwingPanelFactory(); static PanelFactory factory = new AWTPanelFactory(); public static void setPanelFactory (PanelFactory newVal) { factory = newVal; } public static Container createPanel() { return factory.createPanel(); }

64 Main class without Façade package main; … public class AFactoryBasedCourseDisplayer{ static CourseList courses = new ACourseList(); public static void main(String[] args){ fillCourses(); while (true) { System.out.println("Please enter course title:"); String inputLine = readString(); if (inputLine.equals(".")) break; else { Course matchedCourse = courses.matchTitle(inputLine); if (matchedCourse == null) System.out.println("Sorry, this course is not offered."); else { printHeader(); print (matchedCourse); }

65 Main Class without Façade... static void fillCourses() { CourseFactory courseFactory = (new CourseFactorySelector()).getCourseFactory(); CourseList prog = new ACourseList(); RegularCourse introProg = courseFactory.getRegularCourse (); introProg.init("Intro. Prog.", "COMP", 14); RegularCourse foundProg = courseFactory.getRegularCourse (); foundProg.init(“Found. Prog.", "COMP", 114); … } … } Composes courses and course lists

66 Main class with façade package main; … public class AFactoryBasedCourseDisplayer{ static TitleToCourseMapper titleToCourseMapper = new ATitleToCourseMapper(); public static void main(String[] args){ while (true) { System.out.println("Please enter course title:"); String inputLine = readString(); if (inputLine.equals(".")) break; else { titleToCourseMapper.setTitle(inputLine); Course matchedCourse = titleToCourseMapper.getCourse(); if (matchedCourse == null) System.out.println("Sorry, this course is not offered."); else { printHeader(); print (matchedCourse); } }}

67 Façade interface package facades; import courseTree.Course; public interface TitleToCourseMapper { public String getTitle(); public void setTitle (String newVal); public Course getCourse(); }

68 Façade Class package facades; import courseTree.Course; import courseTree.RegularCourse; import courseTree.FreshmanSeminar; import courseTree.CourseList; import courseTree.ACourseList; import factories.CourseFactory; import factories.ACourseFactorySelector; public class AFactoryBasedTitleToCourseMapper implements TitleToCourseMapper{ CourseList courses = new ACourseList(); public AFactoryBasedTitleToCourseMapper() { fillCourses(); } String title = ""; public String getTitle() {return title;} public void setTitle (String newVal) { title = newVal; course = courses.matchTitle(title); } Course course; public Course getCourse() { return courses.matchTitle(title); }

69 Façade Class void fillCourses() { CourseFactory courseFactory = (new ACourseFactorySelector()).getCourseFactory(); CourseList prog = new ACourseList(); RegularCourse introProg = courseFactory.getRegularCourse (); introProg.init("Intro. Prog.", "COMP", 14); prog.addElement(introProg); RegularCourse foundProg = courseFactory.getRegularCourse(); foundProg.init ("Found. of Prog.", "COMP", 114); prog.addElement(foundProg); courses.addElement(prog); FreshmanSeminar compAnimation = courseFactory.getFreshmanSeminar(); compAnimation.init("Comp. Animation", "COMP"); courses.addElement(compAnimation); FreshmanSeminar legoRobots = courseFactory.getFreshmanSeminar(); legoRobots.init("Lego Robots", "COMP"); courses.addElement(legoRobots); }

70 Facade pattern RegularCourse FreshmanSeminar CourseList Facade

71 Facade pattern Component1 Component2 ComponentN Facade

72 Factory-based Façade Class package facades; … public class AFactoryBasedTitleToCourseMapper implements TitleToCourseMapper{ … void fillCourses() { CourseFactory courseFactory = (new ACourseFactorySelector()).getCourseFactory(); RegularCourse introProg = courseFactory.getRegularCourse (); FreshmanSeminar legoRobots = courseFactory.getFreshmanSeminar(); … }

73 Application-specific factory Factory switching occurs for all classes What if we want it for some subset of classes

74 Factory Method Creates objects Could be abstract Subclasses override it to create objects of different classes Change in subclass does not change other subclasses

75 Abstract facade class package facades; import courseTree.Course; import courseTree.RegularCourse; import courseTree.FreshmanSeminar; import courseTree.CourseList; import courseTree.ACourseList; public abstract class AnAbstractTitleToCourseMapper implements TitleToCourseMapper{ … abstract RegularCourse getRegularCourse(); abstract FreshmanSeminar getFreshmanSeminar(); void fillCourses() { RegularCourse introProg = getRegularCourse (); FreshmanSeminar legoRobots = getFreshmanSeminar(); … }

76 Concrete course user package facades; import courseTree.Course; import courseTree.RegularCourse; import courseTree.FreshmanSeminar; import courseTree.ARegularCourse; import courseTree.AFreshmanSeminar; public class ATitleToCourseMapper extends AnAbstractTitleToCourseMapper{ RegularCourse getRegularCourse() { return new ARegularCourse(); } FreshmanSeminar getFreshmanSeminar() { return new AFreshmanSeminar(); }

77 Logged course user package facades; import courseTree.Course; import courseTree.RegularCourse; import courseTree.FreshmanSeminar; import courseTree.ALoggedRegularCourse; import courseTree.ALoggedFreshmanSeminar; public class ATitleToLoggedCourseMapper extends AnAbstractTitleToCourseMapper{ RegularCourse getRegularCourse() { return new ALoggedRegularCourse(); } FreshmanSeminar getFreshmanSeminar() { return new ALoggedFreshmanSeminar(); }

78 Factory Methods in Course Example AnAbstractTitleToCourseMapper { defines createRegularCourse and createFreshmanSeminar and uses them} ATitleToCourseMapper { implements these methods to create one configuration } ATitleToLoggedCourseMapper { implements these methods to create another configuration } extends

79 Factory Method Pattern Abstract Class { defines and uses class creation methods} Concrete Class { implements these methods to create some configuration } extends

80 Factory Methods in Course Example AnAbstractTitleToCourseMapper { defines createRegularCourse and createFreshmanSeminar and uses them} ATitleToCourseMapper { implements these methods to create one configuration } ATitleToLoggedCourseMapper { implements these methods to create another configuration } extends ATitleToLoggedCourseMapper IS-A ATitleToCourseMapper

81 Factory Methods in Course Example AnAbstractTitleToCourseMapper { defines createRegularCourse and createFreshmanSeminar and uses them} ATitleToCourseMapper { implements these methods to create one configuration } ATitleToLoggedCourseMapper { implements these methods to create another configuration } extends ATitleToLoggedCourseMapper IS-A ATitleToCourseMapper extends Redundant class with a single user

82 Alternative Factory Method Usage ATitleToCourseMapper { implements createRegularCourse and createFreshmanSeminar and uses them} ATitleToLoggedCourseMapper { overrides these methods to create an extension} extends

83 Factory methods Do not have to be abstract –Though pattern book says they are A concrete class may define and use class creation methods Some subclass of it overrides them The subclass must extend the functionality ATitleToLoggedCourseMapper IS-A ATitleToCourseMapper as LoggedCourse IS-A Course

84 Factory Classes vs. Factory Methods Create a configuration applying to all users of a factory selector Creates local configurations. If class C implements abstract factory method defined in super class S, then configuration applies to C, and all subclasses of C and superclasses between C and S that do not override/implement it

85 Factory Classes vs. Methods public class AFactoryBasedTitleToCourseMapper implements TitleToCourseMapper{ … void fillCourses() { CourseFactory courseFactory = (new ACourseFactorySelector()).getCourseFactory(); RegularCourse introProg = courseFactory.getRegularCourse (); FreshmanSeminar legoRobots = courseFactory.getFreshmanSeminar(); … } public class ATitleToCourseMapper implements TitleToCourseMapper{ … RegularCourse getRegularCourse() {return new ARegularCourse();} FreshmanSeminar getFreshmanSeminar() {return new AFreshmanSeminar();} void fillCourses() { RegularCourse introProg = getRegularCourse (); FreshmanSeminar legoRobots = getFreshmanSeminar(); … } Lots of methods possible, which may return incompatible objects Single factory method simply acts as factory selector.

86 Electronics Example Need for factories –VCR RGB goes with TV RGB –VCR SVideo goes with TV SVideo RGB Factory –TV RF and VCR RF SVideo Factory –Svideo TVs & VCR Need for façade –Want to simulate a single combo unit, using VCR as channel tuner for TV Methods –Constructor asks vcr to connect to TV and sets TV channel to vcr’s CHANNEL –power() powers both components –getChannel(), setChannel(), record() and play() Asks vcr to do the operation


Download ppt "Multiple Inheritance & Factories Prasun Dewan Comp 114."

Similar presentations


Ads by Google