47
Factory Patterns

Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

Embed Size (px)

DESCRIPTION

DCS – SWC 3 Being less concrete Animal sleep() makeSound() lookForFood() Dog sleep() makeSound() lookForFood() Horse sleep() makeSound() lookForFood()

Citation preview

Page 1: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

Factory Patterns

Page 2: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 2

Being less concrete

• One important OO principle is: ”Program to an interface, not an implementation”

• Interfaces reduces the coupling between code and concrete types

• Code does not need to know the concrete type of an object

Page 3: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 3

Being less concrete

Animalsleep()makeSound()lookForFood()

Dogsleep()makeSound()lookForFood()

Horsesleep()makeSound()lookForFood()

Page 4: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 4

Being less concrete

Animal oneAnimal = new Horse();…oneAnimal.sleep();oneAnimal.makeSound();oneAnimal.lookForFood():…

Page 5: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 5

Being less concrete

Animal oneAnimal = new Dog();…oneAnimal.sleep();oneAnimal.makeSound();oneAnimal.lookForFood():…

Page 6: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 6

Being less concrete

• This is fine, but we still need to be concrete when creating an object

• Also, we might need to choose – at run-time – between various concrete types

Page 7: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 7

Being less concreteAnimal oneAnimal;…if (needToRide)

oneAnimal = new Horse();else if (mustBeMammal)

oneAnimal = new Dog();else

oneAnimal = new Parrot();…oneAnimal.sleep();oneAnimal.makeSound();oneAnimal.lookForFood():…

Page 8: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 8

Being less concrete

• Is anything wrong with this…?• What if we need to add some new

concrete types?• In that case, we will need to change the

code in order to include the new types• ”Closed for modification, open for

extension…”

Page 9: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 9

Being less concrete

• We want to isolate the references to concrete types to another class

• One class produces concrete objects, using their concrete types

• Another class processes the objects, knowing only the interface

• The processing class can then be closed for modification

Page 10: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 10

Being less concrete

• A class which produces objects is usually called a Factory Class

• A factory class usually has a single method: create(…)

• The create method often – but not always – takes a parameter, defining what concrete object to create

Page 11: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 11

Being less concrete

Animalsleep()makeSound()lookForFood()

Dogsleep()makeSound()lookForFood()

Horsesleep()makeSound()lookForFood()

AnimalFactoryAnimal create(String info)

Page 12: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 12

Being less concretepublic class AnimalFactory{

public Animal create(String info){ if (info.equals(”Dog”)) return new Dog(); else if (info.equals(”Horse”)) return new Horse(); else if (info.equals(”Parrot”)) return new Parrot(); else return null;}

}

Page 13: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 13

Being less concreteAnimalFactory fac;…Animal oneAnimal = fac.create(”Dog”);…oneAnimal.sleep();oneAnimal.makeSound();oneAnimal.lookForFood():…

Page 14: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 14

Being less concrete

• Have I achieved something, or am I just moving code around…?

• With this setup, we can now parameterise the processing code further

• This removes the last references to concrete types

Page 15: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 15

Being less concretepublic void processAnAnimal(String type){

AnimalFactory fac = new AnimalFactory();…Animal oneAnimal = fac.create(type);…oneAnimal.sleep();oneAnimal.makeSound();oneAnimal.lookForFood():…

}

Type specifi-cation is a parameter

Page 16: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 16

Being less concretepublic void processAnAnimal

(String type, AnimalFactory fac){

Animal oneAnimal = fac.create(type);…oneAnimal.sleep();oneAnimal.makeSound();oneAnimal.lookForFood():…

}

Type specifi-cation and object factory are parameters

Page 17: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 17

Being less concrete

• This pattern is known as Simple Factory• We have separated code for producing

objects, and code for processing objects• Processing code only knows about the

interface• Fewer responsibilities per class – ”Classes

should only have one reason to change”

Page 18: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 18

Abstraction to the next level

• The processing code needs a parameter which carries the type information for the object being created

• However, we also suggested that the factory itself could be a parameter

• Why would we do that….?

Page 19: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 19

Abstraction to the next levelpublic void processAnAnimal

(String type, AnimalFactory fac){

Animal oneAnimal = fac.create(type);…oneAnimal.sleep();oneAnimal.makeSound();oneAnimal.lookForFood():…

}

Type specifi-cation and object factory are parameters

Page 20: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 20

Abstraction to the next level

• Consider a word processor:– A document is composed of various typo-

graphic objects, like Heading, Emphasis, and so on

– All such classes implement the interface Typo– Given some input source, a piece of code

must produce a list of Typo objects

Page 21: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 21

Abstraction to the next level// Part of input processing codeTypoFactory theTypoFactory;

public void createDocument(DocInput in){

ArrayList<Typo> doc = new ArrayList<Typo>();while (in.hasNext()){ TypoInput tyIn = in.next(); Typo typ = makeTypo(tyIn); doc.add(typ);}

}

Page 22: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 22

Abstraction to the next level// Part of input processing codeprivate Typo makeTypo(TypoInput in){

String text = in.getText();String type = in.getType();

Typo theTypo = theTypoFactory.create(type);thetypo.addText(text);

return theTypo;}

Page 23: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 23

Abstraction to the next level// TypoFactory codeprivate Typo create(String type){

if (type.equals(”Heading”))return new Heading();

else if (type.equals(”Emphasis”))return new Emphasis();

...else

return null;}

Page 24: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 24

Abstraction to the next level

• The code processing the input does not know about concrete Typo classes – good

