用最简单的例子说明设计模式(三)之责任链、建造者、适配器、代理模式、享元模式

责任链模式

一个请求有多个对象来处理,这些对象是一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链中的下一个对象,直到有对象处理它为止

使用场景

1)有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定

2)在不明确指定接收者的情况下,向多个对象中的一个提交一个请求

3)可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求

public class Chain {

    public abstract class Handler {
        private Handler nextHandler;
        // 当前领导能审批通过的最多天数
        public int maxDay;

        protected Handler(int maxDay) {
            this.maxDay = maxDay;
        }

        //设置责任链中下一个处理请求的对象
        public void setNextHandler(Handler handler) {
            nextHandler = handler;
        }

        protected void handleRequest(int day) {
            if (day <= maxDay) {
                reply(day);
            } else {
                if (nextHandler != null) {
                    //审批权限不够,继续上报
                    nextHandler.handleRequest(day);
                } else {
                    System.out.println("没有更高的领导审批了");
                }
            }
        }

        protected abstract void reply(int day);
    }

    class ProjectManager extends Handler {
        public ProjectManager(int day) {
            super(day);
        }

        @Override
        protected void reply(int day) {
            System.out.println(day + "天请假,项目经理直接审批通过");
        }
    }

    class DepartmentManager extends Handler {
        public DepartmentManager(int day) {
            super(day);
        }

        @Override
        protected void reply(int day) {
            System.out.println(day + "天请假,部门经理审批通过");
        }
    }

    class GeneralManager extends Handler {
        public GeneralManager(int day) {
            super(day);
        }

        @Override
        protected void reply(int day) {
            System.out.println(day + "天请假,总经理直接审批通过");
        }
    }

    public static void main(String[] strings) {
        Chain chain = new Chain();
        Handler projectManager = chain.new ProjectManager(3);
        Handler departmentManager = chain.new DepartmentManager(5);
        Handler generalManager = chain.new GeneralManager(15);
        //创建职责链
        projectManager.setNextHandler(departmentManager);
        departmentManager.setNextHandler(generalManager);
        //发起请假请求
        projectManager.handleRequest(4);
    }
}

  

Buidler(建造者)模式

一种创建型的设计模式.,通常用来将一个复杂的对象的构造过程分离, 让使用者可以根据需要选择创建过程.另外, 当这个复杂的对象的构造包含很多可选参数时, 也可以使用建造者模式

public class AlerDialog {

    private  String title;
    private  String message;

    public AlerDialog(Builder builder) {
//        View.inflate()
        this.title = builder.title;
        this.message = builder.message;
    }

    public static class Builder {
        private  String title;
        private  String message;

        public  Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        public   Builder setMessage(String message) {
            this.message = message;
            return this;
        }

        public  AlerDialog build() {
            return new AlerDialog(this);
        }
    }
}
 new AlerDialog.Builder().setTitle("").setMessage("").build();

  

适配器模式:

把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起使用的类能够一起工作。  

适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。

类适配器

原理:通过继承来实现适配器功能。

类适配器使用对象继承的方式,是静态的定义方式

对于类适配器,适配器可以重定义Adaptee的部分行为,使Adaptee有了sampleOperation2()

对于类适配器,仅仅引入了一个对象,并不需要额外的引用来间接得
到 Adaptee

对于类适配器,由于适配器直接继承了Adaptee,使得适配器不能和
Adaptee的子类一起工作

public interface Target {

    void sampleOperation1();

    void sampleOperation2();
}
public class Adaptee {

    public void sampleOperation1() {
        System.out.println("sampleOperation1");
    }
}
public class Adapter extends Adaptee implements Target {

    @Override
    public void sampleOperation2() {
        System.out.println("sampleOperation2");
    }

}
public class MyClass {
    public static void main(String[] args) {
        Adapter adapter = new Adapter();
        adapter.sampleOperation1();
        adapter.sampleOperation2();
    }
}

  

对象适配器

与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。

对象适配器使用对象组合的方式,是动态组合的方式

对于对象适配器,一个适配器(adaptee)可以把多种不同的源适配到同一个目标

对于对象适配器,要重定义Adaptee的行为比较困难

对于对象适配器,需要额外的引用来间接得到Adaptee。

public interface Target {

    void sampleOperation1();

    void sampleOperation2();
}

public class Adaptee {
    public void sampleOperation1() {
        System.out.println("sampleOperation1");
    }
}

public class Adapter implements Target {

    private Adaptee mAdaptee;

