Dynamic Design Patterns Adaptive Design in Uncertain Diverse Environment Stephen Wang This book is for sale at http://leanpub.com/dynamic_design_patterns This version was published on 2013-08-22 This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and many iterations to get reader feedback, pivot until you have the right book and build traction once you do. 2013 Stephen Wang
Tweet This Book! Please help Stephen Wang by spreading the word about this book on Twitter! The suggested hashtag for this book is #Software Design. Find out what other people are saying about the book by clicking on this link to search for this hashtag on Twitter: https://twitter.com/search/#softwaredesign
Contents Acknowledgement......................................... 1 Introduction............................................ 2 Section 1. Optimum Pattern................................... 4 Further reading.......................................... 16
Acknowledgement Below is a list of who helped editing this book: Seaborn Lee. Thanks. Thank my family, without their support, this book could not be published. This book referred the book Design Patters¹ ¹http://en.wikipedia.org/wiki/Design_Patterns
Introduction Diversity Software have diverse features, that allows different people have different data. Object oriented programming is one of the technique makes it possible to write software to adapt the diversity of software. A system may have many operations share one same interface, may have many data share some fields. The object oriented technique allows define interfaces and classes for process these diversities. However, nowadays, software become more diverse that makes program more complicated. These diversity are uncertain in some circumstances, the rules are predefined, program runs with these predefined rules makes the uncertainty possible. Uncertainty Entertainment Game applications makes fun with uncertainty, not only the random numbers, but also the diversity of conditions. Business Business changes frequently, software need scalability to fit frequently changed requirements, and if possible, auto-adaptive is desired. Customize In the age of Internet, internet users want to customize the online services they are using. Therefore the online service applications need to be customizable. Customization makes user happy, but also bring technical challenge. Object oriented programming requires classes share method signature with its interface, classes inherit from one interface share method signature. But, in uncertain circumstance, processes are very different, then it is very difficult to unify the method signature of many classes. Adaptive programming techniques is needed to fit in these uncertain diverse circumstances.
Introduction 3 Predictability In uncertain diverse circumstances, only rules are predefined, the instances, behaviors, data are not predictable. In predictable circumstances, just apply some interfaces, and implementations can handle with the diversity, but in unpredictable circumstances, programmers cannot write an exact instance for next step, they can write a piece of codes that generate the desired instance according to the predefined rules. And because the parameters of rules are changeable, the difficulty of programming is raised. Dynamic Design Patterns Design patterns solve the diversity issues. But the uncertainty of diversity can not be solved by design patterns only. Dynamic design patterns are designed to solve some specific uncertain diverse issues. As implied in its name, dynamic design patterns are still design patterns, they are based on design patterns, and added some diversity to fit with the uncertainty of requirements.
Section 1. Optimum Pattern Description Chain of responsibility pattern² allows pass parameter through a chain of classes. Each step in the chain would do with the parameter, and return a result until the end of the chain. But, if the chain is not predictable, the chain can not be predefined. It needs to create handler in the chain dynamically according to the predefined rules, call the created handler continuously until the exit condition is met. This pattern is used to optimize strategies, so it is also called Optimum Pattern. UML The UML of optimum pattern is as follows: Structural Sample ²http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
Section 1. Optimum Pattern 5 This structural sample demonstrates the optimum pattern, which generates dynamic handler until the exit condition is met. Handler The interface of responsibility handler. HandlerFactory The factory creates concrete handler dynamically according to predefined rules. ConcreteHandlerA, ConcreteHanlderB The two concrete handlers to execute the concrete process. NullHandler The Null Object Pattern object that handle request in dummy. Client The client that call other classes. Text The aggregate object that contains the target object. 1 public interface Handler { 2 public Text handle(text text); 3 } 1 public class HandlerFactory { 2 3 public static Handler create(string params) { 4 int aindex = params.lastindexof("a"); 5 int bindex = params.lastindexof("b"); 6 if (aindex >= 0 bindex >= 0) { 7 if (aindex > bindex) { 8 return new ConcreteHandlerA(); 9 } else { 10 return new ConcreteHandlerB(); 11 } 12 } else { 13 return new NullHandler(); 14 } 15 } 16 }
Section 1. Optimum Pattern 6 1 public class ConcreteHandlerA implements Handler { 2 public Text handle(text text) { 3 int index = text.find("a"); 4 return text.reduce(index); 5 } 6 } 1 public class ConcreteHandlerB implements Handler { 2 public Text handle(text text) { 3 int index = text.find("b"); 4 return text.reduce(index); 5 } 6 } 1 public class NullHandler implements Handler { 2 public Text handle(text text) { 3 return text; 4 } 5 } 1 public class Client { 2 public void dynamicchain(text text) { 3 while (text.hasmore()) { 4 Handler next = HandlerFactory.create(text.text); 5 next.handle(text); 6 } 7 } 8 9 public static void main(string[] args) { 10 Client client = new Client(); 11 client.dynamicchain(new Text("aba2fdac23fabc")); 12 } 13 }
Section 1. Optimum Pattern 7 1 public class Text { 2 public String text; 3 4 public Text(String t) { 5 this.text = t; 6 } 7 8 public boolean hasmore() { 9 return!text.isempty(); 10 } 11 12 public int find(string target) { 13 int index = text.lastindexof(target); 14 System.out.println(text.substring(index)); 15 return index; 16 } 17 18 public Text reduce(int index) { 19 String reduced = ""; 20 if (index > 0) { 21 reduced = text.substring(0, index); 22 } else { 23 reduced = ""; 24 } 25 text = reduced; 26 return this; 27 } 28 } The result of the source above is : 1 bc 2 a 3 ac23f 4 a2fd 5 b 6 a Real World Sample A book store is going to have a promotion to a series of books, the discount strategy is defined as below :
Section 1. Optimum Pattern 8 5 different books in set, 75%, 4 different books in set, 80%, 3 different books in set, 90%, 2 different books in set, 95%, 1 book in set, 100%. each book s price is 8 EUR. Then how much would be the cheapest price after pick books as below: book #1-2 copies book #2-2 copies book #3-2 copies book #4-1 copy book #5-1 copy In this case, the best strategy is not predefined, but the rule is predefined. Pick as more as possible, and mind that 4 copies + 4 copies is cheaper than 5 copies + 3 copies. 1 import java.util.list; 2 3 public interface CartStrategy { 4 public Cart handle(cart cart, List<Strategy> strategies); 5 } 1 import java.util.list; 2 3 public class MostCartStrategy implements CartStrategy { 4 public Cart handle(cart cart, List<Strategy> strategies) { 5 Strategy strategy = cart.pickmost(); 6 strategies.add(strategy); 7 return cart; 8 } 9 }
Section 1. Optimum Pattern 9 1 import java.util.list; 2 3 public class SmartCartStrategy implements CartStrategy { 4 public Cart handle(cart cart, List<Strategy> strategies) { 5 Strategy before = cart.pick4(); 6 Strategy after = cart.pick4(); 7 strategies.add(before); 8 strategies.add(after); 9 return cart; 10 } 11 } 1 import java.util.list; 2 3 public class NullCartStrategy implements CartStrategy { 4 public Cart handle(cart cart, List<Strategy> strategies) { 5 return cart; 6 } 7 } 1 public class CartStrategyFactory { 2 3 public static CartStrategy create(cart cart) { 4 if (cart.has44()) { 5 return new SmartCartStrategy(); 6 } else if (!cart.isempty()) { 7 return new MostCartStrategy(); 8 } else { 9 return new NullCartStrategy(); 10 } 11 } 12 }
Section 1. Optimum Pattern 10 1 public class Book { 2 public String name; 3 public float price; 4 5 public Book(String n, float p) { 6 this.name = n; 7 this.price = p; 8 } 9 } 1 import java.util.*; 2 3 public class Cart { 4 5 Map<Book, Integer> books = new HashMap<Book, Integer>(); 6 7 public void add(book book, Integer count) { 8 if (books.containskey(book)) { 9 books.put(book, books.get(book) + count); 10 } else { 11 books.put(book, count); 12 } 13 } 14 15 public boolean isempty() { 16 if (books.isempty()) { 17 return true; 18 } 19 Iterator iterator = books.keyset().iterator(); 20 while (iterator.hasnext()) { 21 Book book = (Book) iterator.next(); 22 if (books.get(book)!= 0) { 23 return false; 24 } 25 } 26 return true; 27 } 28 29 public boolean has44() { 30 //44 = 535 different books, at least 3 of them is more than 2 copies 31 //44 = 44 (4 different books, all are more than 2 copies) 32 List<Book> onecopy = new ArrayList<Book>();
Section 1. Optimum Pattern 11 33 List<Book> morecopies = new ArrayList<Book>(); 34 35 Iterator iterator = books.keyset().iterator(); 36 while (iterator.hasnext()) { 37 Book book = (Book)iterator.next(); 38 Integer count = books.get(book); 39 if (count > 1) { 40 morecopies.add(book); 41 } else { 42 onecopy.add(book); 43 } 44 } 45 46 if (onecopy.size() + morecopies.size() == 5 && morecopies.size() >= 3 47 morecopies.size() >= 4) { 48 return true; 49 } 50 51 return false; 52 } 53 54 public Strategy pick4() { 55 Strategy strategy = new Strategy(); 56 57 if (countbooktype() == 4) { 58 return pickmost(); 59 } else { 60 Book least = findleastbook(); 61 for (Book book : BookFlyweight.books) { 62 if (hasbook(book) &&!book.equals(least)) { 63 pickbook(strategy, book); 64 } 65 } 66 } 67 68 return strategy; 69 } 70 71 private int countbooktype() { 72 int count = 0; 73 for (Book book : BookFlyweight.books) { 74 if (hasbook(book)) {
Section 1. Optimum Pattern 12 75 count ++; 76 } 77 } 78 System.out.println("count = " + count); 79 return count; 80 } 81 82 private Book findleastbook() { 83 int min = -1; 84 Book least = null; 85 Iterator keys = books.keyset().iterator(); 86 while (keys.hasnext()) { 87 Book book = (Book)keys.next(); 88 int count = books.get(book); 89 if (min == -1) { 90 min = count; 91 least = book; 92 } 93 if (min > count) { 94 least = book; 95 min = count; 96 } 97 } 98 return least; 99 } 100 101 public Strategy pickmost() { 102 Strategy strategy = new Strategy(); 103 104 if (hasbook(bookflyweight.book_1)) { 105 pickbook(strategy, BookFlyweight.BOOK_1); 106 } 107 if (hasbook(bookflyweight.book_2)) { 108 pickbook(strategy, BookFlyweight.BOOK_2); 109 } 110 if (hasbook(bookflyweight.book_3)) { 111 pickbook(strategy, BookFlyweight.BOOK_3); 112 } 113 if (hasbook(bookflyweight.book_4)) { 114 pickbook(strategy, BookFlyweight.BOOK_4); 115 } 116 if (hasbook(bookflyweight.book_5)) {
Section 1. Optimum Pattern 13 117 pickbook(strategy, BookFlyweight.BOOK_5); 118 } 119 120 return strategy; 121 } 122 123 private boolean hasbook(book book) { 124 if (books.containskey(book)) { 125 if (books.get(book) == 0) { 126 return false; 127 } 128 return true; 129 } 130 return false; 131 } 132 133 private void pickbook(strategy strategy, Book book) { 134 strategy.add(book); 135 books.put(book, books.get(book) - 1); 136 } 137 } 1 import java.util.hashmap; 2 import java.util.iterator; 3 import java.util.map; 4 5 public class Strategy { 6 Map<Book, Integer> books = new HashMap<Book, Integer>(); 7 8 public void add(book book) { 9 books.put(book, 1); 10 } 11 12 public String tostring() { 13 String text = ""; 14 Iterator iterator = books.keyset().iterator(); 15 while (iterator.hasnext()) { 16 Book book = (Book)iterator.next(); 17 text += book.name + "@" + books.get(book) + ","; 18 } 19 return text; 20 }
Section 1. Optimum Pattern 14 21 22 public float price() { 23 float price = 0.0f; 24 Iterator iterator = books.keyset().iterator(); 25 while (iterator.hasnext()) { 26 Book book = (Book)iterator.next(); 27 price += book.price; 28 } 29 return price * discountrate(); 30 } 31 32 public float discountrate() { 33 switch (books.keyset().size()) { 34 case 5: 35 return 0.75f; 36 case 4: 37 return 0.8f; 38 case 3: 39 return 0.9f; 40 case 2: 41 return 0.95f; 42 default: 43 return 1f; 44 } 45 } 46 } 1 import java.util.arraylist; 2 import java.util.list; 3 4 public class Client { 5 6 public static void main(string[] args) { 7 Cart cart = new Cart(); 8 cart.add(bookflyweight.book_1, 2); 9 cart.add(bookflyweight.book_2, 2); 10 cart.add(bookflyweight.book_3, 2); 11 cart.add(bookflyweight.book_4, 1); 12 cart.add(bookflyweight.book_5, 1); 13 14 List<Strategy> strategies = new ArrayList<Strategy>(); 15
Section 1. Optimum Pattern 15 16 while (!cart.isempty()) { 17 CartStrategy strategy = CartStrategyFactory.create(cart); 18 cart = strategy.handle(cart, strategies); 19 } 20 float price = 0.0f; 21 for (Strategy strategy : strategies) { 22 System.out.println(strategy.toString()); 23 price += strategy.price(); 24 } 25 System.out.println("The amount is : " + price); 26 } 27 } 1 public class BookFlyweight { 2 public static final Book BOOK_1 = new Book("#1", 8); 3 public static final Book BOOK_2 = new Book("#2", 8); 4 public static final Book BOOK_3 = new Book("#3", 8); 5 public static final Book BOOK_4 = new Book("#4", 8); 6 public static final Book BOOK_5 = new Book("#5", 8); 7 } The result of the source above is : 51.2
Further reading Pool Pattern The pattern to access subjects in a limited size pool. Policy Pattern The pattern to work through a policy not a process. Panel Pattern The pattern to ON/OFF switches on a panel. Dispatcher Pattern The pattern to dispatch request to an instance according predefined rules. Coordinator Pattern The pattern to coordinate subjects running under a global circumstance. Dynamic Adapter Pattern The pattern to make adapter by conditions. Dynamic Command Pattern The pattern to execute commands in context.