当前位置 博文首页 > Ruby使用设计模式中的代理模式与装饰模式的代码实例

    Ruby使用设计模式中的代理模式与装饰模式的代码实例

    作者:范孝鹏 时间:2021-02-03 06:14

    代理模式

    需求:

    小明让小李替他追小丽(送洋娃娃,送花,送巧克力)

    没有代理的代码:

    # -*- encoding: utf-8 -*-
    
    #追求者类
    class Pursuit
     attr_accessor :mm
     
     def initialize(mm)
      @mm = mm
     end
     
     def give_dolls
      puts "#{mm.name} 送你洋娃娃"
     end
     
     def give_flowers
      puts "#{mm.name} 送你鲜花"
     end
     
     def give_chocolate
      puts "#{mm.name} 送你巧克力"
     end
    
    end
    
    #被追求者类
    class Girl
     attr_accessor :name
     
     def initialize(name)
      @name = name
     end
    end
    
    xiao_hong = Girl.new('小红')
    
    xiao_ming = Pursuit.new(xiao_hong)
    xiao_ming.give_dolls
    xiao_ming.give_flowers
    xiao_ming.give_chocolate
    
    

    只有代理的代码:

    # -*- encoding: utf-8 -*-
    
    #代理类
    class Proxy
     attr_accessor :mm
     
     def initialize(mm)
      @mm = mm
     end
     
     def give_dolls
      puts "#{mm.name} 送你洋娃娃"
     end
     
     def give_flowers
      puts "#{mm.name} 送你鲜花"
     end
     
     def give_chocolate
      puts "#{mm.name} 送你巧克力"
     end
    
    end
    
    #被追求者类
    class Girl
     attr_accessor :name
     
     def initialize(name)
      @name = name
     end
    end
    
    xiao_hong = Girl.new('小红')
    
    xiao_ming = Proxy.new(xiao_hong)
    xiao_ming.give_dolls
    xiao_ming.give_flowers
    xiao_ming.give_chocolate
    
    

    只是把追求者类换成了代理类。

    实际的代理模式代码:

    # -*- encoding: utf-8 -*-
    
    #公共接口module
    module GiveGift
     def give_dolls
     end
     
     def give_flowers
     end
     
     def give_chocolate
     end
    end
    
    #追求者类
    class Pursuit
     include GiveGift
     attr_accessor :mm, :name
     
     def initialize(mm)
      @mm = mm
     end
     
     def give_dolls
      puts "#{mm.name} 替#{name}送你洋娃娃"
     end
     
     def give_flowers
      puts "#{mm.name} 替#{name}送你鲜花"
     end
     
     def give_chocolate
      puts "#{mm.name} 替#{name}送你巧克力"
     end
    
    end
    
    #代理类
    class Proxy
     include GiveGift
     attr_accessor :gg
     
     def initialize(mm)
      @gg = Pursuit.new(mm)
     end
     
     def give_dolls
      gg.give_dolls
     end
     
     def give_flowers
      gg.give_flowers
     end
     
     def give_chocolate
      gg.give_chocolate
     end
    
    end
    
    #被追求者类
    class Girl
     attr_accessor :name
     
     def initialize(name)
      @name = name
     end
    end
    
    xiao_hong = Girl.new('小红')
    
    xiao_ming = Proxy.new(xiao_hong)
    xiao_ming.gg.name = '小明'
    xiao_ming.give_dolls
    xiao_ming.give_flowers
    xiao_ming.give_chocolate
    
    


    装饰模式
     
    需求:

    给人搭配不同的服饰

    代码版本一

    # -*- encoding: utf-8 -*-
    
    class Person
     attr_accessor :name
     
     def initialize(name)
      @name = name
     end
     
     def wear_t_shirts
      puts '大T恤'
     end
     
     def wear_big_trouser
      puts '垮裤'
     end
     
     def wear_sneakers
      puts '破球鞋'
     end
     
     def wear_suit
      puts '西装'
     end
     
     def wear_tie
      puts '领带'
     end
     
     def wear_leather_shoes
      puts '皮鞋'
     end
     
     def show
      puts "*****装扮的#{name}\n\n"
     end
    
    end
    
    
    xc=Person.new('小菜')
    puts "******第一种装扮"
    xc.wear_t_shirts
    xc.wear_big_trouser
    xc.wear_sneakers
    xc.show
    
    puts "******第二种装扮"
    xc.wear_suit
    xc.wear_tie
    xc.wear_leather_shoes
    xc.show
    
    

    这样写的话,功能是实现了,问题是如果增加“超人”的装扮,就要修改Person类,违反了开放-封闭原则。

     

    代码版本二

    # -*- encoding: utf-8 -*-
    
    class Person
     attr_accessor :name
     
     def initialize(name)
      @name = name
     enddef show
      puts "*****装扮的#{name}\n\n"
     end
    
    end
    
    
    class Finery
     def show
     end
    end
    
    class TShirts < Finery
     def show
      puts '大T恤'
     end
    end
    
    class BigTrouser < Finery
     def show
      puts '垮裤'
     end
    end
    
    class Sneakers < Finery
     def show
      puts '破球鞋'
     end
    end
    
    class Suit < Finery
     def show
      puts '西装'
     end
    end
    
    class Tie < Finery
     def show
      puts '领带'
     end
    end
    
    
    class LeatherShoes < Finery
     def show
      puts '皮鞋'
     end
    end
    
    
    xc=Person.new('小菜')
    ts = TShirts.new
    bt = BigTrouser.new
    sk = Sneakers.new
    puts "******第一种装扮"
    ts.show
    bt.show
    sk.show
    xc.show
    
    
    suit = Suit.new
    tie = Tie.new
    ls = LeatherShoes.new
    puts "******第二种装扮"
    suit.show
    tie.show
    ls.show
    xc.show
    
    

    这样改了之后,如果增加超人装扮,确实不需要去修改Person类。存在的问题是,各种衣服是独立的,并且暴露在外边的,就是一件一件穿的,没有顺序,没有控制。

    代码版本三

    # -*- encoding: utf-8 -*-
    
    class Person
     attr_accessor :name
     
     def initialize(name=nil)
      @name = name
     end
     
     def show
      puts "*****装扮的#{name}\n\n"
     end
    
    end
    
    
    class Finery < Person
     attr_accessor :componet
    
     def decorate(componet)
      @componet = componet
     end
    
     def show
      componet.show if componet
     end
    end
    
    class TShirts < Finery
     def show
      super
      puts '大T恤'
     end
    end
    
    class BigTrouser < Finery
     def show
      super
      puts '垮裤'
     end
    end
    
    class Sneakers < Finery
     def show
      super
      puts '破球鞋'
     end
    end
    
    class Suit < Finery
     def show
      super
      puts '西装'
     end
    end
    
    class Tie < Finery
     def show
      super
      puts '领带'
     end
    end
    
    
    class LeatherShoes < Finery
     def show
      super
      puts '皮鞋'
     end
    end
    
    
    xc=Person.new('小菜')
    ts = TShirts.new
    bt = BigTrouser.new
    sk = Sneakers.new
    puts "******第一种装扮"
    ts.decorate xc
    bt.decorate ts
    sk.decorate bt
    sk.show
    
    
    suit = Suit.new
    tie = Tie.new
    ls = LeatherShoes.new
    puts "******第二种装扮"
    suit.decorate xc
    tie.decorate suit
    ls.decorate bt
    ls.show
    

    js
    下一篇:没有了