    public Adapter(Adaptee adaptee) {
        mAdaptee = adaptee;
    }

    @Override
    public void sampleOperation1() {
        mAdaptee.sampleOperation1();
    }

    @Override
    public void sampleOperation2() {
        System.out.println("sampleOperation2");
    }

}

public class MyClass {

    public static void main(String[] args) {
        Adapter adapter =new Adapter(new Adaptee());
        adapter.sampleOperation1();
        adapter.sampleOperation2();
    }
}

  

代理模式

通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,扩展目标对象的功能。在调用这个方法前作的前置处理(统一的流程代码放到代理中处理)。调用这个方法后做后置处理。
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法。

动态代理的用途与装饰模式很相似,就是为了对某个对象进行增强。所有使用装饰者模式的案例都可以使用动态代理来替换。

/**
 * subject(抽象主题角色):
 * 真实主题与代理主题的共同接口。
 */
interface Subject {
    void sellBook();
}

/**
 * ReaISubject(真实主题角色):
 * 定义了代理角色所代表的真实对象。
 */
public class RealSubject implements Subject {
    @Override
    public void sellBook() {
        System.out.println("出版社卖书");
    }
}

/**
 * Proxy(代理主题角色):
 * 含有对真实主题角色的引用,代理角色通常在将客
 * 户端调用传递给真实主题对象之前或者之后执行某些
 * 操作,而不是单纯返回真实的对象。
 */
public class ProxySubject implements Subject {

    private RealSubject realSubject;

    @Override
    public void sellBook() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        sale();
        realSubject.sellBook();
        give();
    }

    public void sale() {
        System.out.println("打折");
    }

    public void give() {
        System.out.println("送优惠券");
    }
}

public class Main {
    public static void main(String[] args) {
        //静态代理(我们自己静态定义的代理类)
        ProxySubject proxySubject = new ProxySubject();
        proxySubject.sellBook();

        //动态代理(通过程序动态生成代理类,该代理类不是我们自己定义的。而是由程序自动生成)
        RealSubject realSubject = new RealSubject();
        MyHandler myHandler = new MyHandler();
        myHandler.setProxySubject(realSubject);
        Subject subject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),
                realSubject.getClass().getInterfaces(), myHandler);
        subject.sellBook();

    }
}

public class MyHandler implements InvocationHandler {
    private RealSubject realSubject;

