oop - 一个类在其自身上执行功能是好的约定吗?

标签 oop class

我一直被教导如果你正在对一个对象做某事,那应该是一个外部的东西,所以人们会 Save(Class) 而不是拥有对象保存自身:Class.Save()

我注意到在 .Net 库中,类通常使用 String.Format() 修改自身或使用 List.Sort() 对自身进行排序

我的问题是,在严格的 OOP 中,拥有一个在调用时对自身执行函数的类是否合适,或者此类函数应该是外部函数并在类类型的对象上调用?

最佳答案

好问题。我最近刚刚反射(reflection)了一个非常相似的问题,最终打算在这里问同样的问题。

在 OOP 教科书中,您有时会看到诸如 Dog.Bark()Person.SayHello() 之类的示例。我得出的结论是,这些都是不好的例子。当您调用这些方法时,您会发出狗叫声,或者有人打招呼。但是,在现实世界中,您不能这样做;狗自己决定什么时候要叫。一个人自己决定何时向某人打招呼。因此,这些方法更适合建模为事件(在编程语言支持的情况下)。

你会,例如具有 Attack(Dog)PlayWith(Dog)Greet(Person) 函数,它们会触发相应的事件。

Attack(dog)      // triggers the Dog.Bark event 
Greet(johnDoe)   // triggers the Person.SaysHello event 

一旦您拥有多个参数,决定如何最好地编写代码就不会那么容易了。假设我想将一个新项目(比如一个整数)存储到一个集合中。有很多方法可以表达这一点;例如:

StoreInto(1, collection)    // the "classic" procedural approach
1.StoreInto(collection)     // possible in .NET with extension methods
Store(1).Into(collection)   // possible by using state-keeping temporary objects

根据上面列出的想法,最后一个变体将是首选,因为它不会强制对象(1)对自己做某事。但是,如果您遵循这种编程风格,您很快就会发现这种类似流畅界面的代码相当冗长,虽然读起来容易,但也可能很累人编写甚至难以记住确切的语法。


P.S.:关于全局函数:对于 .NET(您在问题中提到),您没有太多选择,因为 .NET 语言不提供全局函数.我认为这些在技术上可以通过 CLI 实现,但语言不允许该功能。 F# 具有全局函数,但它们只能在被打包到模块中时从 C# 或 VB.NET 中使用。我相信 Java 也没有全局函数。

我遇到过这种缺失令人遗憾的场景(例如,使用流畅的界面实现)。但是一般来说,没有全局函数我们可能会更好,因为一些开发人员可能总是会回到旧习惯,并留下一个过程代码库供 OOP 开发人员维护。哎呀。

顺便说一句,但是,在 VB.NET 中,您可以通过使用模块来模拟全局函数。示例:

Globals.vb:

    Module Globals
        Public Sub Save(ByVal obj As SomeClass)
            ...
        End Sub
    End Module

Demo.vb:

    Imports Globals
    ...
    Dim obj As SomeClass = ...
    Save(obj)

关于oop - 一个类在其自身上执行功能是好的约定吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3105692/

相关文章:

javascript - 迭代 HTMLcollection 以动态定义构造函数中的值?

c# - 如何跳过类中接口(interface)的实现

c# - 如何从一种方法中使用的类访问不同方法中的信息?

c++ - 如何链接多个运算符[]

javascript - 从继承类访问父级 "this"变量

matlab - 有没有办法找到一个 Matlab 类的所有 child ?

database - 图数据库中的面向对象编程

c++ - 使用 not2 时将 struct vs class 作为 STL 仿函数

c++ - friend 类声明

python - 在 Python 中创建类后向其添加方法