Top Banner
Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114
93

Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Dec 21, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Multiple Inheritance, Factories, & Facades

Prasun Dewan

Comp 114

Page 2: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Topics Covered

• Multiple inheritance– Extending more than one type

• Factories– Class creating objects

• Facades– Compose objects

• Can be used independently– We use them together here

• Factory methods– Abstract method instead of class

Page 3: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 4: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Old 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);

}

Page 5: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

New Course Interface

package courseTree;public interface LoggedCourse extends Course {

public int getNumberOfQueries();

}

Page 6: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Old abstract classpackage 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;else return null;

}}

Page 7: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

New abstract classpackage 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;

}}

Page 8: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Old Regular Course Interfacepackage courseTree;public interface RegularCourse extends Course {

public void init (String theTitle, String theDept, int theCourseNum);}

Page 9: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

New Regular Course Interfacepackage courseTree;public interface LoggedRegularCourse extends LoggedCourse {

public void init (String theTitle, String theDept, int theCourseNum);}

Page 10: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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);}

LoggedRegularCourse IS-A RegularCourse

Page 11: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 12: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 13: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 14: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

empty interface

Page 15: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Old Regular Course Classpublic 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;}

}

Page 16: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

New Regular Course Classpublic 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 ALoggedRegularCourse is not ARegularCourse!

Page 17: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 18: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 19: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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;else return null;

}}

Two different implementations with same header inherited

Page 20: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 21: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 22: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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 headersAddition: removes duplicates

Page 23: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 24: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 25: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 26: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Implementing Single Interfacepublic 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{}

Page 27: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Implementing Multiple Interfacespublic 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;}

}

Page 28: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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) {…}

Page 29: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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 { …. }

Page 30: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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 { …. }

Page 31: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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.

Page 32: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 33: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

ACourseListpackage 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;

}}

Using interfaces as typesOblivious to actual classes

Page 34: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Main Classpackage 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"));

}}

Page 35: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 36: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 37: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Common Factory Interface

package factories;import courseTree.RegularCourse;import courseTree.FreshmanSeminar;public interface CourseFactory {

public RegularCourse getRegularCourse();public FreshmanSeminar getFreshmanSeminar();

}

Page 38: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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 constructorsFactory user will call init()

Page 39: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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();}

}

Page 40: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Original Main Classpackage 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));…

}}

Page 41: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

New Main Classpackage 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);…

}}

Page 42: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

New Main Class for logged coursespackage 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);

…}

}

Page 43: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 44: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Factory Selector Interface

package factories;public interface CourseFactorySelector {

public CourseFactory getCourseFactory();}

Page 45: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Factory Selector Class

package factories;public class ACourseFactorySelector implements CourseFactorySelector {

public CourseFactory getCourseFactory() {//return new ACourseFactory();return new ALoggedCourseFactory();

}}

Page 46: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Main Class with Factory Selectorpackage 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);

…}

}

Page 47: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Different Selection

package factories;public class ACourseFactorySelector {

public CourseFactory getCourseFactory() {return new ACourseFactory();//return new ALoggedCourseFactory();

}}

No change to main and other users needed!

Page 48: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 49: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Logged Factory Interface

package factories;import courseTree.LoggedRegularCourse;import courseTree.LoggedFreshmanSeminar;public interface LoggedCourseFactory extends CourseFactory {

public LoggedRegularCourse getLoggedRegularCourse();public LoggedFreshmanSeminar getLoggedFreshmanSeminar();

}

Page 50: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

ALoggedCourseFactorypackage 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();}

}

Page 51: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Factory Pattern

Factory Interface

Factory Class 1 Factory Class 2

implements

Page 52: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Alternative Factory Pattern

Abstract Factory Class

Factory Class 1 Factory Class 2

extends

Page 53: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 54: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 55: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Programmer Selection• Multiple toolkits provided to programmer.• 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

• Programmer-defined FactorySelector switches between two classes to change implementation

Page 56: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 57: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Factory Uses• Multiple implementation of AWT toolkit for

each window system.– Microsoft Windows.– X Windows

Page 58: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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!

Page 59: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Reducing Main Class through Facades

• Things to exclude– “computation”

• Things to include– Input/Output– Object instantiation

• Unless done byfactory

– Object composition

• Main class still monolithic• Facades

– Do object composition

Page 60: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Main class without Façadepackage 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);

} }}

Page 61: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 62: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Main class with Façade (edit)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);

} }}

Page 63: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Main class with Façade (edited)package main;…public class AFactoryBasedCourseDisplayer {

static Facade courses = new AFacade();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);

} }}

Page 64: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Main class with façadepackage 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);

} }}

Page 65: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Façade interface

package facades;import courseTree.Course;public interface TitleToCourseMapper {

public String getTitle();public void setTitle (String newVal);public Course getCourse();

}

Page 66: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Façade Classpackage 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);}

Page 67: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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);

}

}

Page 68: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Façade class

• Done with getters and setters for generality purposes

• Helps with creating GUI interfaces in future

