14

I've seen a lot of classes with a SINGLE function in them. Why do they put a SINGLE function into class?

I use classes just to make things more clear, but about those who put a SINGLE function into class? Is there any reason for it?

I see no difference between these:

<?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); 

and

<?php 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); 

My thought was that $resource is the main reason, because it's private:

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); 

and therefore isn't accessible to the global scope. But why isn't a simple function used in this case?

6
  • I know that's only avaible in my lass, it doesn't matter right now. But, that's the reason why it's class, right? Because $resource is hidden from outer space Commented Jun 20, 2011 at 21:16
  • Where does $resource come from, genesis? It's passed to imagecopyresampled, imagesx, and imagesy before it's ever defined. Commented Jun 20, 2011 at 21:43
  • 1
    the difference in EDIT 2 is this: the class Image is extendible. As a class/object, an Image may have properties/attributes like a width and a height. Maybe the Image is the base for different types of Images like JPEGImage or GIFImage or PNGImage, whose methods like resize or reflect or scale, etc are all treated differently and respective to its type. but maybe they are the same in some ways but different in others. the bottom example is simply a function called resize that does something a single way and makes assumptions about image. Commented Jun 20, 2011 at 21:43
  • added resource. @John: nothing? So finally: is there any serious reason to do it in class? Commented Jun 20, 2011 at 21:45
  • @genesis: $resource is still not defined in function resize before it's passed to other functions. Commented Jun 20, 2011 at 22:33

10 Answers 10

28

Classes are not just "function containers", they are there to represent an object, an entity. They are supposed to encapsulate the data required for the given entity with methods that work for it.

Sometimes there might be a class of object that only needs one method defined for it, but nevertheless it only belongs to that class of object.

Sign up to request clarification or add additional context in comments.

7 Comments

sorry but this is little bit unclear for me. Some example why someone would need to "ecapsulate" required data to class?
+1 If I want to polymorphically ->foo() some objects somewhere, I don't give a damn that some of the objects may not have any other methods. Neither will I avoid polymorphism in a place where it would be useful just to avoid class bodies that seem too short.
Any variable represents an object. But you can not add methods to scalar "instances". Just a reminder.
@hakre: In what language? Not all variables are objects in PHP.
@Orbling: see: en.wikipedia.org/wiki/Object_%28computer_science%29 - PHP is not per se OO, so I like the reminder to the more broad picture.
|
9

I mostly do embedded programming, and seldom use classes. But a single function class could possibly be used to -

  • inherited later
  • enforce integrity of the data structure that is private to the class (encapsulation).
  • may be used to maintain the homogeneity of the code.

Comments

8

Why do some functions only have one line of code in them? Because it's all that's needed. Now you can call the function rather than repeating the single line of code everywhere. If that line of code needs to be tweaked, it only has to happen in one place. That's taking advantage of procedural encapsulation.

The same goes for your brief class. You can now take advantage of all that classes can do, especially inheritance and polymorphism, say SVGImage extends Image and override method resize.

There is no minimum number of lines required to fulfill necessary functionality.

3 Comments

With only one class, there can be used "polymorphism" ??
Just an example of what OOP can do, genesis. Your application may grow to the point that your class becomes a parent class.
"ok, but if it wouldn't..?" - if this could be precisely answered for a software, then there are many things which would loose meaning. This unpredictability is the one which requires many things to be done, and one among them could be having a class with a single method.
8

2011 Answer

This is actually a good question, and I've seen some good answers here. I actually really had to think about this for a bit.

I'd like to add something that I haven't seen in any of the other answers here, even if I don't get any votes, so that future readers can benefit.

Let's take your examples. (I've edited them so that they are functionally identical - they are slightly changed from what you had above.)

The class version:

<?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); 

And the function version: <?php

 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"); 

In practice, these are functionally identical. The main difference is simply the OOP paradigm vs. the procedural paradigm; in OOP, you define a function within a class (this is called a method) that acts upon a member variable, whereas in a procedural program you pass that variable to a function defined in the global scope.

So then, what's the benefit of wrapping a function in a class instead of making it global, since the function still does the same thing?

The main reason you'd want to do this in PHP (and many other languages that I can think of) is scope. @Headspin mentioned this briefly. Defining a resize function in the global scope is all well and good...until you need another function with the same name. What happens?

Generally, you run into one of these solutions:

  1. (The good.) Your language supports function overloading, so you don't worry about it as long as your arguments are different.
  2. (The bad.) Your language doesn't support function overloading (or your arguments have to be identical) and so you resort to detailed naming (like resize_image, resize_container), etc.
  3. (Still bad.) You begin to use namespaces to separate your global functions.
  4. (The ugly.) Your function accepts anything as an argument and becomes a hot, bloated mess of if/then statements or switch/case blocks for each variable type that it will handle.

My main reason to encapsulate a function in PHP would be to avoid naming conflicts, making the code more intuitive and easier to understand. I could have a resize method in my Image class, and have one in my Container class, and maybe another one in a test class or something, and none of them would conflict with each other. Reading the code, I know that Image->resize() calls the method within the Image class and nothing else.

Not having name conflicts opens up some more possibilities, such as iterating over a group of objects that share a common method name. (This is where interfaces come into play; read about them.) There's a lot of cool stuff you can do.

I guess that's it - I hope that helps. Below is the TL;DR version.

