重新认识装饰模式--装饰模式实现AOP

一、AOP是什么

AOP:面向方面编程,他是一种编程范式,提供从另外一个角度来考虑程序结构以完善面向对象编程。

二、AOP的功能

在系统开发过程中会有一些共性的功能,这是面向对象的纵向思考方式就能解决问题了,这时候AOP横向延伸就可以解决这些公共服务织入系统中。AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,比如事务处理、日志处理、权限控制封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

按照装饰模式对比上述过程,业务功能对象就可以被看做被装饰的对象,而各个公共的模块就好比是装饰器,可以透明地给业务功能对象增加功能。

所以从某个侧面来说,装饰模式和AOP要实现的功能相似,只不过AOP的实现方法不同,会更加灵活,更加可配置,另外AOP一个更加重要的变化时思想上的变化----主从换位,让原本主动调用的功能模块变成了被动等待,甚至在毫不知情的情况下被织入很多新的功能。

三、用装饰实现AOP:

package itcast.test.decorator;
/**
 * 装饰器的接口,需要和被装饰的对象实现同样的接口*/
public abstract class Dercorator implements GoodsSaleEbi {
    /**
     * 持有被装饰的组件对象*/
    protected GoodsSaleEbi ebi;
    /**
     * 通过构造方法传入被装饰对象
     * @prara, ebi被装饰的对象*/
    public Dercorator(GoodsSaleEbi ebi){
        this.ebi=ebi;
    }
}
package itcast.test.decorator;
public class CheckDecorator extends Dercorator{
    /**
     * 实现权限控制*/
    public CheckDecorator(GoodsSaleEbi ebi){
        super(ebi);
    }

    public boolean sale(String user,String customer,SaleModel saleModel){

        //简单点儿,只让张三执行这个功能
        if(!"张三".equals(user)){
            System.out.println("对不起"+user+",你没有保存销售单的权限");
            //就不用再调用被装饰的对象的功能了
            return false;
        }else{
            return this.ebi.sale(user,customer,saleModel);
        }
    }
}
package itcast.test.decorator;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class LogDercorator extends Dercorator{
    public LogDercorator(GoodsSaleEbi ebi){
        super(ebi);
    }
    public boolean sale(String user,String customer,SaleModel saleModel){
        //执行业务功能
        boolean f= this.ebi.sale(user, customer, saleModel);
        //执行业务功能后记录日志
        DateFormat df= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");

        System.out.println("日志记录:"+user+"于"+df.format(new Date())+"时保存了一条销售记录,客户是"+customer+",购买记录是"+saleModel);

        return f;
    }
}
package itcast.test.decorator;
//商品销售管理的业务接口
public interface GoodsSaleEbi {
    /* * 保存销售信息
     * @param customer 客户
     * @param saleModel 销售数据
     * @return 是否保存成功*/
    public boolean sale(String user,String customer,SaleModel saleModel);
}
package itcast.test.decorator;
public class GoodsSaleEbo implements GoodsSaleEbi {
    @Override
    public boolean sale(String user, String customer, SaleModel saleModel) {
        System.out.println(user+"保存了"+customer+"购买"+saleModel+"的销售数据");
        return true;
    }
}
package itcast.test.decorator;
/**
 * 封装好的销售单数据对象*/
public class SaleModel {
    private String goods;
    private int saleNum;
    public String getGoods() {
        return goods;
    }
    public void setGoods(String goods) {
        this.goods = goods;
    }
    public int getSaleNum() {
        return saleNum;
    }
    public void setSaleNum(int saleNum) {
        this.saleNum = saleNum;
    }

    public String toString(){
        return "商品名称="+goods+",购买数量="+saleNum;
    }

}
package itcast.test.decorator;
public class Client {
    public static void main(String[] args){
        //得到业务接口,组合装饰器
        GoodsSaleEbi ebi = new CheckDecorator(new LogDercorator(new GoodsSaleEbo()));
        /*准备测试数据*/
        SaleModel saleModel= new SaleModel();
        saleModel.setGoods("MoTo 手机");
        saleModel.setSaleNum(2);

        //调用和业务功能
        ebi.sale("张三", "张三丰", saleModel);
        ebi.sale("李四", "张三丰", saleModel);

    }
}

运行结果:

四、分析

装饰可以实现AOP的功能,同时也可以实现关于任何的组合的方式,那么现在我们能够看出,装饰模式的本质有两点:动态+组合,也就是说装饰模式可以动态组合出任何的功能,把这些功能给我们的业务功能做外层包装,这样也就实现了AOP的功能。装饰模式比继承更灵活,更加容易复用功能,并且可以简化对于高层的定义。但是有上述代码中我们可以看出产生了很多细粒度的对象,例如LogDercorator、GoodsSaleEbo等,当功能越复杂的时候,需要的细粒度的对象越多。

