Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无AOP框架动态添加方面的软件设计_Java_Design Patterns_Decorator_Interceptor_Aop - Fatal编程技术网

Java 无AOP框架动态添加方面的软件设计

Java 无AOP框架动态添加方面的软件设计,java,design-patterns,decorator,interceptor,aop,Java,Design Patterns,Decorator,Interceptor,Aop,我编写了一个小示例程序来测量java方法的执行时间。 我想设计一个低耦合的解决方案,它可以动态地添加到其他方法中,这意味着如果我用其他方法编写其他类,我希望将性能度量模块包装在业务逻辑模块上,并在业务逻辑类与性能度量模块没有依赖关系时度量方法的执行时间 我当前的解决方案如下所示 我有一个抽象类,它定义了一些列表操作 我有定义具体列表操作的子类 我有一个性能测量等级,它扩展了应测量的等级 public abstract class ListOperations<T> { pri

我编写了一个小示例程序来测量java方法的执行时间。 我想设计一个低耦合的解决方案,它可以动态地添加到其他方法中,这意味着如果我用其他方法编写其他类,我希望将性能度量模块包装在业务逻辑模块上,并在业务逻辑类与性能度量模块没有依赖关系时度量方法的执行时间

我当前的解决方案如下所示

  • 我有一个抽象类,它定义了一些列表操作
  • 我有定义具体列表操作的子类
  • 我有一个性能测量等级,它扩展了应测量的等级

    public abstract class ListOperations<T> {
    
      private List<T> list;
    
      public ListOperations() {
         initList();
      }
    
      /**
       * Initializes the list. Clients can decide which list type shall be used (e.g LinkedList, ArrayList etc.)
       */
      public abstract void initList();
    
      public abstract void addLast(final T element);
    
      public List<? super T> getList() {
          return list;
      }
    
      protected void setList(final List<T> list) {
          this.list = list;
      }
    }
    
    
    
    
    public class LinkedListOperations<T> extends ListOperations<T> {
    
    public LinkedListOperations() {
        super();
    }
    
    @Override
    public void addLast(final T element) {
        getList().addLast(element);
    }
    
    @Override
    public void initList() {
        setList(new LinkedList<T>());
    }
    
    @Override
    public LinkedList<? super T> getList() {
        return (LinkedList<? super T>) super.getList();
    }
    }
    
    
    
    public class PerformanceMeassuredLinkedListOperations<T> extends LinkedListOperations<T> {
    
    private static final String START_PERFORMANCE_MEASSURE_FOR_METHOD = "Start Performance Meassure for method: ";
    private static final String STOP_PERFORMANCE_MEASSURE_FOR_METHOD = "Stop Performance Meassure for method: ";
    private static final String TIME_EXECUTION_IN_MILLIS = "Time Execution in Millis: ";
    
    /**
     * Used to printout the name of the method from the stack. in depth 2 the real business logic method is located
     */
    private static final int DEPTH_IN_STACKTRACE = 2;
    // depth 0 = printStopMeassurement
    // depth 1 = stopPerformanceMeassure
    // depth 2 = method for which performance is measured (e.g addLast)
    
    private long startCurrentTimeMillis;
    
    @Override
    public void initList() {
        startPerformanceMeassure();
        super.initList();
        stopPerformanceMeassure();
    }
    
    public void meassureAddLast(final int numberOfElements, final T testElement) {
        startPerformanceMeassure();
        for (int i = 0; i < numberOfElements; i++) {
            addLast(testElement);
        }
        stopPerformanceMeassure();
    }
    
    protected void startPerformanceMeassure() {
        printStartMeassurement();
        startCurrentTimeMillis = System.currentTimeMillis();
    }
    
    private void printStartMeassurement() {
        System.out.println(START_PERFORMANCE_MEASSURE_FOR_METHOD + getNameOfCurrentExecutedMethod());
    }
    
    protected void stopPerformanceMeassure() {
        System.out.println(TIME_EXECUTION_IN_MILLIS + (System.currentTimeMillis() - startCurrentTimeMillis));
        printStopMeassurement();
    }
    
    private void printStopMeassurement() {
        System.out.println(STOP_PERFORMANCE_MEASSURE_FOR_METHOD + getNameOfCurrentExecutedMethod());
    }
    
    private String getNameOfCurrentExecutedMethod() {
        final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
        return ste[ste.length - DEPTH_IN_STACKTRACE].getMethodName();
    }
    
    }
    
    
    
    public class Main {
    
    public static void main(String[] args) {
        PerformanceMeassuredLinkedListOperations<String> listOperations = new PerformanceMeassuredLinkedListOperations<String>();
        listOperations.meassureAddLast(50000, "Hello");
    }
    }
    
    公共抽象类ListOperations{
    私人名单;
    公开上市业务(){
    initList();
    }
    /**
    *初始化列表。客户端可以决定使用哪种列表类型(例如LinkedList、ArrayList等)
    */
    公共摘要void initList();
    公共摘要void addLast(最终T元素);
    
    public List你不想使用一个经过验证和测试的框架,因为只有你自己才能做得更好,可以用一个框架交换另一个框架——你自己的框架。不管怎样,你最终会使用一个框架。这有意义吗

    祝你好运,重新发明轮子

    更新:关于为什么我认为您最终会实现自己的AOP框架的更多背景信息:AOP与OOP的继承概念有点正交。没有任何语义扩展(如AspectJ)的OOP语言或框架(如Spring AOP)无法提供表示方面的方法,否则AOP语言/frameworks将是多余的。我怀疑你仅仅通过两种左右的OOP设计模式的组合就能解决这个问题


    更新2:如果设计模式失败,并且字节码生成对您来说太复杂,您可能希望使用与Spring AOP相同的方法:Java动态代理(适用于接口)和/或CGLIB动态代理(适用于非接口类型).

    您不想使用经过验证和测试的框架,因为只有您自己才能做得更好,可以将一个框架转换为另一个框架—您自己的框架。尽管如此,您最终将使用一个框架。这有意义吗

    祝你好运,重新发明轮子

    更新:关于为什么我认为您最终会实现自己的AOP框架的更多背景信息:AOP与OOP的继承概念有点正交。没有任何语义扩展(如AspectJ)的OOP语言或框架(如Spring AOP)无法提供表示方面的方法,否则AOP语言/frameworks将是多余的。我怀疑你仅仅通过两种左右的OOP设计模式的组合就能解决这个问题


    更新2:如果设计模式失败,并且字节码生成对您来说太复杂,您可能希望使用与Spring AOP相同的方法:Java动态代理(适用于接口)和/或CGLIB动态代理(适用于非接口类型)。

    您所描述的是 您的需求完全属于一个方面,您希望能够记录代码中不同切点的延迟

    如果你愿意,你可以投票否决我的答案,但如果你自己做,你最终会用另一个名字做一个方面

    考虑:

    方法1

    • 您需要拦截对上述业务模块的所有调用
    • 您可以定义一个
      businessmodule
      接口。创建一个代理类,该类截获此公共调用,然后包装一个抽象方法并记录延迟(或其他)
    • 它是有限的,但是,通过一些努力可以工作,这是最简单的实现
    方法2

    • 开发某种表达性语言,说明您希望在哪些类上拦截哪些方法
    • 找出一种拦截这些方法调用的方法(不使用AspectJ,也不编写自己的类加载器,我无法想象)并执行它们
    方法1完全不是动态的。您必须对整个系统的实现具有严格的控制。任何未包含在委托/代理方案中的类都不会获得此行为。必须有人确保每个实现的类都有此包装器

    方法2是超级动态的。通过一种表达性的语言/语法,你可以描述代码来获得包装器,然后,即使它不是你的代码或者你正在与懒惰的人一起工作,它仍然会被包装。缺点是实现起来非常困难和耗时。好消息!Spring AOP和AspectJ已经完成了这项工作是!

    那么,你的问题是

    如果没有Spring AOP或AspectJ,我怎么做

    我相信我已经给出了一个答案。但要完全清楚:大量的授权将是最简单的途径


    这就是说:没有很好的理由可以解释你自己的。我确实有一个方面和Spring的bean配置来做这件事。如果是时间问题,我可以简单地将它粘贴进去,你可以把它撕下来并用它运行。

    你所描述的是一个 您的需求完全属于一个方面,您希望能够记录代码中不同切点的延迟

    如果你愿意,你可以投票否决我的答案,但如果你自己做,你最终会用另一个名字做一个方面

    考虑:

    方法1

    • 您需要拦截对上述业务模块的所有调用
    • 您可以定义一个
      businessmodule
      接口。创建一个代理类,该类截获此公共调用,然后包装一个抽象方法并记录延迟(或其他)