Rubyクラス継承、抽象クラス、クラス拡張混入、エージェントクラスインスタンス

4944 ワード

仕事で出会ったクラス拡張をまとめます.
1、クラス継承:
複数のクラスが複数のメソッドを共通に使用する場合、共通メソッドの部分を抽出し、必要なクラスを関連継承することができます.
例:
 
  
class A < ActiveRecord::Base
    def a
        p "it was a "
    end
end

class Bend

class Cend

B.new.a #=>"it was a "
C.new.a #=>"it was a "


2、抽象類
複数のクラスが1つのクラスを継承する場合、最初の方法で問題が発生します.(他の人の注釈を引用して抽象類の運用を説明しましょうhttps://ihower.tw/rails4/activerecord-others.html)
�我槐砀窭^承STI(Single-table inheritance)
どのように�10�の锛�の中の�^は概念を受けて、�P�式のY料�の美しい脳O�まで、�大哉�です.Rails�冉はその中で最も�蔚嚢�解法で、ただ1�Y料表�だけである.Υセシウム^承�w系のものに、type�谖挥�碇同�@�P�Y料の�e名�Qを组み合わせます.
要�_STI机能は、T例によっては1つの凶悪なタイプ、タイプB文字列があればよい.仮�O以下のposts�Y�料表には�谖唤凶�typeがあり、その�N�@三�Models�H上就�はposts一�Y�料表を共用しています.presence_of :subject:
 
  
class Post < ActiveRecord::Base 
    validates_presence_of :subject 
end 
 
class GuestPost < Post 
end 
 
class MemberPost < Post 
end 

�我�M入rails console�见て、Rails�根�あなたが使う�e、尤皮O定type�
 
  
post = GuestPost.create( :subject => "guest")
post.type # "GuestPost"
post.id # 1
post = MemberPost.create( :subject => "member" )
post.id # 2
post.type # "MemberPost"
GuestPost.last # 1

残念ながら、�檫@�T例の�P�Sのため、あなたは�type�@�Nの名前を流用することができません.STI最大の�谖壊睦速Mでは、�^承�w系の中で交わる�多くの共用しないものがあれば、P者�建�hは使用しないでください.eの�eには自分の�Y料表があります.要�P�]STI、父�eにselfを加える.abstract_class = true
 
  
class Post < ActiveRecord::Base 
    self.abstract_class = true 
end 
 
class GuestPost < Post 
end 
 
class MemberPost < Post 
end 

,@eのGuestPostとMemberPostは独自のMigrationsでguest_を確立する必要がありますpostsとmember_posts�Y材料表.
また、あるクラスに複数の依存を導入することもできます.
 
  
class Dependency     require_dependency 'guestpost' 
    require_dependency 'memberpost' 
end 

3、類開拓混入
rubyのクラスは単一継承であり,マルチ継承機能を実現するにはmixin(パラレルモード)方式,すなわちクラス拡張混入で実現する必要がある.例:
 
  
module Extract 
  def self.included(base) 
     base.extend(ClassMethods) 
  end 
  module ClassMethods 
     def a 
        p "it was a " 
     end 
  end 
end   
 
class A<:base>   include Extract 
end 
 
A.new.a  #=>"it was a" 

4、代理類
ある機能が複雑である場合,もちろん再libを書く場合,関数向けの方法として処理するのは簡単であり,エージェントクラス方式でオブジェクト向けの呼び出しを実現することもできる.
例:
 
  
class A<:base>  def generate_schedule
    generator =  Generator::ExcelGenerator.new(self)
    generator.generate_schedule
  end
end

module Generator
  class ExcelGenerator

    attr_reader :excel,:workbook,:a,:worksheet
    attr_accessor :styles

    def initialize(a)
      @excel ||= Axlsx::Package.new
      @workbook ||= @excel.workbook
      @worksheet = @workbook.add_worksheet(:name => ' excel ')
      @a ||= a
      @styles ||= Hash.new
    end
   
    def generate_schedule
        #excel
    end

  end
end

A.new.generate_schedule ExcelGenerator A generate_schedule


もちろん、クラスインスタンスの追加方法はincludeのmodelで実現することもでき、混合して使用することもできます.また、エージェントクラスを使用するメリットは、複数のクラスが同じ方法を必要とする場合に共通の部分を定義し、メールを送信する例を挙げることです.
 
  
class A<:base>     include SendEmail
end

class B<:base>     include SendEmail
end


導入モジュールの実装:
 
  
module SendEmail
    #include this module to class::A and B
    #use like that--  A.first.send_email
    def send_email
      Email.call_email(self)
    end
end

エージェントクラスの実装:
 
  
class Email < ActionMailer::Base
  default :from => "[email protected]"

  def self.call_email(obj)
     define_method "#{obj.state}" do |obj|
       @obj = obj
       mail(:to => @obj.email, :subject => "XX " )
     end
     send("#{obj.state}").deliver
     # obj.state , , send 。
  end
    
end


RUBYは柔軟でもちろん他にも多くの方法が実現されていますが、後でゆっくりとまとめます.