我有很多实例方法,都共享相同的实例变量。 由于课程变得庞大,我将方法分成大约50个模块。 然后剩下的课程包括所有这50个模块。
我最终得到了一个令人难以置信的丑陋代码,其中充满了像“module_name_method_name”这样的实例方法,以避免方法名称的冲突。 问题是每个模块可能具有相似(相似,不相同)的功能(反过来类似的方法名称)。
我目前的代码如下:
模块:
module Toyota
def toyota_method1;@foo...;end
def toyota_method2;@foo...;end
....
end
module Ford
def ford_method1;@foo...;end
def ford_method2;@foo...;end
....
end
....大约50个这样的模块
class Cars
include Toyota
include Ford
include ...
def foo
@foo = "bar"
@bar = "foo"
...
toyota_method1
ford_method2
toyota_method2
...
end
end
我怎样才能更好地设计代码? 最重要的是所有实例方法需要共享相同的实例变量..或者至少以某种方式可以访问相同的数据!
编辑: 我自己想出了这个:
class Toyota
attr_accessor :foo
def method1
puts @foo
end
end
class Ford
attr_accessor :foo
def method1
puts @foo
end
end
class Cars
def foo
@foo = "bar"
toyota = Toyota.new
toyota.foo = @foo
toyota.method1
ford = Ford.new
ford.foo = @foo
ford.method1
end
end
cars = Cars.new
cars.foo
实际上它解决了丑陋的方法名称问题,但现在我正在处理新问题:变量@foo可能非常大并且它将自身重复50次(或更多)到内存中(因为我有50个这样的类)。
还有其他解决方案吗?
答案 0 :(得分:1)
它不仅重复50次或更多,每个实例重复一次,因为它是一个实例变量。从我可以告诉你的代码,如果我错了你必须纠正我,你最好在类级别上使用inheritance和变量共享。如果你的汽车类真的需要知道它可能是所有类型的所有不同方法,那么这可能不起作用,但是我会说你从一开始就做了一些固有的错误。那么让我们来看看继承:
class Car
attr_accessor :foo
# lets you initialize attributes via a hash
#
def initialize attrs={}
super()
attrs.each do |att, value|
self.send(:"#{att}=", value)
end
end
end
从Toyota
继承Car
:
class Toyota < Car
def method1
# do what you want to do in this method
end
end
Ford
相同:
class Ford < Car
def method1
# do what you want to do in this method
end
end
像这样,您不必将名称空间放在方法前面:
Ford.new(:foo => 'fordfoo').foo #=> will put out «fordfoo»
Toyota.new(:foo => 'toyotafoo').foo #=> will put out «toyotafoo»
现在,如果foo
在所有汽车中共享,那么如果汽车类是静态的,您可以将其设为a)constant:
class Car
FOO = 'bar'
def put_foo
puts FOO
end
end
像这样,Car
,Toyota
或Ford
的所有实例都可以访问静态常量FOO
,它只会在内存中存在一次:
Toyota.new.put_foo #=> 'bar'
如果foo
必须是可分配的,并且只需要存在一次整个继承树,请使用class variables:
class Car
class << self
def foo= data
@@foo = data
end
end
def foo= data
self.class.foo = data
end
def foo
@@foo
end
end
现在@@foo
仅对继承树存在一次,所以如果你这样做:
car = Car.new
toyota = Toyota.new
toyota.foo = 'toyota'
car.foo #=> 'toyota'
如果你没有注意,这可能会导致严重的问题,但如果foo
对于所有课程都必须相同,那么这就是要走的路。 Thread Safety还有一些问题需要解决(Mutex
}使用类变量。
如果Car
,Toyota
和Ford
都有不同的foo
,但每个类的实例需要共享相同的foo(因此总共有3个foo) ),使用class instance variables:
class Car
class << self
def foo= data
@foo = data
end
def foo
@foo
end
end
def foo= data
self.class.foo = data
end
def foo
self.class.foo
end
end
像这样你会得到:
car = Car.new
car.foo = 'bla'
toyota = Toyota.new
toyota.foo #=> is nil
toyota.foo = 'bar'
car.foo #=> still 'bla'
toyota.foo #=> is 'bar'
这些是跨实例共享相同数据的方法。