• 请不要在回答技术问题时复制粘贴 AI 生成的内容
zjsxwc
V2EX  ›  程序员

Python 、 PHP 、Ruby 这些语言为什么不抄下 Java 的动态代理来实现 AOP?

  •  
  •   zjsxwc ·
    zjsxwc · Mar 15, 2018 · 4122 views
    This topic created in 2985 days ago, the information mentioned may be changed or developed.

    我看了 Java 的动态代理实现原理( http://blog.csdn.net/weidea/article/details/43348447 ) 的文章,

    对应 Python、PHP、Ruby 这些语言来说山寨个 newProxyInstance 方法很简单啊,新手都可以花几小时就实现,为什么唯独就 Java 来说动态代理和 AOP 很火?

    Supplement 1  ·  Mar 15, 2018
    ruby、python 有猴子补丁,
    php 有__call 方法

    感觉都有点反模式
    Supplement 2  ·  Mar 15, 2018
    思考了下。

    对于动态语言,函数、方法 本身就是对象,他们天生就可以被赋值与传递,于是用猴子补丁这种手段,可以动态修改实例对象已经拥有的方法,也就是说其实我们可以随意拿捏对象,而不用管他最初的 class 是什么,这对于 ruby\python\php\js 来说很简单( php 需要稍微修改下__call 方法来实现 https://phpfashion.com/monkey-patching-v-php )。

    而 Java 是做不到这种任性地修改对象的方式,只能通过动态代理的方式来实现。
    13 replies    2018-03-16 08:25:04 +08:00
    F281M6Dh8DXpD1g2
        1
    F281M6Dh8DXpD1g2  
       Mar 15, 2018   ❤️ 3
    ruby 表示笑翻在地
    zjsxwc
        2
    zjsxwc  
    OP
       Mar 15, 2018
    @liprais 猴子方法我知道。。
    zjsxwc
        3
    zjsxwc  
    OP
       Mar 15, 2018
    @zjsxwc 但我觉得猴子方法反模式啊
    fool079
        4
    fool079  
       Mar 15, 2018
    python 表示????
    vindurriel
        5
    vindurriel  
       Mar 15, 2018 via iPhone
    静态语言才需要动态代理 动态语言不需要
    这几种语言都可以实现 aop 具体方法 google 语言名称 + aop
    至于为什么 aop 只有在 java 火 大概是因为 java 设计强制 oop 导致代码冗余 引入 aop 有助于缓解冗余吧
    SlipStupig
        6
    SlipStupig  
       Mar 15, 2018
    python 表示很无辜....
    janxin
        7
    janxin  
       Mar 15, 2018
    动态语言都笑了-,-
    tailf
        8
    tailf  
       Mar 15, 2018
    动态语言的发明者就是不想写那一大坨代码才用动态的。。。。
    toono
        9
    toono  
       Mar 15, 2018
    最近看 python 的书,感觉 python 就是让你突破在 其他语言很必要用设计模式才能方便实现和管理代码 的限制。

    所以在其他语言应该用设计模式的地方,对 python 苛求模式的人,是不是在写 java 式 python ?因为很可能根据 python 的特性,不照搬设计模式可能会实现得更方便。


    上面的小例证可以考虑 java 和 python 对于“策略模式”(来自《流畅的 python 》)
    假设在不同的情况下需要执行不同的 run 方法

    java 实现策略模式的时候,可能是几个子类继承同一个父类 A,并且都实现了 run 方法。这样在不同的类型情况下都能够调用子类实体的 run 方法,而且不同子类实体工作内容不相同。

    python 的实现可以声明几个函数都放在一个数组中,然后选件选择运行哪个就好了。还可以用单分派泛函数 singledispatch 装饰器简单实现 java 的重载。

    只能说每个语言都有它的特点
    wwqgtxx
        10
    wwqgtxx  
       Mar 15, 2018 via iPhone
    说反模式的只是因为你习惯了 java 的模式,但这并不是 ruby/python/php 的模式
    sorra
        11
    sorra  
       Mar 15, 2018
    @zjsxwc Java 的动态代理才是反模式,有很多限制。静态编织更好,但构建过程要复杂。
    Ruby 的猴子补丁还可以,如果能冻结就是好模式了。
    多学习。
    Pool
        12
    Pool  
       Mar 15, 2018
    设计模式这种东西本来就是针对静态的 OOP 才总结出来的套路。
    对于动态语言来说有相应语法来支持,不是更好吗?
    不用纠结设计模式这种模式这种东西,不增加代码的复杂度并实现了功能才是最好的
    msg7086
        13
    msg7086  
       Mar 16, 2018
    很多设计模式是因为这些语言太不灵活,没法做到一些功能,而被迫创造出来的东西。
    你贴的这篇文章我看了很久很久,算是看明白个大概了。
    是说你拿到一个对象,想在外面包一层,然后动态改变其中的某个方法行为吧。
    这不是 Ruby 的猴子补丁,猴子补丁是修改方法本身,你需要的是 Delegation,所以可以这样写:

    require 'active_support'
    require 'active_support/core_ext/module/delegation'

    def wrap(source, overrides)
      klass = Class.new do
       delegate_missing_to :@source
       def initialize(source)
        @source = source
       end

       overrides.each do |func, code|
        define_method(func, &code)
       end
      end
      klass.new(source)
    end

    a = [1, 2]
    a << 3
    puts a
    b = wrap(a, {:<< => ->(*args) { puts 'foo' } })
    b << 4
    b[1] = 5
    puts b
    puts a



    # ruby test.rb
    1
    2
    3
    foo
    1
    5
    3
    1
    5
    3
    不知道是不是你提到的东西。这里我 wrap 函数只是简单写下,但是应该是能够处理各种你想要的状况的,比如 before_hook after_hook wrap_hook 等等。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2873 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 11:02 · PVG 19:02 · LAX 04:02 · JFK 07:02
    ♥ Do have faith in what you're doing.