关于ruby:在两个类之间共享一个类实例

Sharing a class instance between two classes

我有两个不同的类,它们都表示需要持久化到数据库中的对象,现在我想在两个类之间共享数据库客户机对象。我希望避免多次实例化客户机对象。

目前,我通过使用全局变量来实现这一点

1
2
3
4
5
6
7
8
9
10
11
12
13
$client = Mysql2::Client.new(:database =>"myDb", :user =>"user", :password =>"password", :host =>"localhost")

class Person
  def save
    $client.query("INSERT INTO persons")
  end
end

class Car
  def save
    $client.query("INSERT INTO cars")
  end
end

这是可行的,但我想知道是否有更正确的方法来做到这一点,以及为什么它们更正确?


你可以从父类继承。这个功能允许你分享的对象是在普通和干(不要重复自己)规划原则。所以,你想让它保护你的数据库连接和锁定,resuces,游泳池,和任何其他线索,你可能想要做一个没有你担心你的儿童班

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Record
  @table_name = nil
  @@client = Mysql2::Client.new(:database =>"myDb", :user =>"user", :password =>"password", :host =>"localhost")

  def save
    @@client.query("INSERT INTO #{@table_name}") if @table_name
  end
end

class Person < Record
  @table_name ="persons"
end

class Car < Record
  @table_name ="cars"
end

而我们的主题,你应该看看你的数据库使用ActiveRecord模型的处理和连接。它已经是相当多的东西,你会需要将更多的兼容其他宝石已经出去了。它也可以用于讽刺。


在使用作为替代继承,为什么不考虑一个简单的单件模式?这可以让你的模特在清洁,分捡的责任你的班。和消除需要继承。

下面的例子illustrates本。只有一个单实例类的datamanager CAN存在。所以,你只有一次,但它instantiate CAN使用它无处不在。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
require 'singleton'

class DataManager
  include Singleton

  attr_accessor :last_run_query

  def initialize()
    if @client.nil?
      p"Initialize the Mysql client here - note that this'll only be called once..."
    end
  end

  def query(args)
    # do your magic here
    @last_run_query = args
  end

end

下一步,调用它使用访问器是一个.instance微风和我点到一个单实例,像这样:

1
2
3
4
5
6
7
8
9
10
11
# Fetch, or create a new singleton instance
first = DataManager.instance
first.query('drop table mother')
p first.last_run_query

# Again, fetch or create a new instance
# this'll actually just fetch the first instance from above
second = DataManager.instance
p second.last_run_query

# last line prints:"drop table mother"

Singleton模式的记录,有一些downsides CAN和使用它的结果在A没有结尾的辩论对你是否应该使用它。但在我看来它是非常另类的特异性问题。