Encapsulating a single function in a class prevents naming conflicts for similar functions, without resorting to namespaces, function overloading, or function renaming. As such, if you have one function that performs a generic task, it may be best to create a class for each variable type that the function handles and convert the function to a class method.

2020 Edit:

I wrote this nine years ago when I was much more into OOP paradigms. The answer isn't necessarily wrong, but I've come to realize that the "stick everything in a class" methodology is a side effect of classic object-oriented, class-based programming that can't support other models. I don't really mess with PHP anymore, so I'm going to write this from a generic programming standpoint.

For current readers - organize your functions. Use file strategies, modules, namespaces - whatever it takes. This is good practice. However, functions don't have to be class methods, and in this day and age I would actually argue that they shouldn't be; functions should be just functions, taking input and creating output with minimal side effects. Modern languages and paradigms have a lot of benefits - one main benefit is that "classes" are no longer necessarily conflated with "namespaces/modules", so you don't need to encapsulate a function in a class (with all the overhead and annoyances that come with that) just for organizational purposes. Benefits of using standalone functions include:

  • Standalone functions often can be used in multiparadigm ways - they can be used like class methods (since methods are just functions with a specific parameter binding), or they can be used in a functional way.
  • They can more easily be treated as first-class objects and avoid being pinned to a particular implementation.
  • They can use generics when possible to avoid repetition when a concept is generic and interfaces are well-defined.
  • They can be easily used with interfaces and contracts, depending on the language.
  • They are easier to test in isolation without mocks (which is a pitfall of OOP) and they are self-scoping (they don't have to be, but it's not bad practice to avoid side effects outside of the function unless absolutely necessary).

So basically, in 2020, I would not follow my earlier advice:

~~Encapsulating a single function in a class prevents naming conflicts for similar functions, without resorting to namespaces, function overloading, or function renaming. As such, if you have one function that performs a generic task, it may be best to create a class for each variable type that the function handles and convert the function to a class method.~~

Use modern tools and paradigms when possible. Prefer simple functions. If your languages offers alternatives for code organization to classes, use those and only use classes and methods for their true design purpose.

1 Comment

This answer is brilliant and was much more helpful than the accepted answer.
6

Instead of looking at a class as a collection of functions, think in terms of the class' role. Classes should generally know about what it contains and nothing about what it doesn't, and should only capture a single key abstraction. There can be cases where it makes sense.

Comments

4

I think the best reason to 'classify' anything, even small functions like the one you have there is simply for scalability. Maybe down the line you will want to add additional functionality to function which allows it to decipher image formats or what have you. Encapsulating this into a class would be the way to go for easy scalability. Also, it is always a good idea to have control over the scope of your functions and variables, and is usually not a great idea to keep them on the global scope. This is just good practice as it can cause troubles when your seemingly small project all of a suddenly turns into a large one.

Comments

3

First, in your function you cannot use this function for any other image file. This could be remedied with an extra argument however so I will skip this one.

Second, you can extend the class, and add more methods that all affect your set image resource.

Third, you can use a class autoloader with classes therefore only loading the file that contains the class if the class is actually used, instead of loading it every time the script runs or worrying about where to place include and require statements.

Fourth, and probably most important, you can use this class and any other class as an input for another class allowing you to change the functionality of that class simply by choosing which class to insert. As an example...

class ImageProcessingClass { protected $imageResource; protected $processors = array(); public function setImageResource($image_resource) { $this->imageResource = $image_resource; } public function addProcessor(Processor $processor) { $this->processors[] = $processor; } public function processImage() { foreach ($this->processors as $processor) { $this->imageResource = $processor->process($this->imageResource); } } } interface Processor { public function process($image); } class ProcessorResize implements Processor { public function process($image) { // resize image code here... return $image; } } class ProcessorFilter implements Processor { public function process($image) { // filter image code here... return $image; } } 

and the code that uses this

$image_processor = new ImageProcessor(); $image_processor->setImageResource($image_resource); $image_processor->addProcessor(new ProcessorResize()); $image_processor->addProcessor(new ProcessorFilter()); $image_resource = $image_processor->processImage(); 

this pattern would allow you to add Processor classes in many different combinations with different outcomes in the way that it affects the image. reusable code with many different possibilities though composition of classes.

Comments

1
+50

According To Modern Development in php, It is very Flexible or Robust to use Classes.

and Exposing all the functions globally is not a good idea. so, to avoid this we can use static function in class and calling it with class name.

eg:

Class A{ public static function xyz(){ //function handling } } A::xyz(); 

Comments

0

Apart from some of the great reasons given above about why to wrap even a single method into a class here is one more:

In C++, if You want to offer an interface for even just one method, you have to define a call for that.

e.g.

class CallBackClient { public: // A callback function. virtual s32 callback( int param1, int param2 ) = 0; }; 

Every Client that wants to provide their own implementation of callback needs to extend to this class.

Java offers a direct notation for an interface which can be "implemented".

2 Comments

I don't really see any difference between a class with only pure virtual methods in C++ and an interface in Java. I'm not quite sure I understand your point as a result.
The original quesion asks for reasons where to have a class with ONLY one method. I am provide an exmaple where you have to wrap around the method into a class.
0

Classes is like collection of objects, an entity. Class encapsulate the data required for the given entity with methods that work for it And an Object have some properties(attribute) and method(Function) that define into its type of class generally method are used to change the attribute values.such that Each function Need Class for Its existence.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.