尚学堂Java培训设计模式及实例.doc
北京尚学堂提供生产模式1.工厂方法模式(Factory Method)将程序中创建对象的操作,单独出来处理,创建一个产品的工厂接口,把实际的工作转移到具体的子类。大大提高了系统扩展的柔性,接口的抽象化处理给相互依赖的对象创建提供了最好的抽象模式。java view plaincopy1. public class TestFactoryMethod 2. public static void main(String args) 3. AnimalFactory af=new DogFactory(); 4. 5. Animal1 a=af.getAnimal(); 6. 7. 8. abstract class Animal1 9. 10. class Dog1 extends Animal1 11. 12. class Cat1 extends Animal1 13. 14. 15. 16. abstract class AnimalFactory 17. 18. public abstract Animal1 getAnimal(); 19. 20. class DogFactory extends AnimalFactory 21. public Animal1 getAnimal() 22. System.out.println("Dog"); 23. return new Dog1(); 24. 25. 26. class CatFactory extends AnimalFactory 27. public Animal1 getAnimal() 28. System.out.println("Cat"); 29. return new Cat1(); 30. 31. 2.抽象工厂模式(Abstract Factory)针对多个产品等级的情况,而工厂方法模式针对单一产品等级的情况。java view plaincopy1. import java.awt.*; 2. import javax.swing.*; 3. import java.awt.event.*; 4. public class TestAbstractFactory 5. public static void main(String args) 6. GUIFactory fact=new SwingFactory(); 7. Frame f=fact.getFrame(); 8. Component c1=fact.getButton(); 9. Component c2=fact.getTextField(); 10. f.setSize(500,300); 11. f.setLayout(new FlowLayout(); 12. f.add(c1); 13. f.add(c2); 14. f.setVisible(true); 15. f.addWindowListener(new WindowAdapter() 16. public void windowClosing(WindowEvent e) 17. System.exit(0); 18. 19. ); 20. abstract class GUIFactory 21. public abstract Component getButton(); 22. public abstract Component getTextField(); 23. public abstract Frame getFrame(); 24. 25. class AWTFactory extends GUIFactory 26. public Component getButton() 27. return new Button("AWT Button"); 28. public Frame getFrame() return new Frame("AWT Frame"); public Component getTextField() 29. return new TextField(20); 30. class SwingFactory extends GUIFactory 31. public Component getButton() 32. return new JButton("Swing Button"); 33. 34. public Frame getFrame() 35. return new JFrame("Swing Frame"); 36. public Component getTextField() 37. return new JTextField(20); 38. 39. 3.单例模式(Singleton) 改善全局变量和命名空间的冲突,可以说是一种改良了的全局变量。这种一个类只有一个实例,且提供一个访问全局点的方式,更加灵活的保证了实例的创建和访问约束。系统中只有一个实例,因此构造方法应该为私有 饿汉式:类加载时直接创建静态实例 懒汉式:第一次需要时才创建一个实例,那么newInstance方法要加同步 饿汉式比懒汉式要好,尽管资源利用率要差。但是不用同步。java view plaincopy1. public class TestSingleton 2. 3. public static void main(String args) 4. 5. 6. class ClassA /饿汉式 7. 8. private static ClassA i=new ClassA(); 9. 10. public static ClassA newInstance() 11. 12. return i; 13. 14. private ClassA() 15. 16. class ClassB /懒汉式 17. private static ClassB i=null; 18. public static synchronized ClassB newInstance() 19. if (i=null) i=new ClassB(); 20. return i; 21. 22. private ClassB() 23. 4.建造模式(Builder) 将一个对象的内部表象和建造过程分割,一个建造过程可以造出不同表象的对象。可简化为模版方法模式.java view plaincopy1. public class TestBuilder 2. 3. public static void main(String args) 4. 5. Builder b=new BuilderImpl1(); 6. 7. Director d=new Director(b); 8. 9. Product p=d.createProduct(); 10. 11. 12. 13. 14. interface Builder 15. void buildPart1(); 16. void buildPart2(); 17. void buildPart3(); 18. Product getProduct(); 19. 20. 21. class BuilderImpl1 implements Builder 22. public void buildPart1() 23. System.out.println("create part1"); 24. 25. public void buildPart2() 26. System.out.println("create part2"); 27. 28. public void buildPart3() 29. System.out.println("create part3"); 30. 31. 32. public Product getProduct() 33. return new Product(); 34. 35. 36. 37. class Director 38. Builder b; 39. public Director(Builder b) 40. this.b=b; 41. 42. public Product createProduct() 43. 44. b.buildPart1(); b.buildPart2(); 45. 46. b.buildPart3(); 47. 48. return b.getProduct(); 49. 50. 51. class Product 5.原型模式(ProtoType) 深拷贝:拷贝本对象引用的对象,有可能会出现循环引用的情况。可以用串行化解决深拷贝。写到流里再读出来,这时会是一个对象的深拷贝结果。ü 浅拷贝:只拷贝简单属性的值和对象属性的地址 ü通过一个原型对象来创建一个新对象(克隆)。Java中要给出Clonable接口的实现,具体类要实现这个接口,并给出clone()方法的实现细节,这就是简单原型模式的应用。 java view plaincopy1. import java.io.*; 2. public class TestClonealbe 3. 4. public static void main(String args) throws Exception 5. 6. Father f=new Father(); 7. User u1=new User("",f); 8. 9. User u2=(User)u1.clone(); 10. 11. System.out.println(u1=u2); 12. 13. System.out.println(u1.f=u2.f); 14. 15. 16. class User implements Cloneable,Serializable 17. String password; 18. Father f; 19. public User(String password,Father f) 20. this.password=password; 21. this.f=f; 22. 23. public Object clone() throws CloneNotSupportedException 24. /return super.clone(); 25. ObjectOutputStream out=null; 26. ObjectInputStream in=null; 27. try 28. ByteArrayOutputStream bo=new ByteArrayOutputStream(); 29. out = new ObjectOutputStream(bo); 30. out.writeObject(this); 31. out.flush(); 32. byte bs=bo.toByteArray(); 33. ByteArrayInputStream bi=new ByteArrayInputStream(bs); 34. in = new ObjectInputStream(bi); 35. Object o=in.readObject(); 36. return o; 37. 38. catch (IOException e) 39. e.printStackTrace(); 40. return null; 41. catch (ClassNotFoundException e) 42. e.printStackTrace(); 43. return null; 44. 45. finally 46. try 47. out.close(); 48. in.close(); 49. catch (IOException e) 50. e.printStackTrace(); 51. 52. 53. 54. 55. class Father implements Serializable 结构模式 如何把简单的类根据某种结构组装为大的系统 6.适配器模式(Adapter) 在原类型不做任何改变的情况下,用一个适配器类把一个接口转成另一个接口,扩展了新的接口,灵活且多样的适配一切旧俗。这种打破旧框框,适配新格局的思想,是面向对象的精髓。以继承方式实现的类的 Adapter模式和以聚合方式实现的对象的Adapter模式,各有千秋,各取所长。java view plaincopy1. public class TestAdapter 2. public static void main(String args) 3. USB mouse=new Mouse(); 4. PC pc=new PC(); 5. /pc.useMouse(mouse); 6. PS2 adapter=new USB2PS2Adapter(mouse); 7. pc.useMouse(adapter); 8. 9. 10. interface PS2 11. void usePs2(); 12. 13. interface USB 14. void useUsb(); 15. 16. class Mouse implements USB 17. public void useUsb() 18. System.out.println("通过USB接口工作"); 19. 20. 21. class PC 22. public void useMouse(PS2 ps2Mouse) 23. ps2Mouse.usePs2(); 24. 25. 26. 27. class USB2PS2Adapter implements PS2 28. private USB usb; 29. public USB2PS2Adapter(USB usb) 30. this.usb = usb; 31. 32. public void usePs2() 33. System.out.println("把对usePS2的方法调用转换成对useUSB的方法调用"); 34. usb.useUsb(); 35. 36. 7.组合模式(Composite) 把整体和局部的关系用树状结构描述出来,使得客户端把整体对象和局部对象同等看待。java view plaincopy1. import java.util.*; 2. 3. public class TestComposite 4. 5. public static void main(String args) 6. 7. Node n1=new LeafNode(3); 8. 9. Node n2=new LeafNode(4); 10. 11. Node n3=new LeafNode(6); 12. 13. Node n4=new LeafNode(5); 14. 15. Node n5=new LeafNode(2); 16. 17. Node n6=new LeafNode(9); 18. Node n7=new LeafNode(12); 19. Node n8=new LeafNode(7); 20. Node n9=new LeafNode(8); 21. Node c1=new CompositeNode(n1,n2,n3); 22. Node c4=new CompositeNode(n8,n9); 23. Node c3=new CompositeNode(n5,c4); 24. Node c2=new CompositeNode(n4,c3); 25. Node c5=new CompositeNode(n6,n7); 26. Node root=new CompositeNode(c1,c2,c5); 27. System.out.println(root.getValue(); 28. 29. 30. abstract class Node 31. public abstract int getValue(); 32. 33. class LeafNode extends Node 34. int value; 35. public LeafNode(int value) 36. this.value=value; 37. 38. public int getValue() 39. return value; 40. class CompositeNode extends Node 41. private List children=new ArrayList(); 42. public CompositeNode(Node. nodes) 43. for(Node n:nodes) 44. children.add(n); 45. public int getValue() 46. int result=0; 47. for(Node n:children) 48. result+=n.getValue(); 49. 50. return result; 51. 52. 8.装饰模式(Decorator) 以对客户透明的方式来扩展对象的功能。 用户根据功能需求随意选取组成对象的成分,通过方法的链式调用来实现。 可以给对象动态的增加功能,比继承灵活性更大。1. public class TestDecorator 2. 3. public static void main(String args) 4. 5. Teacher t1=new SimpleTeacher(); 6. Teacher t2=new CppTeacher(t1); 7. Teacher t3=new JavaTeacher(t2); 8. t3.teach(); 9. /t.teach(); 10. 11. 12. abstract class Teacher 13. 14. public abstract void teach(); 15. 16. class SimpleTeacher extends Teacher 17. public void teach() 18. System.out.println("Good Good Study, Day Day Up"); 19. 20. 21. class JavaTeacher extends Teacher 22. Teacher teacher; 23. public JavaTeacher(Teacher t) 24. this.teacher=t; 25. 26. public void teach() 27. teacher.teach(); 28. System.out.println("Teach Java"); 29. 30. 31. class CppTeacher extends Teacher 32. Teacher teacher; 33. 34. public CppTeacher(Teacher t) 35. 36. this.teacher=t; 37. public void teach() 38. teacher.teach(); 39. System.out.println("Teach C+"); 40. 41. 9.代理模式(Proxy) 用一个代理对象来作为另一个对象的代理,对客户来说是透明的。 存在一个抽象主题类,具体主题类和代理主题类都继承(实现)抽象主题,代理主题类中的方法会调用具体主题类中相对应的方法。10.享元模式(Flyweight Pattern) 对象的状态分为内蕴状态和外蕴状态。内蕴状态不随环境变化而变化,因此可以作成系统共享. 11.门面模式(Facade) 访问子系统的时候,通过一个Façade对象访问。Facade类是单例的。 客户代码只需要和门面对象通信,不需要和具体子系统内部的对象通信,使得他们之间的耦合关系减弱。 这次将表现层和逻辑层隔离,封装底层的复杂处理,为用户提供简单的接口,这样的例子随处可见。门面模式很多时候更是一种系统架构的设计,在我所做的项目中,就实现了门面模式的接口,为复杂系统的解耦提供了最好的解决方案。 12.桥梁模式(Bridge)将抽象和实现脱耦,使得二者可以单独变化。使得一个继承关系不承担两个变化因素.使用合成来代替继承的一种体现.1. public YuanUser(BankAccount account) 2. super(account); 3. 4. public void getMoney() 5. System.out.print("人民币"); 6. account.withdraw(); 7. 8. public void saveMoney() 9. System.out.print("人民币"); 10. account.deposit(); 11. 12. 13. class DollarUser extends BankUser 14. public DollarUser(BankAccount account) 15. super(account); 16. 17. public void getMoney() 18. System.out.print("美元"); 19. account.withdraw(); 20. 21. public void saveMoney() 22. System.out.print("美元"); 23. account.deposit(); 24. 25. 行为模式 描述如何在对象之间划分责任 13.策略模式(Strategy) 如同LayoutManager和具体的布局管理器的关系,在抽象策略类中定义方法,将易于变化的部分封装为接口,通常Strategy 封装一些运算法则,使之能互换。Bruce Zhang在他的博客中提到策略模式其实是一种“面向接口”的编程方法,真是恰如其分。 在具体策略子类中实现,客户代码根据不同的需要选择相应的具体类,例如电子商务中多种价格算法。 一种策略一旦选中,整个系统运行期是不变化的1. public class TestStrategy 2. public static void main(String args) 3. Strategy s1=new May1Strategy(); 4. Strategy s2=new June1Strategy(); 5. 6. Book b=new Book(100); 7. 8. b.setS(s2); 9. 10. System.out.println(b.getPrice(); 11. class Book 12. Strategy s; 13. public Book(double price) 14. this.price=price; 15. private double price; 16. public void setS(Strategy s) 17. this.s = s; 18. public double getPrice() 19. return price*s.getZheKou(); 20. interface Strategy 21. double getZheKou(); 22. class May1Strategy implements Strategy 23. public double getZheKou() 24. return 0.8; 25. class June1Strategy implements Strategy 26. public double getZheKou() 27. return 0.7; 14.模板方法(Template Method) 准备一个抽象类,把部分确定的逻辑定义在某些方法中,用其他抽象方法实现剩余的逻辑。不同子类对这些逻辑有不同的实现。 用法:定义多个抽象操作,定义并实现一个模板方法,将步骤放在这个具体方法里,推迟到子类实现。子类可以改变父类的可变部分,但不能改变模板方法所代表的顶级逻辑。1. public class TestTemplateMethod 2. public static void main(String args) 3. XiaoPin xp=new DaPuKe(); 4. xp.act(); 5. 6. 7. abstract class XiaoPin 8. public abstract void jiaoLiu(); 9. public abstract void xuShi(); 10. public abstract void gaoXiao(); 11. public abstract void shanQing(); 12. public final void act() 13. jiaoLiu(); 14. xuShi(); 15. gaoXiao(); 16. shanQing(); 17. 18. 19. class DaPuKe extends XiaoPin 20. public void jiaoLiu() 21. System.out.println("顺口溜"); 22. 23. public void xuShi() 24. System.out.println("火车除夕,老同学见面"); 25. 26. public void gaoXiao() 27. System.out.println("名片当作扑克"); 28. 29. public void shanQing() 30. System.out.println("马家军"); 31. 32. 15.观察者模式(Observer) 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。观察者和被观察者的分开,为模块划分提供了清晰的界限。在低耦合的对象间完成协调。 Java中的事件模型就是一个应用。16.迭代器模式(Iterator) 类似于集合中的Iterator,使用迭代器来统一不同集合对象的遍历方式。在绝大多数的系统中,都会用到数组、集合、链表、队列这样的类型,关心迭代模式的来龙去脉非常有必要。在遍历算法中,迭代模式提供了遍历的顺序访问容 器,GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。.NET中就是使用了迭代器来 创建用于foreach的集合。1. public class TestIterator 2. public static void main(String args) 3. Stack s=new Stack(); 4. s.push("Liucy"); 5. s.push("Huxz"); 6. s.push("George"); 7. LinkedList l=new LinkedList(); 8. l.addFirst("Liucy"); 9. l.addFirst("Huxz"); 10. l.addFirst("George"); 11. print(l.iterator(); 12. 13. public static void print(Itr it) 14. while(it.hasNext() 15. System.out.println(it.next(); 16. 17. 18. 19. interface Itr 20. boolean hasNext(); 21. Object next(); 22. 23. class Stack 24. Object os=new Object10; 25. int index=0; 26. private void expand() 27. Object os2=new Objectos.length*2; 28. System.arraycopy(os,0,os2,0,os.length); 29. os=os2; 30. 31. public void push(Object o) 32. if (index=os.length) expand(); 33. osindex=o; 34. index+; 35. 36. public Object pop() 37. 38. index-; 39. 40. Object o=osindex; 41. 42. osindex=null; 43. 44. return o; 45. 46. private class StackItr implements Itr 47. 48. int cursor=0; 49. 50. public boolean hasNext() 51. return cursor 52. public Object next() 53. 54. return oscursor+; 55. 56. 57. 58. public Itr iterator() 59. return new StackItr(); 60. class LinkedList 61. private class Node 62. Object o; 63. Node next; 64. public Node(Object o) 65. this.o=o; 66. 67. public void setNext(Node next) 68. this.next=next; 69. 70. public Node getNext() 71. return this.next; 72. 73. Node head; 74. public void addFirst(Object o) 75. Node n=new Node(o); 76. n.setNext(head); 77. 78. head=n; 79. 80. 81. public Object removeFirst() 82. 83. Node n=head; 84. head=head.getNext(); 85. return n.o; 86. 87. class LinkedListItr implements Itr 88. 89. Node currentNode=head; 90. 91. public boolean hasNext() 92. 93. return this.cur