Java23种设计模式
Posted dielianhua
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java23种设计模式相关的知识,希望对你有一定的参考价值。
设计模式并非类库,但类库中使用了设计模式
● java.util.Iterator是用于遍历元素集合的接口,这里使用了Iterator模式
● java.util.Observer是用于观察对象状态变化的接口,这里使用了Observer模式
● 以下的方法中使用了Factory Method模式
java.util.Calender类的getInstance方法
java.secure.SecureRandom类的getInstance方法
java.text.NumberFormat类的getInstance方法
● java.awt.Component和java.awt.Container这两个类中使用了Composite模式
第一部分 适应设计模式
第一章:Iterator模式---一个一个遍历:用于在数据集合中按照顺序遍历集合,迭代器
Iterator模式中的登场角色
◆Iterator(迭代器)
◆ConcreteIterator(具体的迭代器)
◆Aggregate(集合)
◆ConcreteAggregate(具体的集合)
不管实现如何变化,都可以使用Iterator:设计模式的作用就是帮助我们编写可复用性的类。
所谓的“可复用”,就是指将类实现为“组件”,当一个组件发生改变时,不需要对其他的组件进行修改或是只需很小的修改即可应对。
难以理解抽象类和接口:不要只使用具体类来编程,要优先使用抽象类和接口来编程
Aggregate和Iterator的对应
容易弄错“下一个”
next方法是“返回当前的元素,并指向下一个元素”
还容易弄错“最后一个”
hasNext方法在返回最后一个元素前会返回true,当返回了最后一个元素后则返回false,作用是“确认接下来是否可以调用next方法”
多个Iterator
“将遍历功能置于Aggregate角色之外”是Iterator模式的一个特征。
根据这个特征,可以针对一个ConcreteAggregate角色编写多个ConcreteIterator角色。
迭代器的种类多种多样
遍历的方法 ?从最后开始向前遍历 ?既可以从前向后遍历,也可以从后向前遍历(既有next方法也有previous方法)
?指定下标进行“跳跃式”遍历
不需要deleteIterator
没有被使用的对象实例将会自动被删除(垃圾回收,GC)。
相关的设计模式
◆Visitor模式
Iterator模式是从集合中一个一个取出元素进行遍历,但是并没有在Iterator接口中声明对取出的元素进行何种处理。
Visitor模式则是在遍历元素集合的过程中,对元素进行相同的处理。
◆Composite模式
Composite模式是具有递归结构的模式,在其中使用Iterator模式比较困难。
◆Factory Method模式
在Iterator方法中生成Iterator的实例时可能会使用Factory Method模式。
1 /** 2 *定义Book类,定义构造方法并初始化 3 */ 4 public class Book 5 { 6 private String name; 7 public Book(String name) { 8 this.name = name; 9 } 10 public String getName() { 11 return name; 12 } 13 }
1 /** 2 *定义BookShelf类 3 */ 4 import java.util.ArrayList; 5 6 /*public class BookShelf implements Aggregate 7 { 8 private Book[] books; 9 private int last = 0; 10 public BookShelf(int maxsize) { 11 this.books = new Book[maxsize]; 12 } 13 public Book getBookAt(int index) { 14 return books[index]; 15 } 16 public void appendBook(Book book) { 17 this.books[last] = book; 18 last++; 19 } 20 public int getLength() { 21 return last; 22 } 23 public Iterator iterator() { 24 return new BookShelfIterator(this); 25 } 26 }*/ 27 /** 28 *当书的数量超过最初指定的书架容量时,就无法继续向书架中添加书本了。 29 *编写用java.util.ArrayList修改程序 30 */ 31 public class BookShelf implements Aggregate 32 { 33 private ArrayList books; 34 public BookShelf(int initialsize) { 35 this.books = new ArrayList(initialsize); 36 } 37 public Book getBookAt(int index) { 38 return (Book)books.get(index); 39 } 40 public void appendBook(Book book) { 41 books.add(book); 42 } 43 public int getLength() { 44 return books.size(); 45 } 46 public Iterator iterator() { 47 return new BookShelfIterator(this); 48 } 49 }
1 /** 2 *表示集合的接口,该方法会生成一个用于遍历集合的迭代器 3 */ 4 public interface Aggregate 5 { 6 public abstract Iterator iterator(); 7 }
1 /** 2 *定义Iterator接口用于遍历集合中的元素 3 *其作用相当于循环语句中的循环变量 4 */ 5 public interface Iterator 6 { 7 /*当集合中存在下一个元素时,该方法返回true; 8 当集合中不存在下一个元素,即已经遍历至集合末尾时,该方法返回false 9 hasNext方法主要用于循环终止条件*/ 10 public abstract boolean hasNext(); 11 /*该方法返回的是集合中的一个元素,也可以返回下一个元素*/ 12 public abstract Object next(); 13 }
1 /** 2 *定义BookShelfIterator类 3 */ 4 public class BookShelfIterator implements Iterator 5 { 6 private BookShelf bookShelf; 7 private int index; 8 public BookShelfIterator(BookShelf bookShelf) { 9 this.bookShelf = bookShelf; 10 this.index = 0; 11 } 12 public boolean hasNext() { 13 if(index < bookShelf.getLength()) { 14 return true; 15 } else { 16 return false; 17 } 18 } 19 public Object next() { 20 Book book = bookShelf.getBookAt(index); 21 index++; 22 return book; 23 } 24 }
1 /** 2 *测试类Main 3 */ 4 public class Main 5 { 6 public static void main(String[] args) { 7 BookShelf bookShelf = new BookShelf(4); 8 bookShelf.appendBook(new Book("Around the World in 80 Days")); 9 bookShelf.appendBook(new Book("Bible")); 10 bookShelf.appendBook(new Book("Cinderella")); 11 bookShelf.appendBook(new Book("Daddy-Long-Legs")); 12 bookShelf.appendBook(new Book("East of Eden")); 13 bookShelf.appendBook(new Book("Frankenstein")); 14 bookShelf.appendBook(new Book("Gulliver‘s Travels")); 15 bookShelf.appendBook(new Book("Hamlet")); 16 Iterator it = bookShelf.iterator(); 17 while(it.hasNext()) { 18 Book book = (Book)it.next(); 19 System.out.println(book.getName()); 20 } 21 } 22 }
第二章:Adapter模式---加个“适配器”以便于复用
●类适配器模式(使用继承的适配器)
●对象适配器模式(使用委托的适配器)
Adapter模式中的登场角色
◆Target(对象)-->Print类
◆Client(请求者)-->Main类
◆Adaptee(被适配)-->Banner类
◆Adapter(适配)-->PrintBanner类
在类适配器模式中,Adapter角色通过继承来使用Adaptee角色,而在对象适配器模式中,Adapter角色通过委托来使用Adaptee角色。委托指将某个方法中的实例处理交给其他实例的方法。
什么时候使用Adapter模式
Adapter模式会对现有的类进行适配,生成新的类。通过该模式可以很方便地创建我们需要的方法群。当出现Bug时,由于我们很明确地知道Bug不在现有的类(Adaptee角色)中,所以只需调查扮演Adapter角色的类即可。这样一来,代码问题的排查就会变得非常简单。
如果没有现成的代码
使用Adapter模式可以在完全不改变现有代码的前提下使现有代码适配于新的接口(API)。此外,在Adapter模式中,并非一定需要现成的代码。只要知道现有类的功能,就可以编写出新的类。
版本升级与兼容性
功能完全不同的类
Adaptee角色和Target角色的功能完全不同时,Adapter模式无法使用。
相关的设计模式
◆Bridge模式
Adapter模式用于连接接口(API)不同的类,而Bridge模式则用于连接类的功能层次结构与实现层次结构。
◆Decorator模式
Adapter模式用于填补不同接口(API)之间的缝隙,而Decorator模式则是在不改变接口(API)的前提下增加功能。
1 /** 2 *Banner类 3 */ 4 public class Banner 5 { 6 private String string; 7 public Banner(String string) { 8 this.string = string; 9 } 10 public void showWithParen() { 11 System.out.println("(" + string + ")"); 12 } 13 public void showWithAster() { 14 System.out.println("*" + string + "*"); 15 } 16 }
1 2 /** 3 *定义FileIO接口(Target角色)中声明了将属性集合保存至文件的方法, 4 *并假设FileProperties类会实现这个FileIO接口 5 */ 6 import java.io.*; 7 public interface FileIO 8 { 9 public void readFormFile(String filename) throws IOException; 10 public void writeToFile(String filename) throws IOException; 11 public void setValue(String key, String value); 12 public String getValue(String key); 13 }
1 /** 2 *Print接口是"需求"的接口 3 *使用继承的适配器 4 */ 5 /*public interface Print 6 { 7 public abstract void printWeak(); 8 public abstract void printStrong(); 9 }*/ 10 /** 11 *使用委托的适配器 12 */ 13 public abstract class Print 14 { 15 public abstract void printWeak(); 16 public abstract void printStrong(); 17 }
1 /** 2 *PrintBanner类扮演适配器的角色 3 *使用继承的适配器 4 */ 5 /*public class PrintBanner extends Banner implements Print 6 { 7 public PrintBanner(String string) { 8 super(string); 9 } 10 public void printWeak() { 11 showWithParen(); 12 } 13 public void printStrong() { 14 showWithAster(); 15 } 16 }*/ 17 /** 18 *使用委托的适配器 19 */ 20 public class PrintBanner extends Print 21 { 22 private Banner banner; 23 public PrintBanner(String string) { 24 this.banner = new Banner(string); 25 } 26 public void printWeak() { 27 banner.showWithParen(); 28 } 29 public void printStrong() { 30 banner.showWithAster(); 31 } 32 }
1 /** 2 *用Adapter模式将一个属性集合保存至文件中的FileProperties类 3 */ 4 import java.io.*; 5 import java.util.*; 6 public class FileProperties extends Properties implements FileIO 7 { 8 public void readFormFile(String filename) throws IOException { 9 load(new FileInputStream(filename)); 10 } 11 public void writeToFile(String filename) throws IOException { 12 store(new FileOutputStream(filename),"written by FileProperties"); 13 } 14 public void setValue(String key,String value) { 15 setProperty(key,value); 16 } 17 public String getValue(String key) { 18 return getProperty(key,""); 19 } 20 }
1 /** 2 *Main类是通过扮演适配器角色的PrintBanner类来弱化(带括号) 3 *或是强化Hello(带*号)字符串的显示 4 */ 5 /*public class Main 6 { 7 public static void main(String[] args) { 8 Print p = new PrintBanner("Hello"); 9 p.printWeak(); 10 p.printStrong(); 11 } 12 }*/ 13 import java.io.*; 14 public class Main 15 { 16 public static void main(String[] args) { 17 FileIO f = new FileProperties(); 18 try { 19 f.readFormFile("file.txt"); 20 f.setValue("year","2017"); 21 f.setValue("month","6"); 22 f.setValue("day","9"); 23 f.writeToFile("newfile.txt"); 24 } catch(IOException e) { 25 e.printStackTrace(); 26 } 27 } 28 }
file.txt
year=1995
生成的newfile.txt
#written by FileProperties
#Fri Jun 09 20:04:48 CST 2017
day=9
year=2017
month=6
以上是关于Java23种设计模式的主要内容,如果未能解决你的问题,请参考以下文章