    public void setProxySubject(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    /**
     * @param proxy   指代我们所代理的那个真实对象
     * @param method   指代的是我们所要调用真实对象的某个方法的Method对象
     * @param args    指代的是调用真实对象某个方法时接受的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        sale();
        proxy = method.invoke(realSubject, args);
        give();
        return proxy;
    }

    public void sale() {
        System.out.println("打折");
    }

    public void give() {
        System.out.println("送优惠券");
    }
}

  

享元模式

享元的目的是为了减少不会要额内存消耗,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗。

public class FlyWeight {

    static class MyString {
        private String myChar;

        public MyString(String myChar) {
            this.myChar = myChar;
        }

        public void display() {
            System.out.println(myChar);
        }
    }

    static class MyCharacterFactory {

        private Map<String, MyString> pool;

        public MyCharacterFactory() {
            pool = new HashMap<>();
        }

        public MyString getMyCharacte(String strig) {
            MyString myString = pool.get(strig);
            if (myString == null) {
                myString = new MyString(strig);
                pool.put(strig, myString);
            }
            return myString;
        }
    }

    public static void main(String[] args) {
        MyCharacterFactory myCharacterFactory = new MyCharacterFactory();
        MyString a = myCharacterFactory.getMyCharacte("a");
        MyString b = myCharacterFactory.getMyCharacte("b");
        MyString a1 = myCharacterFactory.getMyCharacte("a");
        MyString d = myCharacterFactory.getMyCharacte("d");

        if (a == a1) {
            System.out.println("true");
        }

    }
}

  

相关源码:https://github.com/peiniwan/DesignPattern.git

原文地址:https://www.cnblogs.com/liuyu0529/p/9021641.html

时间: 2024-10-11 12:26:45

用最简单的例子说明设计模式(三)之责任链、建造者、适配器、代理模式、享元模式的相关文章

Java设计模式(六)合成模式 享元模式

(十一)合成模式 Composite 合成模式是一组对象的组合,这些对象可以是容器对象,也可以是单对象.组对象允许包含单对象,也可以包含其他组对象,要为组合对象和单对象定义共同的行为.合成模式的意义是 保证客户端调用单对象与组合对象的一致性. class TreeNode{ private String name; private TreeNode parent; private Vector<TreeNode> children = new Vector<TreeNode>();

设计模式--组合模式&amp;享元模式&amp;桥梁模式

一.组合模式 组合模式也叫作部分-整体模式,其定义如下:将对象组合成树形结构以表示"部分"和"整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 组合模式的优点和使用场景 优点:1.节点增加和减少是非常自由和方便的,这也是树形结构的一大特点:2.所有节点,不管是分支节点还是叶子结点,不管是调用一个结点,还是调用一个结点群,都是非常方便的.使用场景:1.维护部分与整体的逻辑关系,或者动态调用整体或部分的功能接口,可以考虑使用组合模式.例如,非常多的操作系

设计模式(28)-----结构型模式-----享元模式

享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象.我们将通过创建 5 个对象来画出 20 个分布于不同位置的圆来演示这种模式.由于只有 5 种可用的颜色,所以 color 属性被用来检查现有的 Circle 对象.这里只有5个对象的. 介绍 意图:运用共享技术有效地支持大量细粒度的对象. 主

java设计模式--结构型模式--享元模式

享元模式 概述 运用共享技术有效地支持大量细粒度的对象. 适用性 当都具备下列情况时,使用Flyweight模式: 1.一个应用程序使用了大量的对象. 2.完全由于使用大量的对象,造成很大的存储开销. 3.对象的大多数状态都可变为外部状态. 4.如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象. 5.应用程序不依赖于对象标识.由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值. 参与者 1.Flyweight 描述一个接口,通过这个接口flywe

Java进阶篇设计模式之七 ----- 享元模式和代理模式

前言 在上一篇中我们学习了结构型模式的组合模式和过滤器模式.本篇则来学习下结构型模式最后的两个模式, 享元模式和代理模式. 享元模式 简介 享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 用通俗的话来说就是进行共用.生活中也有一些例子,比如之前很火的共享单车,更早之前的图书馆,编程中经常用的String类,数据库连接池等等.当然,享元模式主要的目的是复用,如果该对象没有的话,就会进行创建. 享

5分钟读书笔记之 - 设计模式 - 享元模式

本章探讨另一种优化模式-享元模式,它最适合于解决因创建大量类似对象而累及性能的问题.这种模式在javascript中尤其有用,因为复杂的javascript代码很快就会用光浏览器的所有可用内存,通过把大量独立对象转化为少量共享对象,可以降低运行web应用程序所需的资源数量. 享元模式用于减少应用程序所需对象的数量.这是通过对对象的内部状态划分为内在数据和外在数据俩类实现的.内在数据是指类的内部方法所需要的信息,没有这种数据的话类就不能正常运转.外在数据则是可以从类身上剥离并存储在其外部的信息.我

javascript设计模式——享元模式

前面的话 享元(flyweight)模式是一种用于性能优化的模式,“fly”在这里是苍蝇的意思,意为蝇量级.享元模式的核心是运用共享技术来有效支持大量细粒度的对象.如果系统中因为创建了大量类似的对象而导致内存占用过高,享元模式就非常有用了.在javascript中,浏览器特别是移动端的浏览器分配的内存并不算多,如何节省内存就成了一件非常有意义的事情.本文将详细介绍享元模式 享元模式初识 假设有个内衣工厂,目前的产品有50种男式内衣和50种女士内衣,为了推销产品,工厂决定生产一些塑料模特来穿上他们

设计模式-12 享元模式(结构型模式)

一 享元模式 享元模式的主要目的是实现对象的共享,即共享池,当系统中对象多的时候可以减少内存的开销,通常与工厂模式一起使用. 主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建. 关键代码:存储相似的对象 使用场景: 1.系统有大量相似对象. 2.需要缓冲池的场景. 类图 : 二 实现代码 Java里面的JDBC连接池,适用于作共享的一些个对象,他们有一些共有的属性,就拿数据库连接 池来说,url.driv

设计模式--享元模式C++实现

1定义 使用共享对象可有效的支持大量细粒度的对象 2类图 角色分析 Flyweight抽象享元角色,一个产品的抽象,定义内部状态和外部状态的接口或者实现 ConcreteFlyweight具体享元角色,实现抽象角色定义的业务.注:内部状态处理和环境无关 unsharedConcreteFlyweight不可共享的享元角色,不存在外部状态或者安全要求,不能够使用共性技术的对象,该对象一般不会出现在享元工厂中 Flyweight享元工厂,就是构造一个池容器,同时提供从翅中获得对象的方法 3实现 #p