zoukankan      html  css  js  c++  java
  • java设计模式学习笔记

    简介

    设计模式可以分为五类

    1. 接口型 模式:适配器模式,外观模式,合成模式,桥接模式
    2. 职责型 模式:单例模式,观察者模式,调停者模式,代理模式,职责链模式,享元模式 
    3. 构造型 模式:构建者模式,工厂方法模式,抽象工厂模式,原型模式,备忘录模式
    4. 操作型 模式:模板方法模式,状态模式,策略模式,命令模式,解析器模式
    5. 扩展型 模式:装饰器模式,迭代器模式,访问者模式。

     接口类

    适配器模式 通过一个接口来适配类的接口

    接口的优点:限制了类之间的协作 , 即使实现类发生巨大变化, 接口的客户端也不受影响

    不同场景下使用 的模式

    1. 适配类的接口,以匹配客户端期待的接口-->适配器模式
    2. 为一组类提供简单接口-->外观模式
    3. 为简单对象和复合对象提供统一接口-->合成模式
    4. 解除抽象与实现之间的耦合,使得二者独立演化-->桥接模式

    1. 适配器模式

     类适配器

    使用继承方式,是静态的继承方式

    简述 :接口中的方法  分别在父类和子类中实现 

    写一个demo

    接口中有两个方法 

    public interface Target {
    
        void firstMethod();
    
        void secondMethod();
    }
    

    adaptee只有一个方法

    public class Adaptee {
        public void firstMethod(){
            System.out.println("this is first method.");
        }
    }
    

    adapter 继承 adaptee 并实现 secondMethod

    public class Adapter extends Adaptee implements Target {
        @Override
        public void secondMethod() {
            System.out.println("this second method.");
        }
    }
    

      

    对象适配器  

    采用委派的方式 

    将  adaptee组合到 adpter2中

    写个demo

    public class Adapter2 implements Target{
        private Adaptee adaptee;
    
        public Adapter2(Adaptee adaptee) {
            this.adaptee = adaptee;
        }
    
        @Override
        public void firstMethod() {
             this.adaptee.firstMethod();
        }
    
        @Override
        public void secondMethod() {
            System.out.println("this second method.");                                                     
        }
    }
    

    优点:代码复用,扩展 ,灵活 ,强大

    缺点:是系统零乱 不易把握   

     2.外观模式

    外观模式的意图是为 子系统 提供提供一个接口, 方便使用

    外观类可能全是静态方法

    简单描述一下  为复杂的子系统 提供一个 简单的调用门面  

    网上找了个易于理解的例子 http://www.aichengxu.com/java/681321.htm

    一个人申请开公司 他需要分别 去 工商局,银行,公安局,质监局,税务部门 办理相关手续 特别麻烦

    现在 有个绿色通道 ,actor只要 和它对接 既可以完成 上述操作  这个 绿色通道便可以看成是 一个 facade

    这样看来  facade 模式 减少了客户端和 各个子系统之间交互,减少耦合。使接入变得简单

    写一个简单的demo

    工商系统

    public class Indutry {
       void regist(){
           System.out.println("indutry registration.");
       }
    }
    

    公安系统

    public class PoliceStation {
        void regist(){
            System.out.println("police station registration.");
        }
    }
    

    税务系统

    public class RevenueDepartment {
        void regist(){
            System.out.println("revenue department registration.");
        }
    }
    

    facade

    public class Facade {
        public void buildCompany() {
            Indutry indutry = new Indutry();
            PoliceStation policeStation = new PoliceStation();
            RevenueDepartment revenueDepartment = new RevenueDepartment();
    
            indutry.regist();
            policeStation.regist();
            revenueDepartment.regist();
        }
    }
    

    3.合成模式

    composite :组合对象 ,单对象 。组对象和单对象有共同的行为

    组合对象 可以包括其他组合对象,也可以包括单对象。

    合成模式 作用:保证客户端调用 单对象与组合对象的一致性

    安全合成模式

    管理聚集的方法 只出现在树枝构建中

    写一个demo

    相同接口

    public interface Component {
        void printStruct(String preStr);
    }
    

    组合

    public class Composite implements Component {
        private List<Component> childComponens = new ArrayList<Component>();
        private String name;
    
        public void add(Component child) {
            childComponens.add(child);
        }
    
        public void remove(int index) {
            childComponens.remove(index);
        }
    
        public Composite(String name) {
            this.name = name;
        }
    
        public List<Component> getChildComponens() {
            return childComponens;
        }
    
        public void setChildComponens(List<Component> childComponens) {
            this.childComponens = childComponens;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void printStruct(String preStr) {
            System.out.println(preStr + "-->" + name);
            if (childComponens != null) {
                preStr += "      ";
                for (Component child : childComponens) {
                    //递归调用
                    child.printStruct(preStr);
                }
            }
    
        }
    }
    

    叶子节点

    public class Leaf implements Component {
    
        private String name;
    
        public Leaf(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public void printStruct(String preStr) {
            System.out.println(preStr+"-->"+name);
        }
    }
    

     测试

    public void test(){
            Composite root=new Composite("knowledge");
            //java 节点
            Composite java=new Composite("java");
    
            Composite map=new Composite("Map");
            map.add(new Leaf("HashMap"));
            map.add(new Leaf("TreeMap"));
    
            java.add(new Leaf("JVM"));
            java.add(new Leaf("List"));
            java.add(map);
    
            //spring节点
            Composite spring=new Composite("spring");
            spring.add(new Leaf("AOP"));
            spring.add(new Leaf("IOC"));
    
            // root add
            root.add(java);
            root.add(spring);
    
            root.printStruct("");
        }
    

    运行结果

     

      

    4. 桥接模式

    桥接模式 (bridge)关注抽象

    桥接模式的意图  是  将 抽象与抽象方法的实现 相互分离出来, 实现 解耦合,以便二者可以相互独立

    简单的说 就是 将对象 与方法分离

    书上看到一个例子:现在有 2种设备 分别有  启动  关闭 2个抽象方法。

    写个简单的 demo

    抽象设备

    public abstract class AbstractMachine {
    
       private MechineMethod mechineMethod;
    
        public void setMechineMethod(MechineMethod mechineMethod) {
            this.mechineMethod = mechineMethod;
        }
    
        public MechineMethod getMechineMethod() {
            return mechineMethod;
        }
    
        abstract void checkMethod();
    }  

     设备A

    public class MachineA extends AbstractMachine {
        @Override
        void checkMethod() {
            System.out.println("check machine A ......");
        }
    }
    

     

    设备B

    public class MachineB extends AbstractMachine {
        @Override
        void checkMethod() {
            System.out.println("check machine B ......");
        }
    }
    

    要检测的功能 的抽象类 (这里对方法的处理 将常规的 竖 转 横,方法平铺 )

    public abstract class MechineMethod {
        abstract void methodRun();
    }
    

      

    start功能

    public class StartMethod extends MechineMethod {
        @Override
        void methodRun() {
            System.out.println("start method running.");
        }
    }
    

      

    close功能

    public class CloseMethod extends MechineMethod {
        @Override
        void methodRun() {
            System.out.println("close method running.");
        }
    }
    

      

     

    测试 检测 A设备的Start功能

    //检测A设备的 start功能
     public void test() {
            //检测A设备的 start功能
            AbstractMachine machine = new MachineA();
            MechineMethod mechineMethod = new StartMethod();
            machine.setMechineMethod(mechineMethod);
            machine.checkMethod();
            machine.getMechineMethod().methodRun();
        }
    

    输出结果

     职责类 

     

     我们常见的职责模式 如

    根据可见性控制职责 :java代码中的 public,private,protected

    职责设计模式

    1. 将职责集中到某个类的单个实例中-->单例模式
    2. 将对象从依赖它的对象中解耦-->观察者模式
    3. 将职责集中在某个类,该类可以监督其他对象的交互-->调停者模式
    4. 让一个对象扮演其他对象的行为--代理模式
    5. 允许将职责链的请求传递给其他对象,直到这个请求被某个对象处理-->职责链模式
    6. 将共享的 细粒度的职责 进行集中管理-->享元模式

     

     1. 单例模式

    单例模式 : 是确保一个类的 有且仅有一个实例,并为它提供一个全局访问点

    单例模式中 往往使用 static关键字

    static 修饰的变量为 静态变量,静态变量只在类第一次调用的时候加载 ,在内存中只有一个副本。

     

    1.饿汉模式

    public class EagerSingleton {
        private static EagerSingleton eagerSingleton=new EagerSingleton();
    
        private EagerSingleton() {
        }
    
        public EagerSingleton getSingleton(){
            return eagerSingleton;
        }
    }
    

    2.懒加载模式

    public class LazzySingleton {
        private static LazzySingleton lazzySingleton;
    
        private LazzySingleton() {
        }
    
        //同步方法
        public static synchronized LazzySingleton getSingleton() {
            if (lazzySingleton == null) {
                lazzySingleton = new LazzySingleton();
            }
            return lazzySingleton;
        }
    }
    

    3.  支持多线程

    public class Singleton {
        private static Singleton singleton;
    
        private Singleton() {
        }
    
        public static Singleton getSingleton() {
            //先条件  后程序
            if (singleton == null) {
                //锁 住整个对象
                synchronized (Singleton.class) {
                    singleton = new Singleton();
                }
            }
            return singleton;
        }
    }
    

      

    2. 观察者模式

    Observer  [əbˈzɜ:rvə(r)] 

    观察者模式:在多个对象之间定义一对多依赖关系,当一个对象的状态发生改变时,通知你依赖于它的对象,并根据新状态做出相应反应。

    写一个demo

    如 写一个 微博更新自动推送给客户

     抽象 WeiBo 父类

    public abstract class WeiBo {
        //保存 Observer 
        private List<Observer> list = new ArrayList<Observer>();
    
        public void addObserver(Observer observer) {
            list.add(observer);
        }
    
        public void delObserver(Observer observer) {
            list.remove(observer);
        }
    
        //通知所有观察者
        public void notifyObservers(String operation) {
            for (Observer observer : list) {
                observer.update(operation);
            }
        }
    }
    

    具体的Video类

    public class Video extends WeiBo {
        private String operation;
    
        public String getOperation() {
            return operation;
        }
    
        public void change(String operation) {
            this.operation = operation;
            notifyObservers(operation);
        }
    }
    

    观察者接口

    public interface Observer {
        public void update(String operation);
    }
    

    监听文件大小的观察者

    public class ObserverSize implements Observer {
        private String operation;
    
        @Override
        public void update(String operation) {
            this.operation = operation;
            System.out.println("Observer Size : " + operation);
        }
    }
    

    写一个测试的demo

     public void test() {
            Video video = new Video();
            Observer observer = new ObserverSize();
            video.addObserver(observer);
            video.change("compress video");//压缩视频
        }
    

    运行结果

    推模式 

    主题发生改变时自动推送给观察者 ,不管观察者是否需要,主题推送的通常是主题对象的全部数据 或部分数据

    拉模式

    主题发生改变时 只传递少了信息给观察者  ,观察者根据需再向主题拉取数据。

    java 提供的观察者支持类  

    Observable

    Observable [əbˈzərvəbəl] 可观察

    被观察的类只要继承该类即可。

      

    public class Observable {
        private boolean changed = false;
        private Vector<Observer> obs;
    
        /** Construct an Observable with zero Observers. */
    
        public Observable() {
            obs = new Vector<>();
        }
    
        /**
         * Adds an observer to the set of observers for this object, provided
         * that it is not the same as some observer already in the set.
         * The order in which notifications will be delivered to multiple
         * observers is not specified. See the class comment.
         *
         * @param   o   an observer to be added.
         * @throws NullPointerException   if the parameter o is null.
         */
        public synchronized void addObserver(Observer o) {
            if (o == null)
                throw new NullPointerException();
            if (!obs.contains(o)) {
                obs.addElement(o);
            }
        }
    
        /**
         * Deletes an observer from the set of observers of this object.
         * Passing <CODE>null</CODE> to this method will have no effect.
         * @param   o   the observer to be deleted.
         */
        public synchronized void deleteObserver(Observer o) {
            obs.removeElement(o);
        }
    
        /**
         * If this object has changed, as indicated by the
         * <code>hasChanged</code> method, then notify all of its observers
         * and then call the <code>clearChanged</code> method to
         * indicate that this object has no longer changed.
         * <p>
         * Each observer has its <code>update</code> method called with two
         * arguments: this observable object and <code>null</code>. In other
         * words, this method is equivalent to:
         * <blockquote><tt>
         * notifyObservers(null)</tt></blockquote>
         *
         * @see     java.util.Observable#clearChanged()
         * @see     java.util.Observable#hasChanged()
         * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
         */
        public void notifyObservers() {
            notifyObservers(null);
        }
    
        /**
         * If this object has changed, as indicated by the
         * <code>hasChanged</code> method, then notify all of its observers
         * and then call the <code>clearChanged</code> method to indicate
         * that this object has no longer changed.
         * <p>
         * Each observer has its <code>update</code> method called with two
         * arguments: this observable object and the <code>arg</code> argument.
         *
         * @param   arg   any object.
         * @see     java.util.Observable#clearChanged()
         * @see     java.util.Observable#hasChanged()
         * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
         */
        public void notifyObservers(Object arg) {
            /*
             * a temporary array buffer, used as a snapshot of the state of
             * current Observers.
             */
            Object[] arrLocal;
    
            synchronized (this) {
                /* We don't want the Observer doing callbacks into
                 * arbitrary code while holding its own Monitor.
                 * The code where we extract each Observable from
                 * the Vector and store the state of the Observer
                 * needs synchronization, but notifying observers
                 * does not (should not).  The worst result of any
                 * potential race-condition here is that:
                 * 1) a newly-added Observer will miss a
                 *   notification in progress
                 * 2) a recently unregistered Observer will be
                 *   wrongly notified when it doesn't care
                 */
                if (!changed)
                    return;
                arrLocal = obs.toArray();
                clearChanged();
            }
    
            for (int i = arrLocal.length-1; i>=0; i--)
                ((Observer)arrLocal[i]).update(this, arg);
        }
    
        /**
         * Clears the observer list so that this object no longer has any observers.
         */
        public synchronized void deleteObservers() {
            obs.removeAllElements();
        }
    
        /**
         * Marks this <tt>Observable</tt> object as having been changed; the
         * <tt>hasChanged</tt> method will now return <tt>true</tt>.
         */
        protected synchronized void setChanged() {
            changed = true;
        }
    
        /**
         * Indicates that this object has no longer changed, or that it has
         * already notified all of its observers of its most recent change,
         * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.
         * This method is called automatically by the
         * <code>notifyObservers</code> methods.
         *
         * @see     java.util.Observable#notifyObservers()
         * @see     java.util.Observable#notifyObservers(java.lang.Object)
         */
        protected synchronized void clearChanged() {
            changed = false;
        }
    
        /**
         * Tests if this object has changed.
         *
         * @return  <code>true</code> if and only if the <code>setChanged</code>
         *          method has been called more recently than the
         *          <code>clearChanged</code> method on this object;
         *          <code>false</code> otherwise.
         * @see     java.util.Observable#clearChanged()
         * @see     java.util.Observable#setChanged()
         */
        public synchronized boolean hasChanged() {
            return changed;
        }
    
        /**
         * Returns the number of observers of this <tt>Observable</tt> object.
         *
         * @return  the number of observers of this object.
         */
        public synchronized int countObservers() {
            return obs.size();
        }
    }
    

    Observer  

    观察者只要实现该类即可。

    3. 调停者模式 Mediator

      

    mediator [ˈmēdēˌātər] :中间人

    调停者模式:定义一个对象,封装一组对象的交互,从而降低对象间的耦合度,避免了对象之间的显示引用,并且可以独立的改变对象间的行为。

    复杂的调用关系

     引入 mediator

    写个demo

    Mediator 接口 

    public interface Mediator {
    
        void changed(Component component);
    }
    

    将A,B,C...等组件 抽象出一个父类

    /**
     * A,B,C,D...抽象出一个父类 叫 Colleague
     * 因为 调停者 要和 A,B,C,D..组件关联 所以将它注入到各组件中(抽象到父类里)
     */
    public abstract class Component {
        private Mediator mediator;
    
    
        public Component(Mediator mediator) {
            this.mediator = mediator;
        }
    
        public Mediator getMediator() {
            return mediator;
        }
    
    }
    

      

    组件A

    public class ComponetA extends Component {
    
        public ComponetA(Mediator mediator) {
            super(mediator);
        }
        public void start(){
            getMediator().changed(this);//通过Mediator 调停者 通知 其他组件
        }
    }
    

      

    组件B

    public class ComponetB extends Component {
        public ComponetB(Mediator mediator) {
            super(mediator);
        }
        public void start(){
            getMediator().changed(this);//通过Mediator 调停者 通知 其他组件
        }
    }
    

      

    实现 Mediator 类

    public class MediatorConcrete implements Mediator {
        //调停者 要交互 其他组件 所以 其他组件 要注入调停者里面
        private ComponetA colleagueA;
        private ComponetB colleagueB;
    
        public void setColleague(ComponetA colleagueA, ComponetB colleagueB) {
            this.colleagueA = colleagueA;
            this.colleagueB = colleagueB;
        }
    
        @Override
        public void changed(Component colleague) {
            //通知给其他组件
            if (colleague instanceof ComponetA) {
                System.out.println("hi B,ComponetA start");
            } else if (colleague instanceof ComponetB) {
                System.out.println("hi A,ComponetB start");
            }
        }
    }
    

      

    测试  

    public void test(){
            //实例化一个调停者
            MediatorConcrete mediator = new MediatorConcrete();
            //创建两个组件,放入调停者(要通过调停者传递消息)
            ComponetA a = new ComponetA(mediator);
            ComponetB b = new ComponetB(mediator);
    
            //交互的组件放入 (因为一个组件change,要通知其他组件)
            mediator.setColleague(a,b);
            a.start();//a组件启动
    
        }
    

    运行结果 

    4. 代理模式 Proxy

    代理对象通常拥有一个几乎和实际对象相同的接口。它常常会控制访问,并将请求合理的转发给底层的真实对象。

    Java 代理 

    1.  静态代理
    2.  动态代理

    静态代理

     client-->subject-->proxy-->realSubject

    realSubject : 委托类

    proxy : 代理类

    subject : 委托类和代理类的接口

    静态代理中 一个委托类  realSubject 对应一个代理类 proxy 代理类在编译期间就已经确定

    动态代理

    Java 动态代理

    动态代理的代理类 不是在Java代码中实现  是在运行期生成

    1.定义接口 SubjectService

    public interface SubjectService {
         void add();
    }
    

    2.定义委托类 RealSubjectServiceImpl

    public class RealSubjectServiceImpl implements SubjectService {
        @Override
        public void add() {
            System.out.println("init real sub service.");
        }
    }
    

    3.定义 myInvocationHandler 实现java.lang.reflect.InvocationHandler接口

    m.invoke(obj,args)  : 对目标对象的调用转发给 包装对象 

    public class MyInvocationHandler implements InvocationHandler {
        private Object target;//目标对象
    
        public MyInvocationHandler(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println(".....before......");
            Object result=method.invoke(target,args);
            System.out.println(".....after......");
            return result;
        }
        public Object getProxy(){
            return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),target.getClass().getInterfaces(),this);
        }
    }

    4.测试

    @Test
    public void proxyTest(){
    MyInvocationHandler handler=new MyInvocationHandler(new RealSubjectServiceImpl());
    //proxy
    SubjectService proxy= (SubjectService) handler.getProxy();
    proxy.add();
    }

    运行结果

    cglib动态代理  

    cglib底层使用 ASM 重写 非 final 方法实现

      

    1.创建 自己的方法拦截器  MyMethodInterceptor 实现  MethodInterceptor  

    2.通过 net.sf.cglib.proxy.Enhancer 创建代理对象

    public class MyMethodInterceptor implements MethodInterceptor {
    private Object target;

    public MyMethodInterceptor(Object target) {
    this.target = target;
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    System.out.println(".....before......");
    Object result=proxy.invokeSuper(obj,args);
    System.out.println(".....before......");
    return result;
    }

    public Object getProxy(){
    Enhancer enhancer=new Enhancer();
    enhancer.setCallback(this);
    enhancer.setSuperclass(target.getClass());
    return enhancer.create();
    }
    }

    测试. 

      @Test
        public void cglibTest(){
            MyMethodInterceptor interceptor=new MyMethodInterceptor(new RealSubjectServiceImpl());
            SubjectService proxy= (SubjectService) interceptor.getProxy();
            proxy.add();
        }
    

     5. 职责链模式 chain of responsibility

     职责链模式 通过给予多个对象处理请求的机会,以解除请求的发送者与接收者之间的耦合。

    简单的说 :请假3天假-->leader审批-->经理审批-->人事审批

                       或者

                      我只请半天假-->leader审批-->人事审批 

    职责链的节点 可以自由组合 

     抽象一个Hander父类

    public abstract class Handler {
        private Handler next;//后续责任对象
    
        public Handler getNext() {
            return next;
        }
    
        public void setNext(Handler next) {
            this.next = next;
        }
    
        public abstract void handleRequest();//处理请求
    }
    

      

     A节点

    public class HanderA  extends Handler{
        @Override
        public void handleRequest() {
            System.out.println("A done..");
            if(getNext()!=null){
                getNext().handleRequest();
            }else {
                System.out.println("finish..");
            }
        }
    }
    

      

    B节点

    public class HanderB extends Handler{
        @Override
        public void handleRequest() {
            System.out.println("B done..");
            if(getNext()!=null){
                getNext().handleRequest();
            }else {
                System.out.println("finish..");
            }
        }
    }
    

      

    c节点

    public class HanderC extends Handler{
        @Override
        public void handleRequest() {
            System.out.println("C done..");
            if(getNext()!=null){
                getNext().handleRequest();
            }else {
                System.out.println("finish..");
            }
        }
    }
    

      

    测试

    public void test(){
            Handler a=new HanderA();
            Handler b=new HanderB();
            Handler c=new HanderC();
            a.setNext(b);
            b.setNext(c);
    
            a.handleRequest();
        }
    

    执行结果

     6. 享元模式 flyweight

     

    享元模式 在客户对象之间提供共享对象,并且为共享对象创建职责

    共享对象发生改变 时  不需要通知其他客户端 

    享元模式的目的是:通过共享来支持大量细粒度对象

    1.享元模式 可以 使你共享的访问 大量出现的细粒度对象

    2.享元对象必须是不可变的

    3.不变的部分提取出来

    4.为了确保享元对象共享 ,需要强制客户端通过享元工厂来访问

    5.享元工厂 做好权限限制

    不变性  

    可以设置成枚举  

     java 中的String就是 享元模式  

      

     1.单纯享元模式

    所有的享元对象都可以共享

     抽象一个接口

    public interface Flyweight {
        void operation(String state);
    }
    

    实现一个享元对象

    public class FlyweightA implements Flyweight {
        //共享对象状态
        private Character inState;
    
        public FlyweightA(Character inState) {
            this.inState = inState;
        }
    
        @Override
        public void operation(String state) {
            //state 改变方法的行为 单 不改变 共享对象的状态
            System.out.println("param :"+state);
            System.out.println("state:"+inState);
        }
    }
    

    享元工厂

    public class FlyweightFactory {
        private Map<Character,Flyweight> files=new HashMap<Character, Flyweight>();
        public Flyweight factory(Character state){
            Flyweight flyweight=files.get(state);
            if(flyweight==null){
                flyweight=new FlyweightA(state);
                files.put(state,flyweight);
            }
            return flyweight;
        }
    }
    

     

    测试

    public class FlyweightTest {
    
        @Test
        public void test() {
            FlyweightFactory factory = new FlyweightFactory();
            Flyweight flyweight = factory.factory(new Character('0'));
            flyweight.operation("test 1");
            flyweight = factory.factory(new Character('1'));
            flyweight.operation("test B");
    
        }
    }
    

      

     运行结果

    2.复合享元模式

    复合享元模式  意思是 单个享元对象 组成一个集合,而这个集合本身不是共享的 

    就是 将上述的例子 instate改成一个集合  

    demo

     接口

    public interface Flyweight {
        void operation(String state);
    }
    

    单个享元

    public class FlyweightA implements Flyweight {
        //共享对象状态
        private Character inState;
    
        public FlyweightA(Character inState) {
            this.inState = inState;
        }
    
        @Override
        public void operation(String state) {
            //state 改变方法的行为 单 不改变 共享对象的状态
            System.out.println("param :"+state);
            System.out.println("state:"+inState);
        }
    }
    

    复合享元

    public class FlyweightB implements Flyweight {
        //复合享元模式
        private Map<Character,Flyweight> files=new HashMap<Character, Flyweight>();
        @Override
        public void operation(String state) {
              for(Flyweight flyweight:files.values()){
                  flyweight.operation(state);
              }
        }
    
        public void add(Character key,Flyweight value){
            files.put(key,value);
        }
    }
    

      

    享元工厂

    public class FlyweightFactory {
        private Map<Character,Flyweight> files=new HashMap<Character, Flyweight>();
        //集合工厂
        public Flyweight factory(List<Character> states){
            FlyweightB b=new FlyweightB();
            for(Character c:states){
                //调用 单个构建
                b.add(c,factory(c));
            }
            return b;
        }
    
        //单参构建
        public Flyweight factory(Character state){
            //先从缓存中查找对象
            Flyweight fly = files.get(state);
            if(fly == null){
                //如果对象不存在则创建一个新的Flyweight对象
                fly = new FlyweightA(state);
                //把这个新的Flyweight对象添加到缓存中
                files.put(state, fly);
            }
            return fly;
        }
    }
    

      

    测试

    public void test(){
            //工厂构建数据
            FlyweightFactory flyweightFactory=new FlyweightFactory();
            List<Character> param= Arrays.asList('0','1','2');
            Flyweight flyweight=flyweightFactory.factory(param);
    
            //操作
            flyweight.operation("test..");
        }
    

      

    运行结果

    构造类

    1. 在请求 创建对象之前  ,逐渐收集创建对象的信息-->构建者模式
    2. 推迟实例化的类对象-->工厂方法模式
    3. 创建一组 有共同特征的对象-->抽象工厂
    4. 根据现有对象 创建一个对象-->原型模式
    5. 通过对象内部静态版本 重构对象-->备忘录模式

     

     1.构建者模式 Builder

    构建者模式 :将类的实例化逻辑 转移到类的外部。

    构建模式 :将构建与对象分离 。将复杂对象的构建逻辑从对象本身抽离,这样能够简化复杂对象 

    网上找了个例子 http://www.blogjava.net/fancydeepin/archive/2012/08/05/384783.html

     我们现在需要生产一个产品 :电脑

    简单的描述 就是  产品(电脑) 是一个类,构建(builder) 是一个类 

    然后 将 产品 放入 builder中构建

    看代码:

    产品

    public abstract class Product {
        protected List<String> parts = new ArrayList<String>();//存储产品的各个部件
    
        //add
        public void add(String part) {
            parts.add(part);
        }
    
        //show product
        public void show() {
            for (String s : parts) {
                System.out.println(s);
            }
        }
    }
    

    宏碁电脑

    public class Acer extends Product {
    }
    

    戴尔电脑

    public class Dell extends Product {
    }
    

      

    构建者接口

    public interface Builder {
        //构建产品 的几个步骤
        void buildCPU();
    
        void buildMemory();
    
        void buildGraphicsCard();
    
        Product getResult();
    }
    

      

    实现 宏碁电脑构建

    public class AcerBuilder implements Builder {
        //产品和构建分离
        //创建Acer产品 进行 构建
        private Product product=new Acer();
        @Override
        public void buildCPU() {
            product.add("cpu:i5");
        }
    
        @Override
        public void buildMemory() {
            product.add("memory:8G");
        }
    
        @Override
        public void buildGraphicsCard() {
            product.add("graphics card:HD");
        }
    
        @Override
        public Product getResult() {
            return product;
        }
    }
    

      

    实现戴尔电脑构建

    public class DellBuilder implements Builder {
        //产品和构建分离
        //创建Dell产品 进行 构建
        private Product product = new Dell();
    
        @Override
        public void buildCPU() {
            product.add("cpu:i7");
        }
    
        @Override
        public void buildMemory() {
            product.add("memory:16G");
        }
    
        @Override
        public void buildGraphicsCard() {
            product.add("graphics card:HD");
        }
    
        @Override
        public Product getResult() {
            return product;
        }
    }
    

      

    指导构建过程

    public class Director {
        private Builder builder;
    
        public Director(Builder builder) {
            this.builder = builder;
        }
         
        public void Construct() {
            //控制 构建逻辑顺序
            builder.buildCPU();
            builder.buildMemory();
            builder.buildGraphicsCard();
        }
    }
    

      

    测试

    public void test() {
            System.out.println("acer");
            AcerBuilder acerBuilder = new AcerBuilder();
            Director director = new Director(acerBuilder);
            director.Construct();
            //Product show
            acerBuilder.getResult().show();
    
            System.out.println("..............");
    
            System.out.println("dell");
            DellBuilder dellBuilder = new DellBuilder();
            director = new Director(dellBuilder);
            director.Construct();
            //Product show
            dellBuilder.getResult().show();
        }
    

      

    运行结果

     2.工厂方法 factory method

    工厂方法:让服务提供者 确定实例化哪个类,而不是客户端代码

    网上找了个 demo http://blog.csdn.net/jason0539/article/details/23020989

    简单工厂模式

    简单工厂模式 又称  静态工厂模式

    客户需要一辆宝马车,客户不必自己亲自造一辆宝马车 。我们可以建立一个工厂 ,工厂负责宝马车的创建,降低 客户和宝马的耦合

    首先我们抽象一个BMW类

    public abstract class BMW {
    }
    

      

    有两种型号的 BMW

    public class BMW320 extends BMW {
        public BMW320() {
            System.out.println("build bmw 320.");
        }
    }
    

    BMW523

    public class BMW523 extends BMW {
        public BMW523() {
            System.out.println("build bmw 523.");
        }
    }
    

      

    工厂 根据传参 创建 相应产品

    public class SimpleFactory {
        public BMW createBMW(int param) {
            switch (param) {
                case 320:
                    return new BMW320();
                case 523:
                    return new BMW523();
                default:
                    break;
            }
            return null;
        }
    }
    

      

    测试

     public void test(){
            SimpleFactory factory=new SimpleFactory();
            factory.createBMW(320);
            factory.createBMW(523);
        }
    

      

    运行结果

      

    工厂方法模式

    简单工厂中   当客户需要 一个新产品时, simpleFactory需修改 case代码  去创建新的代码 ,这样 simpleFactory的代码会频繁改动  很是被动。这也违背了 设计模式的开闭原则。

    这时  我们可以把 case部分的 静态代码抽出来,分成不同的子工厂。

    Factory接口 

    public interface Factory {
        BMW createBMW();
    }
    

      

    320子工厂

    public class FactoryBMW320 implements Factory {
        @Override
        public BMW createBMW() {
            return new BMW320();
        }
    }
    

    523子工厂

    public class FactoryBMW523 implements Factory {
        @Override
        public BMW createBMW() {
            return new BMW523();
        }
    }
    

      

    测试

     public void test(){
            FactoryBMW320 factoryBMW320=new FactoryBMW320();
            factoryBMW320.createBMW();
    
            FactoryBMW523 factoryBMW523=new FactoryBMW523();
            factoryBMW523.createBMW();
        }
    

      

    运行结果

      

     3.抽象工厂 abstract factory

    抽象工厂  创建不同的产品簇

    还按上面的例子说 客户不是简单要一个BMW, 每个客户有 不同的  发动机和变速箱需求。

    先创建两个类  发动机,变速箱

    发动机

    public abstract class Engine {
    }
    

      

    4缸发动机

    public class Engine4 extends Engine {
        public Engine4() {
            //生产 四缸发动机
            System.out.println("create N46.");
        }
    }
    

      

    12缸发动机

    public class Engine12 extends Engine {
        public Engine12() {
            //生产 12缸发动机
            System.out.println("create M73.");
        }
    }
    

      

    变速箱

    public abstract class Gearbox {
    
    }
    

      

    手动变速

    public class ManualGearbox extends Gearbox {
        public ManualGearbox() {
            System.out.println("create manual transmission.");
        }
    }
    

      

    自动变速

    public class AutomaticGearbox extends Gearbox {
        public AutomaticGearbox() {
            System.out.println("create automatic transmission.");
        }
    }
    

      

    抽象工厂

    public interface AbstractFactory {
        Engine createEngine();
    
        Gearbox createGearbox();
    }
    

      

    产品12工厂:12缸发动机,自动变速箱

    public class FactoryBMW12 implements AbstractFactory {
        @Override
        public Engine createEngine() {
            return new Engine12();
        }
    
        @Override
        public Gearbox createGearbox() {
           return new AutomaticGearbox();
        }
    }
    

      

    产品 46 工厂 :4缸发动机,手动变速

    public class FactoryBMW46 implements AbstractFactory {
        @Override
        public Engine createEngine() {
            return new Engine4();
        }
    
        @Override
        public Gearbox createGearbox() {
           return new ManualGearbox();
        }
    }
    

      

    测试

    public void test(){
            System.out.println("bmw 12 :");
            FactoryBMW12 factoryBMW12=new FactoryBMW12();
            factoryBMW12.createEngine();
            factoryBMW12.createGearbox();
            System.out.println("............");
    
            System.out.println("bmw 46 :");
            FactoryBMW46 factoryBMW46=new FactoryBMW46();
            factoryBMW46.createEngine();
            factoryBMW46.createGearbox();
        }
    

      

    执行结果

     4.原型模式 prototype

     原型模式使用户复制对象样本来创建对象。而不是通过实例化的方式。

    原型模式的核心是克隆方法,java 提供了 Cloneable接口 。

    写个demo

    public class Student implements Cloneable {
        private String code;
        List<String> courses;
    
        public List<String> getCourses() {
            return courses;
        }
    
        public void setCourses(List<String> courses) {
            courses = courses;
        }
        public void addCourse(String course) {
            if(courses==null) courses=new ArrayList<String>();
            courses.add(course);
        }
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
        @Override
        protected Student clone() {
            try {
                return (Student) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        @Override
        public String toString() {
            return this.code
                    +",Courses : "+ Arrays.toString(courses.toArray());
        }
    }
    

      

      

    原型模式 内存二进制流copy,要比直接new性能好 。

    new 的时候 也许受权限限制 ,使用原型模式可以访问一些私有对象

    浅拷贝

     public void test(){
            Student student=new Student();
            student.setCode("001");
            student.addCourse("math");
    
            Student studentB=student.clone();
            studentB.setCode("001B");
            studentB.addCourse("java");
            studentB.addCourse("C#");
            System.out.println(student.toString());
            System.out.println(studentB.toString());
    
        }
    

     

    输出

    可以发现  studenB的  Courses变化 会影响到 原始Student

    因为 Object提供的clone只Copy对象 对象中数组和引用对象都未copy,指向的还是元数据的 地址。 

     深拷贝

    可以通过流式copy进行深copy

    public class Teacher implements Serializable{
        private String code;
        List<String> courses;
    
        public List<String> getCourses() {
            return courses;
        }
    
        public void setCourses(List<String> courses) {
            courses = courses;
        }
        public void addCourse(String course) {
            if(courses==null) courses=new ArrayList<String>();
            courses.add(course);
        }
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
    
        @Override
        public String toString() {
            return this.code
                    +",Courses : "+ Arrays.toString(courses.toArray());
        }
    }
    

      

    流 copy

     public void testDeep(){
            try {
                Teacher teacher=new Teacher();
                teacher.setCode("001");
                teacher.addCourse("tech math");
    
                //对象  写入缓存 bytes
                //申明缓存空间
                ByteOutputStream bytes=new ByteOutputStream();
                //申明 对象写入
                ObjectOutputStream out=new ObjectOutputStream(bytes);
                //对象写入
                out.writeObject(teacher);
    
                 //bytes中读取对象
                ObjectInputStream inputStream=new ObjectInputStream(new ByteArrayInputStream(bytes.getBytes())) ;
                Teacher teacherB= (Teacher) inputStream.readObject();
                teacherB.setCode("001B");
                teacherB.addCourse("tech java");
                System.out.println(teacher.toString());
                System.out.println(teacherB.toString());
            } catch (Exception e) {
                e.printStackTrace();  
            }
    
        }
    

      

    运行结果

     5.备忘录模式 Memento

    备忘录模式的目的是 为对象状态 提供存储和恢复功能。

    备忘录模式的结构

    Originator [əˈrijəˌnātər]

    Caretaker [Care taker] 管理人

    1. 发起人:记录当前时刻内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘数据。
    2. 备忘录:负责存储 发起人对象的内部状态,需要的时候提供 发起人需要的内部状态
    3. 管理角色:对备忘录进行管理,保存和提供备忘数据。

     发起人代码

    public class Originator {
        private String state="";
    
        public String getState() {
            return state;
        }
    
        public void setState(String state) {
            this.state = state;
        }
        //创建备忘状态
        public Memento createMemento(){
            return new Memento(this.state);
        }
        //恢复备忘状态
        public void restoreMemento(Memento memento){
            this.setState(memento.getState());
        }
    }
    

    备忘录

    public class Memento {
        private String state="";
    
        public Memento(String state) {
            this.state = state;
        }
    
        public String getState() {
            return state;
        }
    
        public void setState(String state) {
            this.state = state;
        }
    }
    

    管理者

    public class Caretaker {
        private Memento memento;
    
        public Memento getMemento() {
            return memento;
        }
    
        public void setMemento(Memento memento) {
            this.memento = memento;
        }
    }
    

      

    测试

    public void test(){
            Originator originator=new Originator();
            originator.setState("init");
            System.out.println(originator.getState());
    
            //管理员 保存 现有状态
            Caretaker caretaker=new Caretaker();
            caretaker.setMemento(originator.createMemento());
    
            //更新状态
            originator.setState("running");
            System.out.println(originator.getState());
    
            //恢复状态
            originator.restoreMemento(caretaker.getMemento());
    
            System.out.println(originator.getState());
        }
    

      

    执行结果

    多状态 备忘

    将 对象的属性放在map里

    操作类

    不同类 实现同一操作时 采用不同的方式 。类似java的多态 ,多态的设计思路被多种设计模式使用。

    1. 在方法中实现算法,推迟对算法步骤的定义,使得子类能够重新实现-->模板方法模式
    2. 将操作分散,使得每个类都能够表示不同的状态-->状态模式
    3. 封装操作,使得实现都可以相互替换-->策略模式
    4. 用对象来封装方法调用-->命令模式
    5. 将操作分散,使得每个实现运用到不同类型的集合-->解析器模式

     1.模板方法模式 template mothed

      

     模板方法:抽象一些步骤或将它定义在接口中,以便其他类可以实现这一步骤。

    比如 我们去乘车  大致分为  买票-->进站安检-->检票-->入座

    我现在搞一个系统 乘坐汽车,乘坐火车,乘坐地铁 都用该系统  

    写个demo

     先抽象一个公共父类 定义基本的逻辑框架

    public abstract class Ride {
        //模板 方法 final类型 子类不可以修改
        public final void action(){
            buyTicket();
            securityCheck();
            checkIn();
            seated();
            doStarted();
        }
        //购票
        protected abstract void buyTicket();
        //进站安检
        protected abstract void securityCheck();
        //检票
        protected abstract void checkIn();
        //入座
        protected abstract void seated();
        //钩子方法 ,子类可以不必要实现,如果有需求可以写
        protected void doStarted(){
            System.out.println("车辆启动..");
        }
    }
    

      

     汽车出行

    public class Bus extends Ride {
    
        @Override
        protected void buyTicket() {
            System.out.println("buy a bus ticket.");
        }
    
        @Override
        protected void securityCheck() {
    
            System.out.println("bus station security check.");
        }
    
        @Override
        protected void checkIn() {
            System.out.println("bus station check in.");
        }
    
        @Override
        protected void seated() {
            //按票入座
            System.out.println("ticket seat.");
        }
    }
    

      

    地铁出行

    public class Subway extends Ride {
    
        @Override
        protected void buyTicket() {
            System.out.println("buy a subway ticket.");
        }
    
        @Override
        protected void securityCheck() {
    
            System.out.println("subway station security check.");
        }
    
        @Override
        protected void checkIn() {
            System.out.println("subway station check in.");
        }
    
        @Override
        protected void seated() {
            //随便坐
            System.out.println("Sit casually.");
        }
    }
    

      

    测试

    public void test(){
            Ride ride=new Bus();
            ride.action();
            System.out.println(".....");
            ride=new Subway();
            ride.action();
    
        }
    

    运行结果

     2.状态模式

    程序中 经常 因状态不同,执行的不同逻辑代码 。状态模式: 就是将 这些状态 分为不同的状态对象,

    且 这些状态对象 有自己的状态 行为。解耦 

    网上找了个例子

    四种颜色 

    Red,
    White,
    Blue,
    Black

    有 pull和  push两种操作 

    Color类

    public enum  Color {
        Red,
        White,
        Blue,
        Black
    }
    

    操作管理类

    public class Context {
        private Color color;
    
        public Context(Color color) {
            this.color = color;
        }
    
        public void push(){
            //red->white->blue->black
            if(color==Color.Red) color=Color.White;
            else if(color==Color.White) color=Color.Blue;
            else if(color==Color.Blue) color=Color.Black;
        }
        public void pull(){
            //red<-white<-blue<-black
            if(color==Color.Black) color=Color.Blue;
            else if(color==Color.Blue) color=Color.White;
            else if(color==Color.White) color=Color.Red;
    
    
        }
    }
    

    测试

    public void test(){
            Context context=new Context(Color.Red);
            context.push();
            System.out.println(context.getColor().name());
            context.pull();
            System.out.println(context.getColor().name());
        }
    

    结果

    改用状态模式

    public abstract class State {
        protected abstract void push(Context2 context);
        protected abstract void pull(Context2 context);
        protected abstract Color getColor();
    
    }
    

     

    public class RedState extends State {
        @Override
        protected void push(Context2 context) {
            context.setState(new WhiteState());
        }
    
        @Override
        protected void pull(Context2 context) {
            context.setState(new RedState());
        }
    
        @Override
        protected Color getColor() {
            return Color.Red;
        }
    }
    

     

    public class WhiteState extends State {
        @Override
        protected void push(Context2 context) {
            context.setState(new BlueState());
        }
    
        @Override
        protected void pull(Context2 context) {
            context.setState(new RedState());
        }
    
        @Override
        protected Color getColor() {
            return Color.White;
        }
    }
    

      

    public class BlueState extends State {
        @Override
        protected void push(Context2 context) {
            context.setState(new BlackState());
        }
    
        @Override
        protected void pull(Context2 context) {
            context.setState(new WhiteState());
        }
    
        @Override
        protected Color getColor() {
            return Color.Blue;
        }
    }
    

      

     

    public class BlackState extends State {
        @Override
        protected void push(Context2 context) {
            context.setState(new BlackState());
        }
    
        @Override
        protected void pull(Context2 context) {
            context.setState(new BlueState());
        }
    
        @Override
        protected Color getColor() {
            return Color.Black;
        }
    }
    

      

    测试

     public void test2(){
            Context2 context2=new Context2(new RedState());
            context2.push();
            System.out.println(context2.getState().getColor());
            context2.pull();
            System.out.println(context2.getState().getColor());
        }
    

      

    运行结果

    3.策略模式 strategy

    strategy [ˈstratəjē]

     策略模式 就是 将公共操作 ,在不同类中分别实现,也就是继承公共的接口或父类  。再用策略调用者调用自己需要的策略。

    demo:

    1.策略接口

    public interface Strategy {
        void compress();
    }
    

    2.rar压缩算法实现

    public class RarStrategy implements Strategy {
        @Override
        public void compress() {
            System.out.println("execute rar compression");
        }
    }
    

    3.zip压缩算法实现

    public class ZipStrategy implements Strategy {
        @Override
        public void compress() {
            System.out.println("execute zip compression");
        }
    }
    

    4.调用者类

    public class Context {
        private Strategy strategy;
    
        public Context(Strategy strategy) {
            this.strategy = strategy;
        }
    
        public void executeCompress(){
            strategy.compress();
        }
    }
    

    5.测试

    public void test(){
            Context context=new Context(new RarStrategy());
            context.executeCompress();
            context=new Context(new ZipStrategy());
            context.executeCompress();
        }
    

      

    执行结果

     4.命令模式

      

    命令模式的目的是 将请求 封装到 类内部

    命令模式可以将请求封装在一个对象中  允许你可以像管理对象一样去 管理方法 ,传递 并且在适合的机会调用它 

      

    网上找了个例子 :http://blog.csdn.net/jason0539/article/details/45110355  

     开关电视机的请求

    现在设置 请求命令接口

    public interface Command {
        void execute();
    }
    

    然后 建立一个 TV对象 作为命令的接收者

    public class TV {
    
        void turnOn(){
            System.out.println("The TV is turn on.");
        }
        void turnOff(){
            System.out.println("The TV is turn off.");
        }
    }
    

      

    开机命令

    public class CommandOn implements Command {
        private TV tv;
    
        public CommandOn(TV tv) {
            this.tv = tv;
        }
    
        @Override
        public void execute() {
            tv.turnOn();
        }
    }
    

      

    关机命令

    public class CommandOff implements Command {
        private TV tv;
    
        public CommandOff(TV tv) {
            this.tv = tv;
        }
    
        @Override
        public void execute() {
            tv.turnOff();
        }
    }
    

      

    控制 器   就像遥控器

    public class Control {
        private CommandOn commandOn;
        private CommandOff commandOff;
    
        public Control(CommandOn commandOn, CommandOff commandOff) {
            this.commandOn = commandOn;
            this.commandOff = commandOff;
        }
    
        public void turnOn(){
            commandOn.execute();
        }
    
        public void turnOff(){
            commandOff.execute();
        }
    }
    

     

    测试

     public void test() {
            TV tv = new TV();
            CommandOn commandOn = new CommandOn(tv);
            CommandOff commandOff = new CommandOff(tv);
            Control control=new Control(commandOn,commandOff);
            control.turnOn();
            control.turnOff();
        }
    

    执行结果

    本demo将命令 开机和关机命令 封装 传递 ,并在需要的时候触发

      

    5.解析器模式 Interpreter 

    扩展型设计模式 

    1. 让开发者动态组合对象行为-->装饰器模式
    2. 提供一个方法 来顺序访问 集合中的元素-->迭代器模式
    3. 允许开发者定义新的操作 而无需改变 分层体系中的类-->访问者模式

    1.装饰器模式 decorator

    decorator [ˈdekəˌrātər]

    经典的装饰器模式 就是java中的流处理

     public void test(){
            try {
                FileWriter file=new FileWriter(new File("E://test//test.txt"));
                BufferedWriter writer=new BufferedWriter(file);
                writer.write("this is test file.");
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace(); 
            }
        }
    

    这段代码中 我们从 FileWriter 组合成BufferWriter 最后输入文本;

    通过构造器传入参数 ,产生了新的对象行为。  

    查看下  源码

    2.迭代器模式 Iterator

    为顺序访问集合提供一种方式

    /*
     * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
     *
     *
     */
    
    package java.util;
    
    import java.util.function.Consumer;
    
    /**
     * An iterator over a collection.  {@code Iterator} takes the place of
     * {@link Enumeration} in the Java Collections Framework.  Iterators
     * differ from enumerations in two ways:
     *
     * <ul>
     *      <li> Iterators allow the caller to remove elements from the
     *           underlying collection during the iteration with well-defined
     *           semantics.
     *      <li> Method names have been improved.
     * </ul>
     *
     * <p>This interface is a member of the
     * <a href="{@docRoot}/../technotes/guides/collections/index.html">
     * Java Collections Framework</a>.
     *
     * @param <E> the type of elements returned by this iterator
     *
     * @author  Josh Bloch
     * @see Collection
     * @see ListIterator
     * @see Iterable
     * @since 1.2
     */
    public interface Iterator<E> {
        /**
         * Returns {@code true} if the iteration has more elements.
         * (In other words, returns {@code true} if {@link #next} would
         * return an element rather than throwing an exception.)
         *
         * @return {@code true} if the iteration has more elements
         */
        boolean hasNext();
    
        /**
         * Returns the next element in the iteration.
         *
         * @return the next element in the iteration
         * @throws NoSuchElementException if the iteration has no more elements
         */
        E next();
    
        /**
         * Removes from the underlying collection the last element returned
         * by this iterator (optional operation).  This method can be called
         * only once per call to {@link #next}.  The behavior of an iterator
         * is unspecified if the underlying collection is modified while the
         * iteration is in progress in any way other than by calling this
         * method.
         *
         * @implSpec
         * The default implementation throws an instance of
         * {@link UnsupportedOperationException} and performs no other action.
         *
         * @throws UnsupportedOperationException if the {@code remove}
         *         operation is not supported by this iterator
         *
         * @throws IllegalStateException if the {@code next} method has not
         *         yet been called, or the {@code remove} method has already
         *         been called after the last call to the {@code next}
         *         method
         */
        default void remove() {
            throw new UnsupportedOperationException("remove");
        }
    
        /**
         * Performs the given action for each remaining element until all elements
         * have been processed or the action throws an exception.  Actions are
         * performed in the order of iteration, if that order is specified.
         * Exceptions thrown by the action are relayed to the caller.
         *
         * @implSpec
         * <p>The default implementation behaves as if:
         * <pre>{@code
         *     while (hasNext())
         *         action.accept(next());
         * }</pre>
         *
         * @param action The action to be performed for each element
         * @throws NullPointerException if the specified action is null
         * @since 1.8
         */
        default void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            while (hasNext())
                action.accept(next());
        }
    }
    

     如果一个类 支持 for循环 必须实现Iterable接口 ,并提供 Iterator方法

    public interface Iterable <T>  {
        java.util.Iterator<T> iterator();
    
        default void forEach(java.util.function.Consumer<? super T> consumer) { /* compiled code */ }
    
        default java.util.Spliterator<T> spliterator() { /* compiled code */ }
    }
    

      

    比如我们经常使用的 ArrayList

     3.访问者 visitor模式

    访问者模式的意图是 不改变类层次结构前提下,对该层次结构进行扩展。

     

      

      

      

      

      

      

      

      

  • 相关阅读:
    Java
    Spring
    Q&A
    Q&A
    Q&A
    Spring
    Elasticsearch部署及基本概念
    rust(二) 变量及类型
    rust(一) 一些命令
    vim笔记
  • 原文地址:https://www.cnblogs.com/doon-tianba/p/7788245.html
Copyright © 2011-2022 走看看