• But the code is still ”constrained”…• What is a Typo object really – it is a

”binding” between a text and a certain way of formatting the text

• Different concrete Typo classes provide different bindings

Page 25: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 25

Abstraction to the next level

• A Heading might be– Font size 24– Bold– Calibri font

• An Emphasis might be– Bold– Red font color

Page 26: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 26

Abstraction to the next level

• A Typo factory thus defines a set of bindings between text and formatting – a layout

• What if we wish to change the layout of a document?

• We could then just define a different Typo factory, with different bindings

Page 27: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 27

Abstraction to the next level// Part of input processing codeTypoFactoryFormalLayout theTypoFactory;

public void createDocument(DocInput in){

ArrayList<Typo> doc = new ArrayList<Typo>();while (in.hasNext()){ TypoInput tyIn = in.next(); Typo typ = makeTypo(tyIn); doc.add(typ);}

}

Just change the type of the Typo factory…

Page 28: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 28

Abstraction to the next level

• This solution is still quite static• Changing to a different factory requires

code modification• Why not use interfaces once again!• We could also define an interface for the

factory side, making the processing code independent of a specific factory

Page 29: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 29

Abstraction to the next level

TypoaddText()

TypoFactoryTypo create(…)

Page 30: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 30

Abstraction to the next level

TypoTypoFactory

TypoFactory-FormalLayout

TypoFactory-SmartLayout

Page 31: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 31

Abstraction to the next level

TypoTypoFactory

TypoHeading-Formal

TypoEmphasis-Formal

TypoHeading-Smart

TypoEmphasis-Smart

Page 32: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 32

Abstraction to the next level

TypoHeading-Formal

TypoEmphasis-Formal

TypoHeading-Smart

TypoEmphasis-Smart

TypoFactory-FormalLayout

TypoFactory-SmartLayout

Page 33: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 33

Abstraction to the next level

• The factory for Formal layout only knows the concrete classes TypoHeading-Formal and TypoEmphasisFormal

• The factory for Smart layout only knows the concrete classes TypoHeadingSmart and TypoEmphasisSmart

• The factory interface only knows about the Typo interface

Page 34: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 34

Abstraction to the next level// A configurable document creator classpublic class DocumentCreator{

TypoFactory typoFac;

public DocumentCreator(TypoFactory typoFac){

this.typoFac = typoFac;}

public void createDocument(DocInput in) {...}}

Page 35: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 35

Abstraction to the next levelpublic void createFormalDocument(){

TypoFactory typoFac = new TypoFactoryFormalLayout();

DocumentCreator docCre = new DocumentCreator(typoFac);

docCre.createDocument(getDocInput());}

Page 36: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 36

Abstraction to the next level

• Note that the only thing that changes between two TypoFactory implementa-tions is the create method

• We may include concrete methods in the Typo interface – making it an abstract class – if it makes sense

• This is known as the Factory Mehtod pattern

Page 37: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 37

The Factory method pattern

ProductFactorycreate()someMethod()

ConcreteFactorycreate()

ConcreteProduct

Page 38: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 38

The Abstract Factory

• Our code can now work with different concrete factories, through a Factory interface

• What if we need to create several types of ”products”, not just a single type?– Typo – formattings of text– Graphic – formattings of graphic objects

Page 39: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 39

The Abstract Factory

• Answer seems simple: just use Factory Method pattern twice

TypoTypoFactory

TypoFactory-FormalLayout

TypoFactory-SmartLayout

GraphicGraphicFactory

GraphicFactory-FormalLayout

GraphicFactory-SmartLayout

Page 40: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 40

The Abstract Factory

• This looks fine…• …but does it reflect our intention?• Would it make sense to have a document,

with – text using Formal layout– graphics using Smart layout

• Model does not include any ”binding” between related products

Page 41: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 41

The Abstract Factorypublic void createFormalDocument(){

TypoFactory tFac = new TypoFactoryFormalLayout();GraphicFactory gFac = new GraphicFactorySmartLayout();

DocumentCreator docCre = new DocumentCreator(tFac,gFac);docCre.createDocument(getDocInput());

}

Oooppss!

Page 42: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 42

The Abstract Factory

• A Typo and a Graphic are not – as seen from a type point-of-view – related

• Would be somewhat artificial – or perhaps even impossible – to introduce a common base class

• However, we can enforce the binding through a shared factory class!

Page 43: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 43

The Abstract Factory

DocItemFactorycreateTypo()createGraphic()

FormalDocItemFactory SmartDocItemFactory

Page 44: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 44

The Abstract Factorypublic void createFormalDocument(){

DocItemFactory fac = new FormalDocItemFactory ();

DocumentCreator docCre = new DocumentCreator(fac);docCre.createDocument(getDocInput());

}

Page 45: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 45

The Abstract Factorypublic void createDocument(DocInput in){ ... Typo aTypo = theFactory.createTypo(typoInfo); ... Graphic aGraphic = theFactory.createGraphic(graphicInfo);

...}

Using the same factory for creating Typo and Graphic objects!

Page 46: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 46

The Abstract Factory

• This pattern is known as the Abstract Factory pattern

• By making a creator class with several create… methods, we restrict the product combinations the client can create

Page 47: Factory Patterns. DCS – SWC 2 Being less concrete One important OO principle is: ”Program to an…

DCS – SWC 47

The Abstract Factory

• The methods in the Abstract Factory are product-type dependent, so if we add another product, we need to change the interface of the base class

• This is a price we must pay for binding (formally) non-related types together

• Patterns are also compromises…