Ruby类继承、抽象类、类拓展混入、代理类实例
技术  /  管理员 发布于 6年前   284
总结一下工作中遇到的类扩展:
1、类继承:
当多个类公用很多方法的时候可以将公用方法部分抽取出来,需要的类做相关继承。
例子:
复制代码 代码如下:
class A < ActiveRecord::Base
def a
p "it was a "
end
end
class B<A
end
class C<A
end
B.new.a #=>"it was a "
C.new.a #=>"it was a "
2、抽象类
当多个类要继承一个类时,用第一种方法,会遇到一个问题。
(引用一个别人的注解来描述抽象类的运用吧https://ihower.tw/rails4/activerecord-others.html)
我槐砀窭^承STI(Single-table inheritance)
如何⑽锛蛑械睦^承概念,疥P式Y料的O,是大哉。Rails冉似渲凶詈蔚囊解法,只用一Y料表Υ胬^承w系中的物件,搭配一type谖挥碇该@PY料的e名Q。
要_STI功能,依照T例只要有一谖唤凶type,型B字串即可。假O以下的postsY料表有谖唤凶type,那N@三ModelsH上就灿posts一Y料表,然,有@子e也都^承到父e的validates_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
很z憾,也因檫@T例的PS,你不能type@N名字挪做它用。
STI最大的}在於谖坏睦速M,如果^承w系中交集的谖徊欢啵屈N使用STI就浅5睦速M空g。如果有^多的不共用的谖唬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_postsY料表。
你还可以在某个类中,引入多个依赖
复制代码 代码如下:
class Dependency<Post
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<ActiveRecord::Base
include Extract
end
A.new.a #=>"it was a"
4、代理类
当某个功能是比较复杂的,当然写再lib中,作为一个面向函数的方法去处理很简单,也可以用代理类的方式实现面向对象的调用。
例子:
复制代码 代码如下:
class A<ActiveRecord::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<ActiveRecord::Base
include SendEmail
end
class B<ActiveRecord::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很灵活当然还有很多其他的方法实现更多的方式,以后再慢慢总结。
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号