博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式:设计模式概述&JDK中的应用
阅读量:6907 次
发布时间:2019-06-27

本文共 14622 字,大约阅读时间需要 48 分钟。

【概述】

     设计模式主要分为三大类:创建型、结构型、行为型

【创建型】

     目的:对象怎么来的?创建对象时隐藏创建逻辑,不直接使用new。

     1.1 单例模式 Singleton:

        原理:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

        举例:java.lang.Runtime;

Runtime rt = Runtime.getRuntime(); //每一个运行的java都会有唯一的一个运行时实例。运行过程中实例会受影响。           源码:private static Runtime currentRuntime = new Runtime();                        public static Runtime getRuntime() {                            return currentRuntime                      }

     1.2 原型模式 Prototype:

        原理:用于创建重复的对象,同时又保证性能。实现了一个原型接口,该接口用于创建当前对象的克隆。浅拷贝(Cloneable)和深拷贝(Serializable读取二进制流)

        举例:Object.clone();  Spring框架bean装配时scope的类型:Singleton,ProtoType

public static Shape getShape(String shapeId) {      Shape cachedShape = shapeMap.get(shapeId);      return (Shape) cachedShape.clone();   }

     1.3 工厂模式 Factory:

        原理:创建对象时不会对客户端暴露创建逻辑,而且是通过使用一个统统的接口来指向新创建的对象。

        举例: java.lang.Class  

Class clazz = new Object().getClass;Object obj = clazz.newInstance();  // 利用反射创建实例。

     1.4 抽象工厂模式 Abstract:

        原理:接口是负责创建一个相关对象的工厂,不需要显示指定他们的类。每个生成的工厂都能按照工厂模式提供对象。

        举例:java.text.NumberFormat;

