2. Design patterns. part #2

25
Leonid M.

description

Since these presentations were spare time hobby - I've decided to share them :) Hopefully someone will find them useful. This part continues 1. part with more design patterns like Command, State, NullObject.

Transcript of 2. Design patterns. part #2

Page 1: 2. Design patterns. part #2

Leonid M.

Page 2: 2. Design patterns. part #2

Design Patterns- Command

- State

- NullObject

Puzzle questions

Page 3: 2. Design patterns. part #2

Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice

Christopher Alexander, Sara Ishikawa, MurraySilverstein, Max Jacobson,Ingrid Fiksdahl-King, and Shlomo Angel.A Pattern Language. Oxford

University Press, NewYork, 1977.

Page 4: 2. Design patterns. part #2
Page 5: 2. Design patterns. part #2

Synonyms: Action, Transaction

Intent: Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

Page 6: 2. Design patterns. part #2

There are two extremes that a programmer must avoid when using this pattern:

1. The command is just a link between the receiver and the actions that carry out the request

2. The command implements everything itself, without sending anything to the receiver.

We must always keep in mind the fact that the receiver is the one who knows how to perform the operations needed, the purpose of the command being to help the client to delegate its request quickly and to make sure the command ends up where it should.

Page 7: 2. Design patterns. part #2

Command decouples the object that invokes the operation from the one that knows how to perform it.

Commands are first-class objects. They can be manipulated and extended like any other object.

You can assemble commands into a composite command.

It's easy to add new Commands, because you don't have to change existing classes.

Page 8: 2. Design patterns. part #2

Application

add(Document)

Menu

Menu Item

onClick()

Action

Save Command

execute()command->execute()

document->save()

Page 9: 2. Design patterns. part #2

import java.awt.Component;import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;import javax.swing.JFrame;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JOptionPane;

class ExitAction extends AbstractAction {public ExitAction() {

super("exit");}

public void actionPerformed(ActionEvent e) {System.exit(0);

}}

class ShowDialogAction extends AbstractAction {public ShowDialogAction() {

super("show dialog");}

public void actionPerformed(ActionEvent e) {JOptionPane.showMessageDialog((Component) e.getSource(),

"An action generated this dialog");}

}

public class Test extends JFrame {public static void main(String args[]) {

Test frame = new Test();frame.setTitle("Swing Actions");frame.setSize(500, 400);frame.setLocation(400, 200);frame.show();

}

public Test() {JMenuBar mb = new JMenuBar();JMenu fileMenu = new JMenu("File");fileMenu.add(new ShowDialogAction());fileMenu.add(new ExitAction());

mb.add(fileMenu);setJMenuBar(mb);

}}

Page 10: 2. Design patterns. part #2

Undo support

Macro-commands

Queuing requests

Logging requests

Page 11: 2. Design patterns. part #2

Command manager

Command Command

Please, undo the last one. It caused problems!

client

Can undo? Take back, undo, place in queue

-addCommand()-undo()

-execute()-canUndo()-undo()

Page 12: 2. Design patterns. part #2
Page 13: 2. Design patterns. part #2

DrawHouse

PaintRectangle

PaintLine

PaintLine

PaintLine

PaintLine

FillRectangle…

FillRectangle…

Page 14: 2. Design patterns. part #2

/**

* Calculates the proper constraint for a child being added. createAddCommand is called afterwards.

*/

@Override

protected Command getAddCommand(Request generic) {

// cast request to ChangeBoundsRequest

ChangeBoundsRequest request = (ChangeBoundsRequest) generic;

// get all Edit Parts of request

List editparts = request.getEditParts();

// create a new CompoundCommand

CompoundCommand res = new CompoundCommand();

Rectangle r;

Object constraint;

// for each Edit Part set constraint

for (Iterator epIt = editparts.iterator(); epIt.hasNext();) {

GraphicalEditPart part = (GraphicalEditPart) epIt.next();

r = part.getFigure().getBounds().getCopy();

// convert r to absolute from childpart figure

part.getFigure().translateToAbsolute(r);

r = request.getTransformedRectangle(r);

// convert this figure to relative

getLayoutContainer().translateToRelative(r);

getLayoutContainer().translateFromParent(r);

r.translate(getLayoutOrigin().getNegated());

constraint = getConstraintFor(r);

if ((part instanceof AttributeEditPart) || (part instanceof MethodEditPart)

|| (part instanceof SlotEditPart)) {

return null;

} else {

res.add(createAddCommand(part, constraint));

}

}

return res.unwrap();

}

