ell*_*t42 7 javascript ruby lisp python clojure
我有一个非常常见的模式"给一个Foo,返回一个Bar",例如,给一个user_id,返回一个User.
这些功能是否有传统的命名模式?继在软件乔尔,我个人用了很多bar_from_foo(),但我很少看到别人这样做,它很快变得冗长,如
widgets = user_widgets_from_user(user_from_param_map(params))
Run Code Online (Sandbox Code Playgroud)
是否有传统的方式来命名或命名空间(例如User.from_map())在任何流行的语言?我对Python特别感兴趣,但你能想到的任何语言都会很有用.
leo*_*ges 15
我会利用Clojure的命名灵活性并称之为:
(defn foo->bar [] ...)
Run Code Online (Sandbox Code Playgroud)
对我来说,这意味着很清楚,而且很短.
如果你想要的东西转换成另一种,例如一个字符串转换为整数,该方法是将接收器上的定义,因此,它的类是明确的,所以你不应该把接收机类的方法名称的一部分:String#to_i,没有String#string_to_i.这是面向对象编程(多态)的核心思想之一.
如果接收器是太一般要分配这样的方法,例如,如果user_id是纯粹的字符串,并定义一个方法String将其转换为一个User看起来不正确的,那么你应该定义在您所期望的回报类的构造方法价值是:User.new或User.from_id.
在Python和各种其他OO语言中,这应该是Bar上的构造函数,它将单个Foo作为唯一参数.由于Python不进行方法重载(并且尝试模拟它通常很脆弱),如果Bar.__init__已经采用不同的签名,那么约定就是最后一个.重要的是,这通常被定义为类方法而不是静态方法(为了子类的利益):
class Bar:
@classmethod
def from_foo(cls, f):
'''Create a new Bar from the given Foo'''
ret = cls()
# ...
Run Code Online (Sandbox Code Playgroud)
我认为这在很大程度上取决于上下文和选择有意义的隐喻。例如,ActiveRecord 使用类方法“find”在数据库中查找记录,这比“输入 user_id,输出用户”更有意义。例如:
User.find(user_id)
User.find_by_email(user_email)
Run Code Online (Sandbox Code Playgroud)
对于转换,我通常喜欢编写转换方法以使其易于在高阶函数中使用。例如,在 ruby 中,转换通常使用to_*实例方法完成,例如将 a 转换Foo为 a ,为所有 fooBar提供一个方法是有意义的to_bar,因此您可以编写:
foo = Foo.new(...) # make a new Foo
bar = foo.to_bar # convert it to a Bar
Run Code Online (Sandbox Code Playgroud)
然后要转换一堆 foo,你可以简单地:
bars = foos.map(&:to_bar)
Run Code Online (Sandbox Code Playgroud)
Ruby 还倾向于将Foo.parse(str)字符串转换为对象。
对于 javascript,我喜欢使用类方法(我从标准 ml 中获得),例如:
Foo.toBar = function(foo) {
return new Bar(...);
};
Run Code Online (Sandbox Code Playgroud)
然后你也可以映射它(在本例中使用下划线):
var bars = _.map(foos, Foo.toBar);
Run Code Online (Sandbox Code Playgroud)
标准 ML 约定是结构(类)方法。fn 类型示例:
Foo.toBar : foo -> bar
Foo.fromBar : bar -> foo
Run Code Online (Sandbox Code Playgroud)
你会这样使用它:
val bar = Foo.toBar foo;
val bars = map Foo.toBar foos;
Run Code Online (Sandbox Code Playgroud)