Archive for the ‘design pattern’ Category
[design pattern] Observer Pattern
Posted August 25, 2013
on:花一个小时看完了书,自己写了一遍,基本明白咋回事了。需要两个接口,Source and Listener(我自己瞎起的名字),Source是那个变的,Listener是那个被通知的。
- Source:
- 一个private List<Listener> listeners;
- 一个registerListener(Listener l)函数,把l加到listeners里面去
- 一个removeListener(Listener l)函数,把l从listeners里面删掉
- 一个notifyAllListeners()函数,里面对于每个listener, call listener的update()。不需要加parameter,只是通知list里面的监听者“有东西改了”, 具体改的是啥,让Listener里面的update函数自己从source reference里面pull去。
- Listener:
- 一个private Source s
- 一个constructor that takes a Source obj, 初始的时候就把“听谁”(source)给联系上。
- 一个update()函数,里面把Source s cast成自己真监听的concrete type(比如“杂志”),然后从这个s里面pull data。
重点:
- Source的notify函数只是负责告诉listeners,有变动了,你们来pull我的data吧。不用真把动的是哪个data传过去。当然也可以pass一个para说明到底是哪个data变了,client好知道具体pull哪个data。
- Listener的update()函数只被source的notify叫,然后函数里面取出当前obj的source reference, cast, pull data and use it.
- Register这些东西都是在main函数里叫的。
public class Magazine implements Source { private List<Listner> subscribers; private String editorName; public String getEditorName() { return editorName; } public Magazine () { this.subscribers = new ArrayList<Listner>(); this.editorName = "Christina"; } public void changeEditorName(String newEditor) { this.editorName = newEditor; notifyListners(); } @Override public void registerListner(Listner l) { subscribers.add(l); } @Override public void removeListner(Listner l) { if (subscribers.contains(l)) subscribers.remove(l); } @Override public void notifyListners() { for (Listner subscriber : subscribers) { subscriber.update(); } } public static void main(String[] args) { Magazine m = new Magazine(); Subscriber sub1 = new Subscriber(m, "sub1"); Subscriber sub2 = new Subscriber(m, "sub2"); m.registerListner(sub1); m.registerListner(sub2); m.changeEditorName("Meredith"); m.removeListner(sub2); m.changeEditorName("Alex"); } } public class Subscriber implements Listner { private Source magazine; private String name; private String currentEditorName; public Subscriber(Source s, String name) {//this is how one listner bind to one subject. this.name = name; this.magazine = s; } @Override public void update() { //each subscriber knows the subject is a magazine, so it can cast it's subject to magazine and use this subject's properties. String newEditor = ((Magazine) this.magazine).getEditorName(); this.currentEditorName = newEditor; System.out.println(name + ": Updating editor name to " + newEditor); }
[design pattern] iterator pattern
Posted August 22, 2013
on:- In: design pattern | 面经
- Leave a Comment
Iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container’s elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled. It provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
这个模式可以保证不同的容器统一用一个interface来traverse,比如正常用for的话,array的traverse要用arr[i],arrayList的要用get(i),map更是得map.entrySet.get..,各种syntax不同,所以即使对每个element干的事儿一样,traverse也要写三遍,太麻烦了。如果用iterator,所有traverse统一用next()就行了。具体iterator是怎么next()的,自己再在容器里面写(大不了就三个容器都implement MyContainer,全写一遍next()函数对于该容器是怎么取下一个的。反正一劳永逸,next()一旦定义了,以后任何client都可以随便用)。其实对于ArrayList, Map之类这么长用的,java已经都给写好了iterator (e.g. List list = new List(); Iterator it = list.iterator();)。下面是例子:
- Container要implement Iterable<Type>
- Container里面写个implement Iterator<Type> 的iterator inner class
- Container里要有个iterator() method用来生成一个iterator
- Inner iterator class里面implement next(), hasNext()两个method.
public class TreeInPreOrderIterable implements Iterable<TreeNode> { private TreeNode root; private class TreeIterator implements Iterator<TreeNode> { Stack<TreeNode> stack; private TreeIterator(TreeNode root) { stack = new Stack<TreeNode>(); if (root != null) stack.push(root); } @Override public TreeNode next() { if (hasNext()) { TreeNode pop = stack.pop(); if (pop.right != null) stack.push(pop.right); if (pop.left != null) stack.push(pop.left); return pop; } else { throw new NoSuchElementException(); } } @Override public boolean hasNext() { return !stack.isEmpty(); } } @Override public Iterator<TreeNode> iterator() { return new TreeIterator(this.root); } }