DrawHouse

PaintRectangle

PaintLine

PaintLine

PaintLine

PaintLine

FillRectangle

FillRectangle …

Page 15: 2. Design patterns. part #2

Command

Command

Command

Thread

Thread

ThreadThread

Thread

User commands are added to the queue

This gives an effective way to limit computations to a fixed numbers of threads

Threads removes commands from the queue by on one, calls execute(). Once complete, go back for a new command object

Page 16: 2. Design patterns. part #2

java.lang.Runnable- Sample invoker: SwingUtilities.invokeLater()

java.util.concurrent.Callable<V>- Sample invoker: ExecutorService#submit(),

ExecutorService#invokeXxxx()

Page 17: 2. Design patterns. part #2

execute()execute()

execute()

store()

store()

store()

execute()execute()

execute()

load()

load()

load()

Page 18: 2. Design patterns. part #2

Also Known as:Stub, Active Nothing

Intent: - Provide an object as a surrogate for the lack of an object of a given

type.

- The Null Object Pattern provides intelligent do nothing behavior, hiding the details from its collaborators.

Page 19: 2. Design patterns. part #2

Null objects can be used in place of real objects when the object is expected to do nothing.

Makes client code simple. (reduces branching)

Encapsulates the do nothing code into the null object.

Makes the do nothing code in the null object easy to reuse.

Makes the do nothing behavior difficult to distribute or mix into the real behavior of several collaborating objects.

Can be difficult to implement if various clients do not agree on how the null object should do nothing as when your AbstractObject interface is not well defined.

Always acts as a do nothing object. The Null Object does not transform into a Real Object.

Page 20: 2. Design patterns. part #2

Null Object and FactoryThe Null Object design pattern is more likely to be used in conjunction with the Factory pattern. The reason for this is obvious: A Concrete Classes need to be instantiated and then to be served to the client. The client uses the concrete class. The concrete class can be a Real Object or a Null Object.

Null Object and Template MethodThe Template method design pattern need to define an abstract class that define the template and each concrete class implements the steps for the template. If there are cases when sometimes template is called and sometimes not then, in order to avoid the checking a Null Object can be use to implement a Concrete Template that does nothing.

Removing old functionalityThe Null Object can be used to remove old functionality by replacing it with null objects. The big advantage is that the existing code doesn't need to be touched.

Page 21: 2. Design patterns. part #2

NullAppender (log4j)

java.util.Collections (jdk)- #emptyList()

- #emptySet()

- …

NullIterator (jdk, internal structures)

Page 22: 2. Design patterns. part #2

public class NullIterator<E> implements Iterator<E> {

@Overridepublic boolean hasNext() {

return false; // Null implementation returns false indicating iterator is empty}

@Overridepublic E next() {

throw new NoSuchElementException("Null iterator doesn't contain anything");}

@Overridepublic void remove() {

throw new UnsupportedOperationException("Null iterator doesn't support remove operration");}

}

Page 23: 2. Design patterns. part #2

Application: Email spam filtering system. Both HTML and Text formats should be supported.

Multiple spam recognition algorithms are present and several could be used simultaneously.

Multiple weekly report approaches should be supported: XML, HTML files on filesystem;+ email with report attachment.

Page 24: 2. Design patterns. part #2

Do You see a need for the Command, NullObject design patterns?

Is Your vision changed somehow?

- How does it change Your design?

- What new considerations come up to mind?

- How do these changes impact application?

- How do these impact possible request changes?

Page 25: 2. Design patterns. part #2