Должен ли я назвать пространство моделей STI?
У меня есть следующие модели:
module Core
class Conditioner
include Mongoid::Document
field :operator, type: String, default: '' # can be !=, ==, <, >, <=, >=, =
end
end
module Core
class Count < Conditioner
field :threshold, type: Integer, default: 0 # a simple threshold
end
end
module Core
class Time < Conditioner
UNITS = %w(seconds minutes hours days weeks months years)
# will be use like this: Time.value.send(Time.unit) Ex: 3.minutes
field :value, type: Integer, default: 0 # 3
field :unit, type: String, default: '' # minutes
validates :unit, presence: true, inclusion: { in: UNITS }
end
end
Интересно, если я должен пространство имен Count
а также Time
класс с Conditioner
? Как это:
module Core
class Conditioner::Time < Conditioner
end
end
Так как я должен позвонить Time.now
как это сейчас ::Time.now
,
РЕДАКТИРОВАТЬ
Что касается ответов, может быть, это должна быть лучшая идея:
module Core
module Conditioner
class Base
end
end
end
module Core
module Conditioner
class Count < Conditioner::Base
end
end
end
module Core
module Conditioner
class Time < Conditioner::Base
end
end
end
Так как определение класса называется Core::Time
может быть слишком общим и не имеет большого смысла.
Как вы думаете? Не уверен насчет лучшей практики здесь.
3 ответа
Вам не нужно указывать пространство имен, хотя вы можете, если хотите.
Должны ли вы или не должны зависеть от того, что вы хотите моделировать (а не от того, нужно ли вам обращаться к Time с помощью:: Time или нет...). Похоже, ваш Core:: Time уже является подклассом Core:: Conditioner, поэтому нет смысла делать его внутренним классом своего суперкласса. В вашем случае лучше не указывать это пространство имен.
Иметь то же имя класса, что и для ruby, здесь не проблема, поскольку вы уже поместили его в пространство имен с помощью Core.
На мой взгляд, не используйте имя класса, которое использовали Ruby или Rails, это может быть проблемой. Вы должны быть осторожны, когда используете его. Я думаю, что это не нужно. Не используйте пространства имен, если вы не хотите поддерживать много моделей. Держите это простым, и обслуживание будет легче:)
Единственное, что вы меняете префиксом Conditioner
в Time
является то, что поиск констант для Core
модуль не увидит ваш Conditioner::Time
класс при взгляде вверх Time
, Все остальные занятия (Count
, Conditioner
) все равно буду думать Conditioner::Time
заменяет Time
,
module Core
def time
Time.now
end
class Conditioner
def time
Time.now
end
end
end
module Core
class Count < Conditioner
def time
Time.now
end
end
end
module Core
class Conditioner::Time < Conditioner
def time
Time.now
end
end
end
Любой звонок, как Core::Count.new.time
потерпит неудачу, но
class A
include Core
end
A.new.time
выдаст текущее время, а в этом случае:
module Core
def time
Time.now
end
class Conditioner
def time
Time.now
end
end
end
module Core
class Count < Conditioner
def time
Time.now
end
end
end
module Core
class Time < Conditioner
def time
Time.now
end
end
end
class A
include Core
end
A.new.time
также не удастся. Теперь причина довольно проста: поиск констант всегда просматривает константы, доступные в текущем пространстве имен (Core
), затем поднимается вверх по цепочке предков текущего пространства имен, прежде чем искать в пространстве имен Object
(Time
также можно назвать Object::Time
, Он не будет искать в дочерних пространствах имен (которые вы создаете, помещая Conditioner::
до Time
) хотя и поэтому переименовываю свой класс Time
в Conditioner::Time
изменяет только поиск для Core
модуль, но не для классов в Core
,
Итак, просим наилучшей практики в этом случае: просто оставьте это при вызове вашего класса Time
и ссылаясь на Object::Time
от ::Time
, Это довольно известная практика, и преимущества дополнительных пространств имен, позволяющие избежать ее использования, незначительны.