是否有理由为单一功能创建类?

gen*_*sis 13 php class function

我见过很多带有SINGLE功能的类.他们为什么要把一个SINGLE函数放到课堂上?

我使用类只是为了让事情变得更清楚,但关于那些将SINGLE函数放入类中的人呢?有什么理由吗?

我认为这些没有区别:

<?php
class Image {
    private $resource;
    function resize($width, $height) {
        $resized = imagecreatetruecolor($width, $height);
        imagecopyresampled($resized, $this->resource, 0, 0, 0, 0, $width, $height, imagesx($this->resource), imagesy($this->resource));
        $this->resource = $resized;
    }
}
$image = new Image();
$image->resource = "./someimage.jpg";
$image->resize(320, 240);
Run Code Online (Sandbox Code Playgroud)

    function resize($width, $height) {
        $resource = "./someimage.jpg";    
        $resized = imagecreatetruecolor($width, $height);
        imagecopyresampled($resized, $resource, 0, 0, 0, 0, $width, $height, imagesx($resource), imagesy($resource));
        $resource = $resized;
        return $resource;
    }

resize(320, 240);
Run Code Online (Sandbox Code Playgroud)

我的想法是$资源是主要原因,因为它是私有的:

class Image {
    private $resource;
    function resize($width, $height) {
        $resized = imagecreatetruecolor($width, $height);
        imagecopyresampled($resized, $this->resource, 0, 0, 0, 0, $width, $height, imagesx($this->resource), imagesy($this->resource));
        $this->resource = $resized;
    }
}

$image->resize(320, 240);
Run Code Online (Sandbox Code Playgroud)

因此无法进入全球范围.但为什么不是这种情况下使用的简单函数?

Orb*_*ing 28

类不仅仅是"函数容器",它们代表一个对象,一个实体.它们应该使用适合它的方法封装给定实体所需的数据.

有时候可能有一类对象只需要为它定义一个方法,但它只属于那个对象类.

  • +1如果我想多态地` - > foo()`某些对象,我不会说某些对象可能没有任何其他方法.我也不会在一个只是为了避免看起来太短的类体有用的地方避免多态性. (3认同)

Lor*_*oh. 9

我主要做嵌入式编程,很少使用类.但是单个函数类可能用于 -

  • 后来继承了
  • 强制执行类私有的数据结构的完整性(封装).
  • 可用于保持代码的同质性.


web*_*ave 7

为什么有些函数只有一行代码?因为这就是所需要的.现在你可以调用函数而不是在任何地方重复单行代码.如果需要调整该行代码,则只需在一个地方进行.这是利用程序封装.

你的简短课程也是如此.您现在可以利用所有类可以执行的操作,尤其是继承和多态,比如说SVGImage extends Image和覆盖方法resize.

实现必要的功能不需要最少的行数.


joh*_*ohn 6

而不是将一个类视为一个函数集合,而是根据类的角色进行思考.类通常应该知道它包含什么,而不知道它不包含什么,并且应该只捕获一个关键的抽象.可能存在有意义的情况.


jed*_*ung 6

这实际上是一个很好的问题,我在这里看到了一些好的答案.实际上我真的不得不考虑一下这个问题.

我想在这里添加一些我在其他任何答案中都没有看到的东西,即使我没有得到任何选票,这样未来的读者也会受益.

我们来看看你的例子吧.(我对它们进行了编辑,使它们在功能上完全相同 - 它们与上面的内容略有不同.)

班级版本:

<?php
class Image {
    private $resource;
    function resize($width, $height) {
        $resized = imagecreatetruecolor($width, $height);
        imagecopyresampled($resized, $this->resource, 0, 0, 0, 0, $width, $height, imagesx($this->resource), imagesy($this->resource));
        $this->resource = $resized;
    }
}
$image = new Image();
$image->resource = "./someimage.jpg";
$image->resize(320, 240);
Run Code Online (Sandbox Code Playgroud)

功能版本:

    function resize($width, $height, $resource) {
        $resized = imagecreatetruecolor($width, $height);
        imagecopyresampled($resized, $resource, 0, 0, 0, 0, $width, $height, imagesx($resource), imagesy($resource));
        $resource = $resized;
        return $resource;
    }

resize(320, 240, "./someimage.jpg");
Run Code Online (Sandbox Code Playgroud)

在实践中,这些在功能上是相同的.主要区别仅在于OOP范式与程序范式; 在OOP中,您在类中定义一个函数(这称为方法),该函数作用于成员变量,而在过程程序中,您将该变量传递给全局范围中定义的函数.

那么,将一个函数包装在一个类中而不是使它成为全局函数有什么好处,因为该函数仍然做同样的事情?

您希望在PHP(以及我能想到的许多其他语言)中执行此操作的主要原因是范围.@Headspin简要地提到了这一点.resize在全局范围内定义一个函数一切都很好......直到你需要另一个具有相同名称的函数.怎么了?

通常,您会遇到以下解决方案之一:

  1. (好的.)你的语言支持函数重载,所以只要你的论点不同,你就不用担心它.
  2. (不好.)你的语言不支持函数重载(或者你的参数必须相同),所以你求助于详细的命名(比如resize_image,resize_container)等.
  3. (还是不错.)您开始使用命名空间来分隔全局函数.
  4. (丑陋.)你的函数接受任何作为参数的东西,并成为它将处理的每个变量类型的if/then语句或switch/case块的热门,臃肿的混乱.

我在PHP中封装函数的主要原因是避免命名冲突,使代码更直观,更容易理解.我可以在我的Image课堂上有一个调整大小的方法,并且在我的班级中有一个Container,也许在test班级或类似的东西中有一个,并且它们中没有一个会相互冲突.阅读代码,我知道Image->resize()Image类中调用方法而没有别的.

没有名称冲突会带来更多可能性,例如迭代共享公共方法名称的一组对象.(这是界面发挥作用的地方;阅读它们.)你可以做很多很酷的事情.

我想就是这样 - 我希望有所帮助.以下是TL; DR版本.

在类中封装单个函数可以防止类似函数的命名冲突,而无需使用命名空间,函数重载或函数重命名.因此,如果您有一个执行通用任务的函数,最好为函数处理的每个变量类型创建一个类,并将该函数转换为类方法.