2014-10-01 77 views
0

我有SQLite3 gem,我只能初始化一次数据库。假设我有method1,它调用method2十次,它调用method3二十次,它需要访问SQLite数据库并更新一些记录。如果我在method3内初始化它,我将最终得到100多个SQLite3实例。 Method1,method2和method3都在不同的类中。无法传递冗余参数

我通过在顶层创建新实例,然后将其传递到method1,然后传递到method2method3来解决此问题。这是不可持续的,因为如果我用两个或三个以上的参数(例如我有另外三个数据库method3将更新)来做这个,将会有很多冗余参数。

我该如何解决这个问题?一些想法正在创建一个全局变量或一个常量,它将在程序初始化时开始。另外,覆盖new方法。我不知道每个的优点和缺点。如果你知道其他方法,或上述两者的优点/缺点/可行性,请告诉我。

下面是一个例子代码:

require 'sqlite3' 

class A 
    db = SQLite3::Database.new('somename.sqlite') 

    def call_other_method 
    B.new.other_method 
    end 
end 

class B 
    def other_method 
    C.new.other_method_2 
    end 
end 

class C 
    def other_method_2 
    # I want to call here methods on db, without passing it as an arg, first 
    # to call_other_method, then to other_method and then to other_method_2 
    end 
end 

A.new.call_other_method 
+2

的[Singleton模式](http://en.wikipedia.org/wiki/Singleton_pattern)就是你正在请求。 – mudasobwa 2014-10-01 12:18:52

+0

安装'ActiveRecord' gem(它可以在轨道外使用),你的生活会变得更容易。 – BroiSatse 2014-10-01 12:19:21

+1

你可以发布一些你试过的代码来解决你的问题吗? – Surya 2014-10-01 12:32:14

回答

0

的一种方法是:

module Sqlite3Connection 
    require 'sqlite3' 

    def self.connection 
    @@db ||= SQLite3::Database.new('somename.sqlite') 
    end 
end 

require 'sqlite3_connection' 
class SQLite3Record 
    include Sqlite3Connection 

    attr_reader :db 

    def initialize 
    @db = SQLite3Connection.connection 
    end 

end 

class A < SQLite3Record 

    def call_other_method 
    # did you mean this?: 
    10.times{ B.new.other_method } 
    # or?: 
    # b = B.new 
    # 10.times { b.other_method } 
    end 
end 

class B < SQLite3Record 

    def other_method 
    # did you mean this?: 
    20.times{ C.new.other_method_2 } 
    # or?: 
    # c = C.new 
    # 20.times { c.other_method2 } 
    end 
end 

class C < SQLite3Record 

    def other_method_2 
    # will be called 200 times! 
    # will have single instance of "SQLite3::Database" here accessible via method db. 
    db.execute(sql) 
    end 
end 

A.new.call_other_method