• Provide getters and setters in your facades

Page 69: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Facade pattern

RegularCourse

FreshmanSeminar

CourseList

Facade

Page 70: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Facade pattern

Component1

Component2

ComponentN

Facade

Page 71: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Façade pattern• Compose objects into a single unit exposing methods

relevant to that unit• E.g. scanner, parser, program tree, code generator objects

combined into one compiler object– Takes program text as input– Produces code as output– Passes text to scanner, which passes tokens to parser, which

creates program tree, which is processed by code generator, which produces output

• Compiler user not aware of internal components• Componentizing code is a pain as components must be

combined• Facades removes this problem, creating a simple façade to

complex internals

Page 72: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Factory-based Façade Classpackage facades;…public class AFactoryBasedTitleToCourseMapper implements TitleToCourseMapper {

… void fillCourses() {

CourseFactory courseFactory = (new ACourseFactorySelector()).getCourseFactory();

RegularCourse introProg = courseFactory.getRegularCourse ();FreshmanSeminar legoRobots = courseFactory.getFreshmanSeminar();…

…}

}

Page 73: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Application-specific factory

• Factory switching occurs for all classes

• What if we want it for some subset of classes

Page 74: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Factory Method

• Creates objects

• Could be abstract

• Subclasses override it to create objects of different classes

• Change in subclass does not change other subclasses

Page 75: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Abstract facade classpackage 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();…

…}

}

Page 76: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Concrete course userpackage 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();}

}

Page 77: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Logged course userpackage 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();}

}

Page 78: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 79: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Factory Method Pattern

Abstract Class { defines and uses class creation methods}

Concrete Class { implements these

methods to create some configuration }

Concrete Class { implements these methods to create some

configuration}

extends

Page 80: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 81: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Factory Methods in Course ExampleAnAbstractTitleToCourseMapper { 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

Page 82: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Alternative Factory Method Usage

ATitleToCourseMapper { implements createRegularCourse and

createFreshmanSeminar and uses them}

ATitleToLoggedCourseMapper { overrides these methods to create an

extension}

extends

Page 83: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 84: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Alternative Factory Method Usage

ATitleToCourseMapper { implements createRegularCourse and

createFreshmanSeminar and uses them}

ATilteToLoggedCourseMapper { overrides these methods to create an

extension}

extends

Page 85: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Façade super classpublic class ATitleToCourseMapper implements TitleToCourseMapper {

…RegularCourse getRegularCourse() {

return new ARegularCourse();}FreshmanSeminar getFreshmanSeminar() {

return new AFreshmanSeminar();} void fillCourses() {

RegularCourse introProg = getRegularCourse ();FreshmanSeminar legoRobots = getFreshmanSeminar();… …

}}

Page 86: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Logged course subclasspublic class ATitleToLoggedCourseMapper extends ATitleToCourseMapper {

RegularCourse getRegularCourse() {return new ALoggedRegularCourse();

}FreshmanSeminar getFreshmanSeminar() {

return new ALoggedFreshmanSeminar();}

}

Overridden methods

Page 87: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Generalized Factory Method Pattern

Abstract/Concrete Class { defines and maybe implements object creation methods}

Concrete Class { overrides these implementaions to create

an extension}

extends

Concrete Class { overrides these implementaions to create

an extension}

Page 88: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

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

Page 89: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Factory Classes vs. Methodspublic 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

Page 90: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Factory Classes and Methodspublic 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 getCoursefactory() {return new ARegularCourseFactory();}void fillCourses() {

CourseFactory courseFactory = getCourseFactory();RegularCourse introProg = courseFactory.getRegularCourse ();FreshmanSeminar legoRobots = courseFactory.getFreshmanSeminar();…

}} Single factory method simply acts as factory selector.

Page 91: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Combining factories and factory methods

Abstract/Concrete Class { defines and maybe implements method to

choose factory}

Concrete Class { implements this methods to create some

configuration }

Concrete Class { implements this method to create some

configuration}

extends

Page 92: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Electronics Example• VCR interface

– setChannel(), getChannel(), power(),record(), play(), connectToTV()

– CHANNEL constant

• TV interface– power(), setChannel(),

getChannel()

• VCR with RF connector– setRGB()

• TV with RF connector interface– getRGB()

• TV with S-Video connector interface– getSVideo()

• VCR RGB– Implements

connectToTV in terms of getRGB()

• VCR SVideo– Implements

connectToTV() in terms of getSVideo()

Page 93: Multiple Inheritance, Factories, & Facades Prasun Dewan Comp 114.

Electronics Example

• Need for factories– VCR RF goes with TV

RF

– VCR SVideo goes with RV Svideo

• RGB Factory– TV RF and VCR RF

• SVideo Factory– Svideo TVs & VCR

• Need for façade– Want to simulate a single

combo unit

• Methods– Constructor asks vcr to

connect to TV and sets TV channel to vcr’s CHANNEL

– power()• powers both components

– getChannel(), setChannel(), rcord() and play()

• Asks vcr to do the operation