时间: 2024-11-02 22:55:00

重新认识装饰模式--装饰模式实现AOP的相关文章

跟我学设计模式视频教程——装饰模式,装饰模式VS代理模式

课程视频 装饰模式 装饰模式VS代理模式1 装饰模式VS代理模式2 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 跟我学设计模式视频教程--装饰模式,装饰模式VS代理模式,布布扣,bubuko.com

装饰模式Decorator

第三章 装饰模式Decorator  1.1 什么是装饰模式? 装饰模式Decorator,动态的给一些对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活 1.2装饰模式Decorator的结构图 Component是定义一个对象接口,可以给这些对象动态的添加职责. ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责. Decorator装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,

《java与设计模式》之装饰模式详解&Java IO中的装饰器模式

1 概述 在一个项目中,你会有非常多的因素考虑不到,特别是业务的变更,不时的冒出一个需求是很正常的情况.有三个继承关系的类:Father.Son.GrandSon,我们要在Son类上增强一些功能怎么办?给Son类增加方法吗?那对GrandSon的影响呢?特别是对GrandSon有多个的情况,你会怎么办?认真看完本文,你会找到你的答案. JavaIO中,像下面的嵌套语句是不是很常见,为什么要怎样定义呢?理解装饰模式后,你会找到答案. DataInputStream in = new DataInp

设计模式笔记——装饰模式

装饰模式 装饰模式(Decorator),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 1.装饰模式的特点 (1)装饰对象和真实对象有相同的接口.这样客户端对象就能以和真实对象相同的方式和装饰对象交互. (2)装饰对象包含一个真实对象的引用(reference) (3)装饰对象接受所有来自客户端的请求.它把这些请求转发给真实的对象. (4)装饰对象可以在转发这些请求以前或以后增加一些附加功能.这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功

[Python设计模式] 第6章 衣服搭配系统——装饰模式

题目 设计一个控制台程序,可以给人搭配嘻哈风格(T恤,垮裤,运动鞋)或白领风格(西装,领带,皮鞋)的衣服并展示,类似QQ秀那样的. 基础版本 class Person(): def __init__(self, name): self.name = name def wear_T_shirts(self): print("T恤") def wear_big_trouser(self): print("垮裤") def wear_sneakers(self): pri

python学习之aop装饰模式

实际开发过程当中可能要对某些方法或者流程做出改进,添加监控,添加日志记录等所以我们要去改动已有的代码,自己的或者别人的,但改动后测试不周会引发不可控的异常,aop 模式解决了这类问题引发重复代码大量积累,装饰器解决了些类问题 import functools #采用functools.wraps的目的是为了使装饰器返回的类型始终是func的类型,否则将返回嵌套高阶函数的中的类型,例如返回的是wraper #采用参数*args ,**kw是解决函数多参数的问题 def log(func): @fu

装饰模式之AOP之动态改变参数,和原函数绑定属性丢失

//动态改变参数一Function.prototype.before = function( beforefn ){ var __self = this; return function(){ beforefn.apply( this, arguments ); // (1) return __self.apply( this, arguments ); // (2) } } var func = function( param ){ console.log( param ); // 输出: {

设计模式初探

1.适配器模式 类适配器 对象适配器 默认适配器模式 2.桥梁模式 将抽象化与实现脱耦,使得二者可以独立的变化 桥接:为被分离了的抽象部分和实现部分来搭桥 如何桥接:桥接在程序上就体现成了在抽象部分拥有实现部分的接口对象 谁来桥接的问题: 就是谁来负责创建抽象部分和实现部分的关系 3.组合模式 Composite 将对象组合成树形解雇以表示"整体-部分"的层次结构 4.享元模式 FlyWeight 采用一个共享来避免大量拥有相同内容对象的开销 5.责任链模式 当客户提交一个请求时,从第

ANDROID 中设计模式的采用--结构型模式

结构型模式中的适配器模式.外观模式.装饰模式.代理模式都属于包装模式,都是对另外的类或对象的包装,只是各自的意图不同. 适配器模式通过对另外的类或对象的包装,将其接口转换为用户期望的接口,达到接口适配的目的. 外观模式是对包装的一组类或对象提供一个高层接口,意图是简化接口,使系统更加容易使用. 装饰模式的意图是在不改变包装对象接口的情况下为其增加另外的功能或职责. 代理模式的意图是通过对包装对象的包装以便控制对包装对象的访问. 适配器模式.外观模式对客户提供的接口与其包装类的接口有所不同,也就是