NumberFormat numberFormat = NumberFormat.getInstance(Locale.CANADA);源码:  public static NumberFormat getInstance(Locale) {        return getInstance(inLocale, NUMBERSTYLE); //返回的抽象数据类型,会进一步判断choice的类别来返回设置的格式。  }

     1.5 建造者模式 Builder:

       原理:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的标识。顺序无关的对象可以都先创建好。

       举例:Java.lang.StringBuilder;

StringBuilder stringBuilder = new StringBuilder();stringBuilder.append(); //通过系统拷贝方法System.arrayCopy()方法生成一个新的字符序列

【结构型】

    目的:对象和谁有关?关注类和对象,继承的概念被用来组合接口/对象获得新功能。

    2.1 适配器模式 Adapter:

      原理:作为两个不兼容的接口之间的桥梁。主要是解决正在服役的项目的问题。

      举例:java.util.Arrays.asList();    java.io.InputStreamReader(InputStream)

String[] arr = {"1", "2", "3"};List
arrayList = Arrays.asList(arr);源码: public static
List
asList(T.. a) { return new ArrayList<>(a); // 利用数组数据初始化elementData和size字段,这两个值是ArrayList的核心属性。 }

    2.2 桥接模式 Bridage:

     原理:把抽象化与实现化解耦,使它们都可以独立的变化。

     举例:java.sql.Connection/DriverManager;

try {     Class.forName("com.mysql.jdbc.Driver");  // 装载进去,即具体的Driver装载到DriverManager中。     String url = "";     String user = "";     String password = "";     Connection con = DriverManager.getConnection(url, user, password);} catch (Exception e) {
........... } 源码分析:DriverManager就相当于是一个Bridage Driver --> DriverManager(Bridage) --> Connectionpublic class Driver extends NonRegisteringDriver implements java.sql.Driver {  static { try {       java.sql.DriverManager.registerDriver(new Driver); } catch (SQLException e) { ................ } }}

   2.3 过滤器模式 Filter:

     原理:使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。

     举例:java.util.map(JDK8);

Map
> groupMap = persons.stream().collect(Collectors.groupingBy(Person::getGender));groupMap.forEach((k, v) -> { // k是分组的指标,v是list集合 System.out.println(k); v.forEach(System.out::println);});

   2.4 组合模式 Composite:

     原理:创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

     举例:java.util.Map;

Map
map1 = new HashMap
();Map
map2 = new HashMap
();map1.putAll(m2); // 自己可以装配和自己类型相同的对象组

   2.5 装饰器模式 Decorator:

     原理:允许动态地向一个现有的对象添加新的功能,同时又不改变其结构。类似extends,但不需要产生大量子类,关键还是动态产生。

     举例:java.io.BufferedInputStream(InputStream);

源码分析:    public BufferedInputStream(InputStream in, int size) {        super(in);  // inputStream类型的in对象        if (size <= 0) {              throw new IllegalArgumentException("Buffer size <= 0");        }        buf = new byte[size];    }    public void close() throws IOException {        byte[] buffer;        while ( (buffer = buf) != null) {            if (bufUpdater.compareAndSet(this, buffer, null)) {                InputStream input = in;  //实际操作的是in对象,close结构没变                in = null;                if (input != null)                    input.close();                return;            }            // Else retry in case a new buf was CASed in fill()        }    }

   2.6 外观模式 Facade:

     原理:为复杂的模块获子系统提供外界访问的模块。

     举例:javax.servlet.http.HttpServletRequest;

源码分析:public HttpServletRequest getRequest() {   if (facade == null) {        facade = new RequestFacade(this); // 里边有许多内部组件之间交互的public类型方法,但又不能对外开放。如setComet,setRequestedSessionId等。   }}

   2.7 享元模式 Flyweight:

     原理:减少创建对象的数量,以减少内存占用和提供性能。尝试重用现有的同类对象,如果未找到匹配的对象,则创建新的对象。

     举例:java.lang.Integer;

Integer integer = Integer.valueof(1);

源码:assert IntegerCache.hight >=127;if (i >= IntegerCache.low && i <= IntegerCache.high)    return IntegerCache.cache[i + (-IntegerCache.low)];   // 先判断,满足条件就从缓存数据中取,不再创建新对象。 return new Integer(i);

   2.8 代理模式 Proxy:

    原理:在代理模式中,我们创建具有目标对象的代理对象,以便向外界提供功能接口。

    举例:java.lang.reflect.InvocationHnadler;

final ISomeService target = new SomeServiceImpl();  // 自由变量        ISomeService proxy = (ISomeService) Proxy.newProxyInstance(target.getClass().getClassLoader(),                target.getClass().getInterfaces(),                new InvocationHandler() {                    // 织入:交叉业务逻辑切入到主业务中。                    @Override                    public Object invoke(Object proxy, Method method,                            Object[] args) throws Throwable {                        SomeUtils.doTransaction();                        Object result = method.invoke(target, args);                        SomeUtils.doLog();                        return result;                    }          });        proxy.doSome();        proxy.doSecond();

【行为型】

    目的:对象与对象在干吗?关注对象之间的通信

    3.1 责任链模式 Chain of Responsibility:

      原理:通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者.

      举例:java.util.logging.Logger;

public void log(LogRecord record) {        if (record.getLevel().intValue() < levelValue || levelValue == offValue) {            return;        }        Filter theFilter = filter;        if (theFilter != null && !theFilter.isLoggable(record)) {            return;        }        // Post the LogRecord to all our Handlers, and then to        // our parents' handlers, all the way up the tree.        Logger logger = this;        while (logger != null) {            for (Handler handler : logger.getHandlers()) {                handler.publish(record);  //获取Handler的引用,交给其处理            }            if (!logger.getUseParentHandlers()) {                break;            }            logger = logger.getParent();        }    }

    3.2 命令模式 Command:

      原理: 数据驱动,以Command的形式包裹在对象中,并传给Invoker调用对象。Invoker对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。适用于:行为的记录、撤销、重做、事务等。

      举例:java.lang.runnable;   

Runnable runable = () -> System.out.println(“具体命令”);  // 即Command (run)包裹在runnable对象中。            Thread Thread1 = new Thread(runable); // 将包裹cmd的对象交给Thread,即Invoker            Thread1.start(); // Invoker调用 cmd的方法。

    3.3 解释器模式 Interpreter:

      原理:提供了评估语言的语法或表达式的方法。实现了一个表达式接口,该接口解释了一个待定的上下文。常用于SQL解析、符号处理引擎等。

      举例:java.text.Format;  java.util.Pattern;

Pattern pattern = Pattern.compile("regexExpression");  // 解释器的作用Matcher match = pattern.matcher("expresionString"); Boolean result = match.matches();// Pattern实例是不可变的,并且支持并发和多线程安全,而Matcher不支持,则另一种表达方式Boolean result = Pattern.matches("regexExpression", "expresionString")

    3.4 迭代器模式 Iterator:

      原理:顺序访问集合对象的元素,不需要知道集合对象的底层表示。

      举例:java.util.Iterator;

private abstract class HashIterator
implements Iterator
{ Entry
next; // next entry to return int expectedModCount; // For fast-fail int index; // current slot Entry
current; // current entry HashIterator() { expectedModCount = modCount; if (size > 0) { // advance to first entry Entry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } } public final boolean hasNext() { return next != null; } final Entry
nextEntry() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); Entry
e = next; if (e == null) throw new NoSuchElementException(); if ((next = e.next) == null) { Entry[] t = table; while (index < t.length && (next = t[index++]) == null) ; } current = e; return e; }

    3.5 中介者模式 Mediator:

      原理:提供了一个中介类,该类处理不同类之间的通信。符合迪米特法则(最少知道原则),减少实体之间的相互作用。

      举例:java.util.concurrent.Executor;   java.util.Timer;  java.lang.reflect.Method; 

Runnable runable = () -> System.out.println(“具体命令”);  // 即Command (run)包裹在runnable对象中。         ExecoturService executorService = Executors.newSingleThreadExecutor();  // 中介类         executorService.execute(runable);  // 中介类来执行

    3.6 备忘录模式 Memento:

      原理:保存一个对象的某个状态,以便在适当的时候恢复对象。

      举例:java.io.Serializable

public class DemoBean implements Serializable {    private static final long serialVersionUID = 1L;    ................}ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("D:/demoBean.txt")));  //可以备忘到文件,容器缓存中等oos.writeObject(demoBean) // 将对象demoBean保留下来ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("D:/demoBean.txt")));DemoBean demoBean = (DemoBean)ois.readObject();  // 恢复

    3.7 观察者模式 Observer:

      原理:当一个对象被修改时,会自动通知它依赖的对象。一般使用异步方式。

      举例:java.util.EventListener&java.uti.EventObject;   javax.servlet.http.HttpSessionBindingListener 

         1)事件对象

import java.util.EventObject;public class MyEvent extends EventObject {    private static final long serialVersionUID = 1L;    private int sourceState;        public MyEvent(Object source) {        super(source);        sourceState = ((Source)source).getFlag();    }        public int getSourceState() {        return sourceState;    }}
View Code

         2)事件监听器(观察者)

import java.util.EventListener;/** *  * @author Thief * */public class StateChangeListener implements EventListener {    public void handleEvent(MyEvent event) {        System.out.println("触发状态改变事件。。。");        System.out.println("当前事件源状态为:" + event.getSourceState());        System.out.println("。。。。。。。。。。。。。。。。。。。。。。。");    }}
View Code
import java.util.EventListener;/** *  * @author Thief * */public class StateChangeToOneListener implements EventListener {    public void handleEvent(MyEvent event) {        System.out.println("触发状态变为1的事件。。。");        System.out.println("当前事件源状态为:" + event.getSourceState());        System.out.println("。。。。。。。。。。。。。。。。。。。。。。。");    }    }
View Code

         3)事件源(被观察者)

import java.util.EventListener;import java.util.HashSet;import java.util.Set;/** *  * @author Thief * */public class Source {    private int flag = 0;    Set
listeners = new HashSet
(); /** * 注册事件监听器 * * @param listener */ public void addStateChangeListener(StateChangeListener listener) { listeners.add(listener); } /** * 注册事件监听器 * * @param listener */ public void addStateChangeToOneListener(StateChangeToOneListener listener) { listeners.add(listener); } /** * 当事件发生时,通知注册在事件源上的所有事件做出相应的反映 */ public void notifyListener() { for (EventListener listener : listeners) { try { ((StateChangeListener)listener).handleEvent(new MyEvent(this)); } catch (Exception e) { if (flag == 1) { ((StateChangeToOneListener)listener).handleEvent(new MyEvent(this)); } } } } /** * 改变状态 */ public void changeFlag() { flag = (flag == 0 ? 1 : 0); notifyListener(); } public int getFlag() { return flag; }}
View Code

    3.8 状态模式 State:

      原理:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

      举例:java.util.Iterator;

    3.9 策略模式 Strategy:

      原理:策略对象改变context对象的执行算法。

      举例:java.util.concurrent.ThreadPoolExecutor;  java.util.Comparator;

Runnable runable = () -> System.out.println(“具体命令”);  // 即Command (run)包裹在runnable对象中。         ThreadPoolExecutor executorService;         executorService = new ThreadPoolExecutor(1,1,1L,TimeUnit.MINUTES,new ArrayBlockingQueue<1>, new ThreadPoolExecutor.AbortPolicy);  //丢弃并抛出异常         executorService = new ThreadPoolExecutor(1,1,1L,TimeUnit.MINUTES,new ArrayBlockingQueue<1>, new ThreadPoolExecutor.DiscardPolicy); //丢弃不抛出异常         executorService = new ThreadPoolExecutor(1,1,1L,TimeUnit.MINUTES,new ArrayBlockingQueue<1>, new ThreadPoolExecutor.DiscardOldestPolicy); //丢弃队列最前面的任务,然后重新尝试执行任务。         executorService = new ThreadPoolExecutor(1,1,1L,TimeUnit.MINUTES,new ArrayBlockingQueue<1>, new ThreadPoolExecutor.DiscardPolicy); //由调用线程处理任务

    3.10 空对象模式 Null Object:

      原理:Null对象不是检查空值,而是反应一个不做任何动作的关系。这样的null对象也可以在数据不可用的时候提供默认的行为。

      举例:java.util.Collections.EMPTY_LIST;

源码走读: @SuppressWarnings("unchecked")          public static final List EMPTY_LIST = new EmptyList<>();

    3.11 模板模式 Template:

      原理:主要解决一些方法通用,却在每一个子类都重写了这一方法。将这些通用的方法抽象出来。

      举例:java.util.Coolections;  org.springframework.jms.core.JmsTemplate;

public static 
> void sort(List
list) { Object[] a = list.toArray(); Arrays.sort(a); ListIterator
i = list.listIterator(); for (int j=0; j

    3.12 访问者模式 Visitor:

      原理:主要将数据结构与数据操作分离,稳定的数据结构和以便的操作耦合问题。

      举例:java.nio.file.FileVisitor; // 通过Files.walkFileTree方法实现对文件树中每一个文件的访问。

// 使用FileVisitor对目录进行遍历        Files.walkFileTree(Paths.get("d:", "workspace"), new SimpleFileVisitor
() { // 在访问子目录前触发该方法 @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { System.out.println("正在访问" + dir + "目录"); return FileVisitResult.CONTINUE; } // 在访问文件时触发该方法 @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { System.out.println("正在访问" + file + "文件"); if (file.endsWith("FilesTest.java")) { System.out.println("------已找到FilesTest.java,文件内容-----"); List
list = Files.readAllLines(file); // 打印出文件的内容 System.out.println(list); return FileVisitResult.TERMINATE; } return FileVisitResult.CONTINUE; } // 在访问失败时触发该方法 @Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException { // 写一些具体的业务逻辑 return super.visitFileFailed(file, exc); } // 在访问目录之后触发该方法 @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { // 写一些具体的业务逻辑 return super.postVisitDirectory(dir, exc); } });

 

转载于:https://www.cnblogs.com/zhitianji/p/9713822.html

你可能感兴趣的文章
directX学习系列8 颜色融合(转)
查看>>
方法:C#在WinForm中如何将Image存入SQL2000和取出显示
查看>>
码农翻身
查看>>
在windows下运行docker的问题【Error getting IP address: ***】
查看>>
python基础一 day16 匿名函数
查看>>
参考_Android中,如何新建一个界面,并且实现从当前界面切换到到刚才新建的(另外一个)界面...
查看>>
Linux常用命令大全
查看>>
Jenkins卸载方法(Windows/Linux/MacOS)
查看>>
《过节》——北岛
查看>>
并发、并行、同步、异步、多线程的区别?
查看>>
JavaScript的写类方式(5)——转
查看>>
Java并发编程笔记—摘抄—基础知识
查看>>
simple-spring-memcached统一缓存的使用实例
查看>>
Codeforces 600E - Lomsat gelral(树上启发式合并)
查看>>
[Hnoi2013]消毒
查看>>
[HNOI2015]开店
查看>>
容斥与反演
查看>>
GitHub 配置指南
查看>>
swift swift学习笔记--函数和闭包
查看>>
Java 面向对象,封装,继承
查看>>