72

I am currently working on a software project that performs compression and indexing on video surveillance footage. The compression works by splitting background and foreground objects, then saving the background as a static image, and the foreground as a sprite.

Recently, I have embarked on reviewing some of the classes that I have designed for the project.

I noticed that there are many classes that only have a single public method. Some of these classes are:

  • VideoCompressor (with a compress method that takes in an input video of type RawVideo and returns an output video of type CompressedVideo).
  • VideoSplitter (with a split method that takes in an input video of type RawVideo and returns a vector of 2 output videos, each of type RawVideo).
  • VideoIndexer (with an index method that takes in an input video of type RawVideo and returns a video index of type VideoIndex).

I find myself instantiating each class just to make calls like VideoCompressor.compress(...), VideoSplitter.split(...), VideoIndexer.index(...).

On the surface, I do think the class names are sufficiently descriptive of their intended function, and they are actually nouns. Correspondingly, their methods are also verbs.

Is this actually a problem?

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
Yong Jie Wong
  • 831
  • 1
  • 6
  • 5
  • 14
    It depends on the language. In a multi-paradigm language like C++ or Python, these classes have no business existing: Their "methods" should be free functions. –  Jan 29 '14 at 08:35
  • 3
    @delnan: even in C++, you typically use classes for creating modules, even if you don't need the full "OO capabilities". Indeed, there is the alternative of using namespaces instead for grouping "free functions" together to a module, but I don't see any advantages in that. – Doc Brown Jan 29 '14 at 11:52
  • 5
    @DocBrown: C++ has namespaces for that. In fact in modern C++ you often use free functions for methods, because they can be (statically) overloaded for all arguments while methods can only be overloaded for the invocant. – Jan Hudec Jan 29 '14 at 11:58
  • @DocBrown Do we? I'm certain some people do, but that doesn't make it good style. Namespaces are conceptually the right tool, needing less typing and don't allow nonsense like `MyMathModule what_does_this_even_mean;`. I know only one reason to use classes, and it's rarely applicable: Grouping template arguments to reduce typing (namespaces can't be passed to templates). In any case, this argument falls flat for a single-method class; you typically wouldn't create a module for this single function but rather put it where you'd put that module (i.e. `foo::bar` instead of `foo::bar::bar`). –  Jan 29 '14 at 12:01
  • @JanHudec Nitpick: Methods can be overloaded for all arguments too. You may be thinking of dynamic dispatch/subtype polymorphism, but that's not possible *at all* for free functions. http://ideone.com/0Mpr3j –  Jan 29 '14 at 12:03
  • @delnan: Of course they can. Obviously I chose wrong terminology. It's more like some functions make sense for specific combinations of arguments rather than being associated with one or the other. See also [gotw #84](http://www.gotw.ca/gotw/084.htm) about functions not really tied to particular class. – Jan Hudec Jan 29 '14 at 12:07
  • @delnan: I guess this is not the core of the OP's question - the same question arises with modules using namespaces, having just one "external" method. – Doc Brown Jan 29 '14 at 12:09
  • 2
    @DocBrown: It is a very core of the question. Modules using namespaces having just one "external" method are perfectly fine when the function is sufficiently complex. Because namespaces don't pretend to represent anything and don't pretend to be object-oriented. Classes do, but classes like this are really just namespaces. Of course in Java you can't have a function, so this is the result. Shame on Java. – Jan Hudec Jan 29 '14 at 12:11
  • 2
    Related (almost a duplicate): http://programmers.stackexchange.com/q/175070/33843 – Heinzi Jan 29 '14 at 13:01
  • @JanHudec: the way I understand the question is "does proper OO design mean to put the video compressing/indexing/splitting" code (which is potentially huge and complex) all into one `Video` class? I think we both agree that this is obviously not the case here. – Doc Brown Jan 29 '14 at 13:03
  • A humoristic description of the "realm of nouns": http://steve-yegge.blogspot.co.il/2006/03/execution-in-kingdom-of-nouns.html – Erel Segal-Halevi Jan 29 '14 at 13:39
  • 1
    If you don't want to instantiate a class, just create classes that don't require it. – JeffO Jan 29 '14 at 13:55
  • @DocBrown I read it more as a "does proper OO design mean we should create functional classes" - for beginners, I would advocate not making classes that are just collections of functions (obviously in the real world such things are ok once you know why you'd make such things)(because you end up with the "better C" design pattern then). The OP does say he instantiates these classes just to call the function, and that's not "proper" OO design. Some languages would prefer namespace or modules, some would prefer a static class. These are practical ways to mange the code, but are not OO. – gbjbaanb Jan 30 '14 at 09:06
  • @gbjbaanb: do we know that the module keeps to be pure functional in the next version? In C++ it seems to make more sense to use a namespace instead of a class at a first glance - because using a class seems to be more effort there (you have to write that boilerplate `Classname::` again and again into your cpp files). In Java or C# using a "class" for grouping functions is not more effort than using a namespace in C++. But with a class, you are ready when your video compressor "version 1.1" needs some state (like compression parameters etc.), is used in multithreaded environment, etc. – Doc Brown Jan 30 '14 at 10:50
  • ... so the YAGNI argument by @JanHudec down below in a comment may apply somewhat in C++ or Python, but not for Java or C#. So I have to admit delnan was right in his first comment: the right decision is a little bit language specific (though I guess even in C++ or Python it pays to some degree to have "version 1.1" in focus when designing version 1.0 of a module, an I guess for a real-world VideoCompressor module I would always prefer a class over a namespace even in C++). – Doc Brown Jan 30 '14 at 10:55
  • 1
    @DocBrown class over namespace... so would I. But, if anyone asks "what should I do" I have to tell them to think about what OO is fundamentally about to avoid letting the 'easy option' become a bad habit. Any static class functions is really an anti-pattern IMHO, but I don't think we have many practical alternatives sometimes. Got some interesting discussion going for such a simple question though, cheers! – gbjbaanb Jan 30 '14 at 13:20
  • @delnan I don't agree that these methods should be free functions. What if some of these methods are similar, call other smaller methods, or you one day want to extend one to behave slightly differently? Objects make that kind of polymorphism so much easier, and those benefits apply just as much to single method cases as more complex ones. It's just unfortunate we have to use a clunkier calling convention. – AndyHasIt Dec 04 '14 at 12:48

9 Answers9

103

No, this is not a problem, quite the opposite. It is a sign of modularity and clear responsibility of the class. The lean interface is easy to grasp from the viewpoint of a user of that class, and it will encourage loose coupling. This has many advantages but almost no drawbacks. I wish more components would be designed that way!

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • 6
    This is the correct answer, and I have upvoted it, but you could make it better by explaining some of the advantages. I think what the OP's instinct is telling him is a problem is something else ... that is, that VideoCompressor is really an interface. Mp4VideoCompressor is a class and should be interchangable with another VideoCompressor without copying the code for a VideoSplitter to a new class. – pdr Jan 29 '14 at 17:31
  • I wished I could mark more than 1 answer as accepted - all of the comments and responses were really really insightful and I learnt a great deal from the debate. Thank you guys! – Yong Jie Wong Jan 29 '14 at 18:40
  • Wish I could upvote 100 times. – Fred Thomsen Jan 31 '14 at 03:19
  • 2
    Sorry but you're wrong. A class with a single method should just be a standalone function. – Miles Rout Feb 04 '14 at 23:20
  • 4
    @MilesRout: your comment shows you misunderstood the question - the OP wrote about a class with one public method, not with one method (and he indeed meant a class with multiple private methods, as he told us here in one comment). – Doc Brown Feb 05 '14 at 07:22
  • up vote. All I can say is BAM! Right on! All my experience says this is so. I say "few public methods" is a "Good OO code smell." It hits on so many good OO cylinders: minimize coupling, maximize cohesion. Testable. Single Responsibility. Immutable-ish, at least the client is not setting properties. Open/Closed - at its best. – radarbob Oct 02 '15 at 23:10
  • 3
    ["A class with a single method should just be a standalone function. "](http://programmers.stackexchange.com/users/114495/miles-rout) A gross assumption about what that method is. I have a class with one public method. BEHIND IT are multiple methods in that class plus 5 other classes that have absolutely no idea of the client. **Excellent application of SRP will yield clean, simple interface of the layered class structure, with that simplicity manifesting all the way to the top.** – radarbob Oct 02 '15 at 23:24
  • Its irrelevant if there are multiple private functions or not. The "classes" seem to have just behavior and no state. Nothing wrong with that, but its not OO. Static classes would be the best option if the language allows it. – Andy Oct 18 '15 at 19:20
  • 2
    @Andy: the question was "is this a problem" and not "does this conform to a specific OO definition". Moreover, there is absolutely no sign in the question the OP means classes with no state. – Doc Brown Oct 19 '15 at 04:15
  • The question is "is this a problem [when doing an OO design]." Because, you know, the question is tagged OO. There's no evidence the objects have any state either, and given _I find myself instantiating each class **just to make calls** like VideoCompressor.compress(...)_ I think it's reasonable to lean toward the "no state" assumption. – Andy Oct 19 '15 at 14:24
30

It is no longer object oriented. Because those classes don't represent anything, they are just vessels for the functions.

That does not mean it's wrong. If the functionality is sufficiently complex or when it's generic (i.e. the arguments are interfaces, not concrete final types), it makes sense to put that functionality in separate module.

From there it depends on your language. If the language has free functions, they should be modules exporting functions. Why pretend it's a class when it isn't. If the language does not have free functions like e.g. Java, then you create classes with single public method. Well, that just shows the limits of object oriented design. Sometimes functional is simply better match.

There is one case when you may need a class with single public method because it has to implement interface with single public method. Be it for observer pattern or dependency injection or whatever. Here it again depends on the language. In languages that have first class functors (C++ (std::function or template parameter), C# (delegate), Python, Perl, Ruby (proc), Lisp, Haskell, ...) these patterns use function types and don't need classes. Java does not (yet, will in version 8) have function types, so you use single method interfaces and corresponding single method classes.

Of course I am not advocating writing single huge function. It should have private subroutines, but they can be private to the implementation file (file-level static or anonymous namespace in C++) or in a private helper class that is only instantiated inside the public function (To store data or not?).

Jan Hudec
  • 18,250
  • 1
  • 39
  • 62
  • I agree with your answer except your first paragraph. This is IMHO very narrow viewpoint about what the term "object orientation" means. – Doc Brown Jan 29 '14 at 12:36
  • 15
    "Why pretend it's a class when it isn't." Having an object instead of a free function allows state and subtyping. That could prove valuable in a world where requirements change. Sooner or later there's a need to play with video compression settings or to provide alternate compression algorithms. Before that the word "class" simply tells us that this function belongs to an easily extensible and interchangeable software module with a clear responsibility. Isn't that what OO really aims at? – COME FROM Jan 29 '14 at 14:05
  • 1
    Well, if it only has one public method (and kind of implying no protected ones), it can't really be extended. Of course packing compression parameters might make sense in which case it becomes function object (some languages have separate support for those, some don't). – Jan Hudec Jan 29 '14 at 14:11
  • @JanHudec: By extending I mean adding state and functionality to the class. That means more members and probably more visible methods. I certainly agree that there are situations where free functions are handy and classes are quite awkward, but this doesn't seem to be the case here. – COME FROM Jan 29 '14 at 14:36
  • @COMEFROM: If you extend public interface you are going to have to modify the callers anyway, therefore YAGNI. – Jan Hudec Jan 29 '14 at 14:46
  • 3
    This is a fundamental connection between objects and functions: a function is isomorphic to an object with a single method and no fields. A closure is isomorphic to an object with a single method and some fields. A selector function returning one of several functions which all close over the same set of variables is isomorphic to an object. (In fact, this is how objects are encoded in JavaScript, except you use a dictionary data structure instead of a selector function.) – Jörg W Mittag Jan 29 '14 at 16:19
  • 4
    "It is no longer object oriented. Because those classes don't represent anything, they are just vessels for the functions." - This is wrong. I would argue this approach is MORE object-oriented. OO does not mean it represents a real-world object. A large amount of programming deals with abstract concepts, but does this mean you cannot apply an OO approach to solve it? Definitely not. It's more about modularity and abstraction. Each object has a single responsibility. This makes it easy to wrap your head around the program and make changes. Not enough space to list the numerous benefits of OOP. – Despertar Jan 30 '14 at 00:03
  • @JanHudec: Extending an interface (adding more visible methods) does not affect existing clients. – COME FROM Jan 30 '14 at 09:13
  • 2
    @COMEFROM: State in a class like this sounds like a horrible idea, 99.9% of the time, and can anyway be achieved with a function in any language which supports closures. You don't *need* subtyping in a scenario like this, because your function type is simply (T -> K) and would be fulfilled by any function which maps a T to a K, exactly the same functionality you would gain from a subtype relationship on an interface of `K apply(T)`. – Phoshi Jan 30 '14 at 10:05
  • @Phoshi: Yes, I agree. There's no need for subtyping or state. There's just a need for some sort of video manipulation which doesn't really require a single object. However, yjwong has chosen a certain object oriented approach to meet that need, and that approach opens the possibility to use subtyping and state and all sorts of other object oriented tricks if needed later on. I still fail to how using objects to provide the needed functionality is "not object oriented". – COME FROM Jan 30 '14 at 16:44
  • @COMEFROM: My point was that any function from T->K is of the type, so there is no need for a "subtype" relationship there as you achieve exactly the same thing without it. With closures, you can have state if you really really need to. Neither of the things you point out as a future potential advantage to an object oriented approach are unique to object orientation or even unavailable with the simple functional approach suggested. – Phoshi Jan 30 '14 at 16:53
  • 2
    @Phoshi: Yes, I understand. I never claimed that a functional approach wouldn't work as well. However, that is clearly not the topic. A video compressor or a video transmogrifier or whatever is still a perfectly valid candidate for an object. – COME FROM Jan 30 '14 at 20:29
  • @Despertar If you read Jan's answer you would see that modularity and abstraction are addressed specifically, by the suggestion of writing a *module*. In fact, modules like those in ML provide more abstraction and modularity than OOP. Unfortunately many languages don't have module systems, and have to make do with poor approximations like classes and namespaces. – Warbo Aug 12 '14 at 15:51
  • down vote. "It is no longer object oriented." Categorically wrong, I say. So arbitrarily exposing internal state for the sake of having more than one public method is object oriented? For what it's worth the best classes I've written have only a public constructor; adding a single line of code in the client thus enabling all new functionality. Can't do that often but the fewer public members, the higher my internal OO-buzz-trippy meter goes. – radarbob Oct 02 '15 at 23:01
14

There may be reasons to extract a given method into a dedicated class. One of those reasons is to allow Dependency Injection.

Imagine you have a class called VideoExporter which, eventually, should be able to compress a video. A clean way would be to have an interface:

interface IVideoCompressor
{
    Stream compress(Video video);
}

which would be implemented like this:

class MpegVideoCompressor : IVideoCompressor
{
    // ...
}

class FlashVideoCompressor : IVideoCompressor
{
    // ...
}

and used like this:

class VideoExporter
{
    // ...
    void export(Destination destination, IVideoCompressor compressor)
    {
        // ...
        destination = compressor(this.source);
        // ...
    }
    // ...
}

A bad alternative would be to have a VideoExporter which has plenty of public methods and does all the job, including the compressing. It would quickly become a maintenance nightmare, making it hard to add support for other video formats.

Arseni Mourzenko
  • 134,780
  • 31
  • 343
  • 513
  • 2
    Your answer does not distinguish between public and private methods. It could be understood as a recommendation for putting all code of a class just one method, but I guess that is not what you meant? – Doc Brown Jan 29 '14 at 08:31
  • 2
    @DocBrown: Private methods are not relevant to this question. They can be put on internal helper class or whatever. – Jan Hudec Jan 29 '14 at 12:16
  • 2
    @JanHudec: currently the text is "A bad alternative would be to have a VideoExporter which has plenty of methods" - but it should be "A bad alternative would be to have a VideoExporter which has plenty of *public* methods". – Doc Brown Jan 29 '14 at 12:20
  • @DocBrown: Agree here. – Jan Hudec Jan 29 '14 at 12:21
  • 2
    @DocBrown: thank you for your remarks. I edited my answer. Originally, I thought that is was assumed that the question (and so my answer) is about public methods only. It appears that it's not as obvious. – Arseni Mourzenko Jan 29 '14 at 13:04
9

This is a sign that you want to pass functions as arguments to other functions. I'm guessing your language (Java?) doesn't support it; if that's the case, it's not so much a failing in your design as it is a shortcoming in your language of choice. This is one of the biggest problems with languages that insist that everything must be a class.

If you aren't actually passing these faux-functions around then you just want a free/static function.

Doval
  • 15,347
  • 3
  • 43
  • 58
  • 1
    Since Java 8, you have lambdas, so you pretty much can pass functions. – Silviu Burcea Jan 30 '14 at 08:49
  • Fair point, but that won't be officially released for a little while longer, and some workplaces are slow to move to newer versions. – Doval Jan 30 '14 at 17:43
  • Release date is in March. Also, EAP builds were very popular for JDK 8 :) – Silviu Burcea Jan 30 '14 at 18:45
  • Although, as Java 8 lambdas are simply a shorthand way for defining objects with only one public method, other than saving a little bit of boilerplate code, they make no difference at all here. – Jules Feb 19 '16 at 21:32
  • This is completely wrong. Having one method in a class is actually really good design. actually. Because it adheres to the single responsibility paradigm. It also enables you to have 3 other things. Immutability through a constructor, member variables spanning over the public and all private methods. Sounds like perfect encapsulation to me. These things are not a shortcoming, it is actually brilliant design. – David Feb 06 '21 at 13:46
8

I know I'm late to the party but as every one seems to have missed to point this out:

This is a well known design pattern called: Strategy Pattern.

Strategy pattern is used when there are several possible strategies to solve a sub-problem. Typically you define an interface that enforces a contract on all implementations and then use some form of Dependency Injection to provide the concrete strategy for you.

For example in this case you could have interface VideoCompressor and then have several alternative implementations for example class H264Compressor implements VideoCompressor and class XVidCompressor implements VideoCompressor. It is not clear from OP that there is an interface involved, even if there is not, it may simply be that the original author left the door open to implement strategy pattern if needed. Which in and of itself is good design too.

The problem that OP constantly finds herself instantiating the classes to call a method is a problem with her not using dependency injection and the strategy pattern correctly. Instead of instantiating it where you need it, the containing class should have a member with the strategy object. And this member should be injected, for example in the constructor.

In many cases the strategy pattern results in interface classes (as you are showing) with just a single doStuff(...) method.

Emily L.
  • 332
  • 2
  • 9
  • What you are saying is that the OP should ditch the `.method()` call and just add it to constructor instead, making it a class without any public method (only the constructor of course)? – Vinícius Ferrão Mar 01 '22 at 00:36
2

It is a problem - you are working from the functional aspect of the design, rather than the data. What you actually have are 3 standalone functions that have been OO-ified.

For example, you have a VideoCompressor class. Why are you working with a class designed to compress video - why do you not have a Video class with methods on it to compress the (video) data that each object of this type contains?

When designing OO systems, its best to create classes that represent objects, rather than classes that represent activities that you can apply. In the old days, classes were called types - OO was a way to extend a language with support for new data types. If you think of OO like this, you get a better way of designing your classes.

EDIT:

let me try to explain myself a little better, imagine a string class that has a concat method. You can implement such a thing where each object instantiated from the class contains the string data, so you can say

string mystring("Hello"); 
mystring.concat("World");

but the OP wants it to work like this:

string mystring();
string result = mystring.concat("Hello", "World");

now there are places where a class can be used to hold a collection of related functions, but that is not OO, its a handy way of using the OO features of a language to help manage your codebase better, but it is no way any kind of "OO Design". The object in such cases is totally artificial, simply used like this because the language does not offer anything better to manage this kind of problem. eg. In languages such as C# you would use a static class to provide this functionality - it reuses the class mechanism, but you no longer need to instantiate a object just to call the methods on it. You do end up with methods like string.IsNullOrEmpty(mystring) which I think is poor compared to mystring.isNullOrEmpty().

So, if anyone is asking "how do I design my classes", I recommend thinking of the data the class will contain rather than the functions it contains. If you go for the "a class is a bunch of methods", then you end up writing "better C" style code. (which isn't necessarily a bad thing if you are improving C code) but it is not going to give you the best OO designed program.

gbjbaanb
  • 48,354
  • 6
  • 102
  • 172
  • 9
    -1, I totally disagree. Beginners OO design works only with data objects like a `Video` and tends to overblow such classes with functionality, which often ends in messy code with >10K LOC per class. Advanced OO design breaks functionality down to smaller units like a `VideoCompressor` (and lets a `Video` class just be a data class or a facade for the `VideoCompressor`). – Doc Brown Jan 29 '14 at 11:44
  • 5
    @DocBrown: At which point it however is no longer an object oriented design, because the `VideoCompressor` does not represent an _object_. There's nothing wrong with that, just shows the limit of object oriented design. – Jan Hudec Jan 29 '14 at 11:56
  • 3
    ah but beginners OO where 1 function gets turned into a class isn't really OO at all, and only encourages the massive decoupling that ends up in a thousand files of classes no-one can maintain. I think its best to think of a class as a "data-wrapper" not a "functionality wrapper", that'll give a beginner a better understanding of how to think about OO programs. – gbjbaanb Jan 29 '14 at 11:57
  • @gbjbaanb: I guess you misunderstood this: a VideoCompressor will typically consist of several methods, but only one *public* method. – Doc Brown Jan 29 '14 at 12:03
  • @DocBrown who's to say there *are* any other methods, he says 1 public method, but that's all there could be. Still, I think data-driven OO design is the way OO should be done. – gbjbaanb Jan 29 '14 at 12:06
  • 4
    @DocBrown actually accurately highlighted my concern; I indeed do have a `Video` class, but the compression methodology is in no way trivial, so I would actually break down the `compress` method into multiple other private methods. This is part of the reason of my question, after having read [Don't create verb classes](http://c2.com/cgi/wiki?DontCreateVerbClasses) – Yong Jie Wong Jan 29 '14 at 12:08
  • @gbjbaanb: There are other methods. But they are not relevant, because you can handle them like [this](http://programmers.stackexchange.com/questions/225711/to-store-data-or-not/225717#225717). – Jan Hudec Jan 29 '14 at 12:15
  • @JanHudec: OO is about creating abstractions - and some people have mental problems with using classes for other abstractions than data. But that does not mean it would not be any OO design - it is just not *basic* OO design any more, but more advanced OO design. – Doc Brown Jan 29 '14 at 12:17
  • @yjwong: read the last paragraph of that "Don't create verb classes" article you linked to, IMHO this is the case to apply here. – Doc Brown Jan 29 '14 at 12:18
  • 1
    @JanHudec why does a `VideoCompressor` not represent an object? You mean, a physical object? – Konrad Morawski Jan 29 '14 at 12:41
  • @KonradMorawski: I can imagine cases where it does, but then it probably does have more than one method or at least has a constructor with bunch of parameters. But a class with just single method (and trivial constructor) does not have any content and what does such instance represent? – Jan Hudec Jan 29 '14 at 13:04
  • @JanHudec it would represent an operation. If it's at odds with OOP, then so is factory pattern. A simple factory class can only have one method (`Create`). Why not?? And what would it represent? A class capable of creating objects of an appropriate type (based on some input parameter). – Konrad Morawski Jan 29 '14 at 13:09
  • 1
    @KonradMorawski: If a factory is polymorphic (e.g. you dependecy-inject it) and/or stateful, then it's using object oriented techniques. But if it's just a container for a method, then there is nothing object oriented on it. That is not a problem, the fact that object oriented idioms are useful does not mean every idiom has to be object oriented, but in languages that don't require class for everything you should not use it if it does not add anything. – Jan Hudec Jan 29 '14 at 13:16
  • 2
    I think it might be ok to have a `Video` class, but it would be _composed_ of a `VideoCompressor`, a `VideoSplitter`, and other related classes, which should, in good OO form, be highly cohesive individual classes. – Eric King Jan 29 '14 at 15:20
2
public interface IVideoProcessor
{
   void Split();

   void Compress();

   void Index();
}

What you've got is modular and that's good, but if you were to group these responsibilities into IVideoProcessor, that would probably make more sense from DDD point of view.

On the other hand, if splitting, compressing and indexing wasn't related in any way, than I'd keep them as separate components.

CodeART
  • 3,992
  • 1
  • 20
  • 23
  • As the reason for each of these functions needing to change is somewhat different, I'd argue that putting them together like this violates SRP. – Jules Feb 19 '16 at 21:35
0

The ISP (interface segregation principle) says that no client should be forced to depend on methods it does not use. The benefits are multiple and clear. Your approach totally respects the ISP, and that's good.

A different approach also respecting the ISP is, for example, create an interface per each method (or set of methods with a high cohesion) and then have a single class implementing all those interfaces. Whether this is or not a better solution depends on the scenario. The benefit of this is, when using dependency injection, you could have a client with diferent collaborators (one per each interface) but in the end all the collaborators will point to the same object instance.

By the way, you said

I find myself instantiating each class

, these classes seem to be services (and thus stateless). Have you thought about making them singletons?

diegomtassis
  • 195
  • 1
  • 7
  • 1
    Singletons are, usually, antipattern. See [Singletons: Solving problems you didn't know you didn't have since 1995](http://jalf.dk/blog/2010/03/singletons-solving-problems-you-didnt-know-you-never-had-since-1995/). – Jan Hudec Jan 29 '14 at 14:48
  • 3
    For the rest while interface separation principle is a good pattern, this question is about the implementations, not the interfaces, so I'm not sure it's relevant. – Jan Hudec Jan 29 '14 at 14:50
  • 3
    I'm not gonna enter to discuss whether the singleton is a pattern or an antipattern. I suggested a _possible_ solution (it has even a name) to its problem, it's up to him to decide whether it fits or not. – diegomtassis Jan 29 '14 at 15:48
  • Regarding whether the ISP is relevant or not, well, the subject of the question is "are classes with only a single method a problem?", the opposite of that is a class with many methods, which becomes a problem the moment you make a client depend directly on it... exactly the Robert Martin's xerox example it took him to formulate the ISP. – diegomtassis Jan 29 '14 at 15:57
0

Yes, there is a problem. But not severe. I mean you can structure your code like this and nothing bad will happen, it is maintainable. But there are some weaknesses to that kind of structuring. For example consider if representation of your video (in your case it is grouped in RawVideo class) changes, you will need to update all your operation classes. Or consider that you might have multiple representations of video that vary in runtime. Then you will have to match representation to particular "operation" class. Also subjectively it is annoying to drag around a dependency for each operation you want to do on smth. and to update list of dependencies passed around every time you decide that operation is no longer needed or you need new operation.

Also that's actually a violation of SRP. Some people just treat SRP as a guide for splitting responsibilities (and take it to far by treating each operation a distinct responsibility) but they forget that SRP is also a guide to grouping responsibilities. And according to SRP responsibilities that change for same reason should be grouped together so that if change happens it is localized to as little classes/modules as possible. As for big classes it is not a problem having multiple algorithms in same class as long as those algorithms are related (i.e. share some knowledge that should not be known outside of that class). The problem are big classes that have algorithms that are not related in any way and change/vary for different reasons.