Beruflich Dokumente
Kultur Dokumente
Gang of Four
o Pattern-based design was introduced into architecture and engineering in the 1950's o Almost immediately, software engineers began using patterns for designing software o It wasn't until a group of four researchers combined forces that pattern-based design became well-known and commonplace
o This group was known as the gang of four (GoF)
Gang of Four
o The gang of four (GoF) is:
o Erich Gamma o Richard Helm o Ralph Johnson o John Vlissides
o They are the authors of the famous text "Design Patterns: Elements of Reusable Object-Oriented Software"
Pattern Quotes
o A pattern is an idea that has been useful in one practical context and will probably be useful in others
o Martin Fowler
o A pattern is a three-part rule, which expresses a relation between a certain context, a problem, and a solution
o Christopher Alexander
o Architects and designers can more easily communicate their designs to their developers
o How it works:
o The Abstract Factory only determines which Concrete Factory it will use o The Concrete Factory actually creates the appropriate object o Normally, the appropriate Concrete Factory is determined and created at run-time (once)
o Concrete Factory (one per object type): Knows how to create one specific type of object
o e.g. public class UNIXButtonFactory extends ButtonFactory { public Button getInstance() { Button button = new UNIXButton(); // UNIX-specific stuff for buttons here return button; } } ButtonFactory factory = ; Button button = factory.getInstance();
request
User
Button UNIXButtonFactory
getInstance()
WindowsButtonFactory
getInstance()
UNIXButton
WindowsButton
Prototype: Example
// initialize the prototype UMLClass classPrototype = new UMLClass(); classPrototype.setName(NewClass); classPrototype.setAttributes(new ArrayList<Attribute>()); classPrototype.setMethods(new ArrayList<Method>()); etc // create an instance, and customize it UMLClass newClass1 = (UMLClass)classPrototype.clone(); newClass1.setName(Customer); newClass1.setAbstract(true); Attribute attribute1 = new Attribute(); attribute1.setName(firstName); attribute1.setType(String); newClass1.getAttributes.add(attribute1); etc
Prototype: Example
User
BasePrototype
clone()
ClassPrototype
clone()
UseCasePrototype
clone()
o e.g. In Java, if you want to read bytes from a file, you use one of the 'XYZInputStream' classes
o If you want to read characters (including multibyte characters) from a file, you use one of the 'XYZReader' classes o Any 'XYZInputStream' class can be treated like an 'XYZReader' class by applying an adapter called 'InputStreamReader' which converts bytes to characters
o Another example of an Adapter would be a program that sends input to and receives output from a legacy application
o This is typically done using standard in/out o This is done frequently to update old (but operational and well-tested) software to include features such as:
o An updated GUI interface to a text-based application o A web interface
Adapter: Example
o As an example, assume our company switches database vendors
o Our software has isolated database operations to one module o That module makes calls to a well-known API o Our new database has its own API, which has similar functionality o However, the interfaces are not the same o What do we do?
Adapter: Example
User
OldDBAPIInterface
GetObject(String key)
DBAdapter
GetObject(String key)
NewDBAPI
FindObject(String hashedKey)
Adapter: Example
public class DBAdapter { public Object GetObject(String key) { String hashedKey = HashingUtils.hash(key); return FindObject(hashedKey); } }
o A Faade might be used to combine the functionality of these classes into a unified interface
Faade: Example
AccountService
User createAccount() deposit() withdraw()
TransactionService Faade
createAccount() deposit() withdraw() addTransaction() applyForLoan() addTransaction()
LoanService
applyForLoan()
Faade: Example
public class BankFaade { private AccountService accountService; private TransactionService transactionService; private LoanService loanService; public addAccount(Account account) { accountService.addAccount(account); } public deposit(int accountId, float amount) { accountService.deposit(accountId, amount); } public withdraw(int accountId, float amount) { accountService.withdraw(accountId, amount); } public addTransaction(Transaction tx) { transactionService.addTransaction(tx); } public applyForLoan(Customer cust, LoanDetails loan) { loanService.apply(cust, loan); } }
Proxy: Example
AccountService
{abstract}
User
AccountServiceProxy
addAccount() deposit() withdraw()
AccountServiceImpl
addAccount() deposit() withdraw()
Proxy: Example
public class AccountServiceProxy implements AccountService { public void addAccount(Account account) { InvokeMessage message = new InvokeMessage(); message.setMethodName(addAccount); message.setArgumentCount(0); byte[] serializedAccount = serialize(account); message.setArgument(0, serializedAccount); send(message); } private byte[] serialize(Account account) { } private void send(InvokeMessage message) { } }
Iterator: Example
{abstract}
Iterator
ArrayIterator
First() : Item Next() : Item MoreElements() : Bool
LinkedListIterator
First() : Item Next() : Item MoreElements() : Bool
Item
Array
LinkedList
Iterator: Example
public class ArrayIterator implements Iterator { private String[] data; private int index; public ArrayIterator(String[] data) { this.data = data; this.index = 0; } public String first() { index = 0; return data[0]; } public String next() { index++; return data[index]; } public boolean moreElements() { if (index >= data.length) return false; return true; }
Iterator: Example
public class LinkedListIterator implements Iterator { private LinkedListElement first; private LinkedListElement current; public LinkedListIterator (LinkedListElement first) { this.first = first; this.current = first; } public String first() { return first.value(); } public String next() { current = current.getNext(); return current.value(); } public boolean moreElements() { if (current.getNext() == null) return false; return true; }
Observer: Example
ObservableBugList
{abstract} observers
BugObserver
{abstract} BugAdded() BugStatusChanged()
AddObserver() RemoveObserver()
ObservableBugListImpl
bugs: List<Bug> AddObserver() RemoveObserver()
MyBugObserver
BugAdded() BugStatusChanged()
Observer: Example
public abstract class ObservableBugList { private ArrayList<BugObserver> observers; public void addObserver(BugObserver observer) { observers.add(observer); } public void removeObserver(BugObserver observer) { observers.remove(observer); } public abstract notifyBugAdded(Bug bug); public abstract notifyBugStatusChanged(Bug bug);
public MyBugObserver implements BugObserver { public void bugAdded(BugAddedEvent event) { } public void bugStatusChanged(BugStatusChangedEvent e) { } }
o These objects (Observers) may change over time o The object being watched (observable) does not necessarily need to know about the objects observing it
o A program that turns HTML files into a tree data structure might do one thing in these methods, whereas a browser (which draws the HTML elements as its reads the file) might do something different
ParseXMLFile(filename: String) processStartTag(tagName: String) processArgument(tagName: String, argumentName: String, argumentValue: String) processBody(tagName: String, bodyText: String processEndTag(tagName: String)
ConvertHTMLToText
processStartTag(tagName: String) processArgument(tagName: String, argumentName: String, argumentValue: String) processBody(tagName: String, bodyText: String processEndTag(tagName: String)