7

I just want to understand the purpose that static method serves and what are the desirable situation where i can create static methods except some would say that static methods are used for creating helper.

Consider i have 1 website that will be used in my company only like Human resource management system like websites.

Now after Admin login in to the system admin will see the list of employees.so the method is simple which does nothing more than fetching all details of employees from employee table and will display them on the web site and this method will be define in business access layer like this in .net:

 public class EmployeeBal
    {
        public List<Employee> GetAllEmployees()
        {
                 return Select * from Employee
        }
     }

This is how i would call this method from my application.For Eg(.aspx page or mvc controller etc....)

var employeeBal= new EmployeeBal();
employeeBal.GetAllEmployees();

So my question is should i create this method as static method or non static method??

Note:This is just an example of method and this method is in my business access layer.

Consider i have 1 ecommerce website where on the home page i am displaying some list of products and on visit of that website every users can see that list of products.

so my function would be same as above define in Business acess layer:

public class ProductBal
    {
        public List<Product> DisplayProductonHomePage()
        {
                 return Select * from Products
        }
     }

So my question would be same like whether to create this method as static method or non-static method and what will happen if more than 10 users at same time simultaneously access this website then what will be the behaviour/implications of this method???

Will this method will serve the purpose of this each user if we declare this method as static??

Can anybody answer this question with briefly explaining every scenario???

I Love Stackoverflow
  • 6,738
  • 20
  • 97
  • 216
  • 4
    How exactly do you define a "helper"? – Stefan Steinegger Mar 04 '16 at 09:05
  • @StefanSteinegger:If you have use mvc then Html.Textbox and some mathematical functions or you might have created helper for sending email etc.... – I Love Stackoverflow Mar 04 '16 at 09:12
  • 1
    I mean: there is no real definition for "helper". There are instance methods which get a `this` reference, there are static methods which do not get a `this` reference. This is the technical difference. Independent of what the method is doing and how "helping" it is. If you don't want your logic relaying to some `this` object, or just don't have one, it is static. – Stefan Steinegger Mar 04 '16 at 10:10
  • Static methods can help to reduce overload of garbage collection, you will not produce object each time that request received (less garbage quicker work) - good in overloaded systems. Create static method if you does not have any shared state if yes you would manage concurrency. – genichm Mar 07 '16 at 11:12
  • @genichm:I just dont understand this concept of state as Konrad Rudolph has mention alot about state in his answer and you have mention too.Can you please help me understand what is it? – I Love Stackoverflow Mar 08 '16 at 03:31
  • 1
    It is simply some global object that declared outside of your function but used in function for example list, dictionary, class. In case of site it even simpler because objects created per requests and not shared between requests. It mean that shared state can be only some static object (static list, class, dictionary). – genichm Mar 08 '16 at 13:54

7 Answers7

9

A static method makes sense when there’s no state to maintain. What do I mean by state? Well, consider the following: You have two distinct objects, a and b, which are both of type EmployeeBal. Is there ever a case in your program where a.GetAllEmployees() and b.GetAllEmployees() would yield different results?

If not, then why do the objects a and b exist at all? The whole point of having objects is to associate some distinct state with them. If two different objects can never refer to a different state, then they fulfil no purpose.

In fact, in this situation your EmployeeBal would be exactly equivalent to System.Math, and all its methods are “helper methods” (if that’s what you want to call them). In this case, forget about static methods for a minute: your whole class should be static (static class EmployeeBal), and it should not have any constructors; because the concept of an object of type EmployeeBal simply makes no sense. In fact, in other languages EmployeeBal wouldn’t be a class at all; instead, it would be something generally called a module: a unit that logically groups code. C# has no modules, and all code must reside within classes. Classes thus fulfil a dual purpose: they group code, and they generate objects.1

Now consider a less extreme case: EmployeeBal objects actually maintain state, and differ. Yet GetAllEmployees() will still yield the same result, regardless of which object calls the method.

In this case, EmployeeBal obviously cannot be a static class. But GetAllEmployees is still stateless, and thus doesn’t belong to objects of type EmployeeBal. And thus the method should be static.


1 This lack of distinction between two fundamentally distinct concepts (module and class) is actually quite annoying, and the main reason that C# behaves this way is because it was conceived to be similar to Java. It was a mistake in hindsight, but not a serious one.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • thanks for the answer but would you like to tell something about the scenarios which i have describe in my question? – I Love Stackoverflow Mar 07 '16 at 03:24
  • If we determine what is static and what isn't according to whether it maintains state then that breaks encapsulation. EmployeeBal shouldn't reveal whether it maintains state. Consumers should depend on its interface (soliD) not depend on an assumption about its internal implementation (whether it maintains state.) – Scott Hannen Mar 13 '16 at 23:20
  • Along the same lines, a class should not depend on EmployeeBal. It should depend on an abstraction. Making EmployeeBal static makes that impossible. As was mentioned in other posts, a static class makes sense for pure functions. GetAllEmployees is not a pure function. You can call the same function twice and get different results if you add or remove an employee or change any detail about any employee. – Scott Hannen Mar 13 '16 at 23:30
  • @ScottHannen Nonsense, that no more breaks encapsulation than having free functions in the majority of languages that don’t follow the nonsense of Java and C# that every code must be inside a class. And your argument for making non-pure functions non-static makes a lot of sense — but only if they carry their state. Which, as mentioned, is explicitly excluded here. Of course in reality you’d probably make `EmployeeBal` depend in some way on database state so it couldn’t be static. – Konrad Rudolph Mar 13 '16 at 23:42
  • It's not nonsense. If class A depends on static class B and then static class B must be modified to require state (it can no longer be static) then you must also modify class A to change the way it depends on B. If A has to change because internal implementation details of B have changed then A knows too much about B. I can't see dismissing SOLID principles without substantiation. Depend on abstractions. Not saying static classes are evil, but use them by informed, careful choice, not by default. If in doubt, err on the side of non-static. – Scott Hannen Mar 14 '16 at 02:17
  • @ScottHannen That’s the matter of things: if you modify the requirements, you break thing. It’s an illusion to think that you can have abstractions that are immutable to any changes: *every abstraction leaks*. So it’s a trade-off, and your rule demands that you incur ridiculous complexity on all free functions. “err on the side of non-static” is the equivalent of “err on the side of member functions instead of free functions” in languages such as C++ and functional languages, and that runs counter to well established principles, akin to SOLID (KISS, to name one). – Konrad Rudolph Mar 14 '16 at 10:01
  • It's not a change to requirements, it's a change to implementation. The whole point is that if the implementation of B changes we shouldn't have to modify classes that depend on it. That's why we have interfaces. That's why we have dependency inversion. We depend on abstractions, not implementations. I didn't invent it, but I can tell you it works. – Scott Hannen Mar 14 '16 at 13:44
  • @ScottHannen Nobody here is arguing against abstractions. All I’m telling you that no abstraction is absolute, all abstractions leak, and your naïve adherence to SOLID principles without considering trade-offs ignores the complexity you incur, and which in many cases vastly overweights the advantage gained from a stable interface. – Konrad Rudolph Mar 14 '16 at 14:06
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/106261/discussion-between-scott-hannen-and-konrad-rudolph). – Scott Hannen Mar 14 '16 at 15:53
4

Is there a reason why the method should be static? If not I'd always side with non-static. One big reason is being able to write unit tests. In order to write unit tests you want to be able to isolate the class you're testing from other classes. But if class A contains a reference to static class B, then you can't test A without testing B. Maybe B depends on connection strings or config settings. Maybe B depends on other static classes. Now you can't test A unless B and everything it depends on are in place.

If, on the other hand, class A depends on an interface like IEmployeeProvider that gets provided through its constructor then you can test class A with a mocked implementation of IEmployeeProvider.

If A has IEmployeeProvider as an argument in its constructor then you can tell by looking at the constructor that it depends on IEmployeeProvider. But if it depends on a static EmployeeProvider class somewhere inside a method then the dependency is hidden. You have to read the whole class to know what it depends on.

Also, the static class itself can be harder to test. Unless it's absolutely always going to remain stateless then it's better to have a non-static class that you can unit test.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
  • “ Isthere a reason why the method should be static? If not I'd always side with non-static” — it should really be completely the wrong way round; see my answer. The only reason (and, to be fair, it’s a good reason) to deviate from that is mocking, as you’ve mentioned. But I’d be *extremely* wary of incurring substantially increased complexity simply for testing and nothing else. – Konrad Rudolph Mar 07 '16 at 22:07
  • 1
    This is the best answer so far, and I agree with Scott: non-static classes are usually preferable to static classes. Another important reason to use non-static classes, even if you're not writing tests, is to take advantage of dependency injection. The OP's scenario is a perfect example where I would **certainly** use non-static classes for all BAL objects. – Michael Liu Mar 09 '16 at 00:22
  • Using a non-static class enables you to depend on an abstraction, and as Michael said, to use dependency injection. Depending on an abstraction is not "substantially increased complexity." It's an established principle of object-oriented programming, the D in SOLID - dependency inversion. It's established for good reason. It prevents coupling, and allows us to write simple classes that can be read, understood, and tested in isolation from their dependencies. Whatever someone thinks they save by ignoring that, they or someone else pay it back a few times over when reading or maintaining it. – Scott Hannen Mar 13 '16 at 23:38
  • @ScottHannen It’s already in a comment elsewhere but for completeness let me repeat it: there is no need for (non-static) classes to achieve dependency injection. Just pass arguments to functions. That *is* dependency injection, and it’s much simpler. – Konrad Rudolph Mar 17 '16 at 11:28
3

It's fine to have multiple threads executing the same static method, as long as the method does not access static state such as field or properties. In that case, the shared objects stored in the fields/properties must themselves be thread safe. The data access parts of .Net are not designed to be thread safe.

As soon as you start considering aspects such as managing a database connection that can be reused for several queries during the execution of a single web request, you should consider if static is the best approach. Since you cannot store the connection in a static field as explained above, you will have to pass it as a parameter to each static method. On the other hand, if you pass the connection to a constructor and store it in a (non-static) field, you can access it from multiple non-static methods of that instance, which will IMO be easier to manage.

This is quite a big topic however, and in general the management of class dependencies is quite tricky to get right in OOP. Some programmers prefer to delegate this task to an "Inversion of Control"-library. There are many available for .Net such as Microsoft Unity, StructureMap, AutoFac, etc.

Jonas Høgh
  • 10,358
  • 1
  • 26
  • 46
  • Can you update your answer with addressing problems/advantage of my scenarios? – I Love Stackoverflow Mar 04 '16 at 09:03
  • It means you can create complex object graphs automatically and manage the lifetimes of the individual objects. I think you're better off reading a tutorial on IoC containers, or the excellent, though somewhat dated, book by Mark Seemann "Dependency Injection in .Net" https://www.manning.com/books/dependency-injection-in-dot-net – Jonas Høgh Mar 04 '16 at 09:23
  • But i am not asking about DI and Ioc.I am just asking about basic concepts on static and non-static functions. – I Love Stackoverflow Mar 04 '16 at 09:44
  • 1
    Sorry. The problem with using static methods is that you have to pass all state as parameters to the methods, as stated above. If you use an instance method, you can have state as part of the class which is only accessible to that instance, and as such does not have to be thread safe. Is that more clear? – Jonas Høgh Mar 04 '16 at 09:47
  • Please see my question where i have describe scenarios.so can you please provide your answer according to that scenario?? – I Love Stackoverflow Mar 04 '16 at 09:49
  • It's hard to be more concrete since you've just given us SQL pseudocode for your data access methods. But in practice, if you e.g. use ADO.Net, you will need to create and open an SqlConnection, etc. If you want to fetch many different database objects in the same request, you will need to consider how to manage that connection across multiple data access method calls. If the methods are static, you will need to pass the same SqlConnection instance to all the methods (if you want good performance and scalability) – Jonas Høgh Mar 04 '16 at 10:05
3

To answer your question:

So my question is should i create this method as static method or non static method?? Note:This is just an example of method and this method is in my business access layer.

I would make those methods static - given what you provided. But I bet that you would have instance variables either declared in your class, or in methods in that class, which then of course that would mean don't make it static.


So a determining factor for me if I decide to use a static method or not has to do with re-use and resources.

If I find myself re-using a method many times over, and I conclude it doesn't need state (kept in memory) - I will make it a static method.

Also I usually will make my methods static if they can be used in other applications or if I think they will be useful down the road.

For example I recently wrote a method that converts a excel file to a flat file. I made this a static method in its own static class (i may put it in a similar utility class down the road) because I will probably end up using it again in another project, so I can now just reference its class without having to instantiate a new object to just call the method. ( I don't need state anyways)

I'm pretty new to programming as well and I hope you found this helpful.

Radmation
  • 1,486
  • 1
  • 13
  • 30
  • 1
    There’s no relationship between reuse and static methods. In fact, it is often appropriate to make a *class* reusable, rather than a single method, and there’s no reason at all why this class should be static. Furthermore, I think it’s misleading to think in terms of resources rather than state when considering whether a method is supposed to be static. “State” is effectively bound to a resource (e.g. memory) but thinking about resources here is thinking at the wrong level of abstraction. – Konrad Rudolph Mar 21 '16 at 22:23
  • @KonradRudolph - I disagree with you saying that there is "No relationship between reuse and static methods." There is a 100% relationship between static methods and reuse. . Suppose we have a set of helper or utility methods which we would like to wrap together in a class. Since these methods are generic in nature, we can define them all inside a static class. Remember that helper or utility methods need to be called many times, and since they are generic in nature, there is no need to create instances. – Radmation Mar 23 '16 at 19:53
  • @KonradRudolph - Also static methods do not need to be initialized so there is less overhead too. If you do not need state, and plan to reuse it alot - make it static. – Radmation Mar 23 '16 at 19:55
  • That’s simply not true. First off, generic has got nothing to do with static. Second off, *most* reusable functionality (>90%, I’d estimate) for .NET isn’t wrapped in static methods but rather in non-static classes. The overhead argument is likewise wrong: if your static method needed specific objects, these would need to be constructed, in the same way as a non-static method’s `this` object would be. – Konrad Rudolph Mar 23 '16 at 23:37
2

If we are going to talk about static, we need to introduce a dependency. In this case it is a sql client. Here's what the code looks like with that introduced. Since we aren't going to get into the details of a sql client it's used as an interface in the static method.

var client = new SqlClient();
var allEmployeeData = EmployeeBal.GetAllEmployees(client);

class EmployeeBal
{
    public static Employee GetAllEmployees(ISqlClient client)
    {
        return client.Execute("Select * from Employee");
    }
}

Dependency injection through an interface changes everything. Now the method is good as being static, because it only deals with an interface and a string. Both of these are stateless. Since all components of the method are stateless they are perfectly safe for a static method which can have only one global state.

As your code was written originally it's not safe as being static, because how can I be assured the sql client is prepared to be used and after I've checked that it's ready it hasn't been altered when I go to run the query? If I can inject the sql client I can manage it since it has a local vs global scope.

A better example would be something like a factory for a sql client. For example with nhibernate there should only be one session factory created. That one thread safe session factory can create multiple non-thread safe sessions for running sql queries. In this case it's appropriate to have the session factory exposed through a static method, because that describes the fact that there is only ever going to be one session factory.

var session =  SessionFactory.OpenSession();
Timothy Gonzalez
  • 1,802
  • 21
  • 18
1

Use cases for static and non-static methods differ, so you need to create one based on what's the need that they fulfill:

  • Static method does not participate in inheritance-based polymorphism, while non-static does. In other words, you can't mark static method as virtual or abstract, which means you cannot change its behavior. This also means that caller of the static method knows exactly what this static method is going to do and how exactly. With non-static method, you can be calling it on base class but due to polymorphism you may end up calling the derived class method with overriden behavior.
  • Both static and non-static methods can be changing a state of something (as opposed to what others claim), but there's a difference. You can design a static class that has all static members (properties, methods, etc.) in it, so the methods can be changing the state of this static class (that said, even though C# allows you doing that, I don't recommend creating such class anyway). With non-static method, you can be changing both static and non-static state of the class. This goes further into the differences between static and non-static classes, which in short means: static class is one concrete instance, while a non-static class can be multiplied and each of them will have its own copy of the state (so why design a static class with the artificial limitation then - this is why I didn't recommend them before).
  • One more nice usage of static methods is extension methods. These should be defined as static, but you can call them on the instance of the class that they are extending. They still serve as outside shortcuts to the instance, since they can't do anything more than regular static methods (cannot access private or protected members for instance).
  • And you're right, static class fits well when defining helper methods, because those usually are just shortcuts to some fixed functionality, accessible easily to re-execute it from many places. In Visual Basic, instead of static keyword you would use shared keyword, which nicely explains the purpose of the static method.

Finally, I personally recommend creating static methods as Pure functions, which always produce same output for the same input (no side effects, such as output is different based on time or other implicit factors). You should have a strong reason to design it otherwise (e.g. if you are writing Math.Random()).

Now, to answer the points from your question (I know, finally):

  • I think business access layer should not be static, because you would most likely need benefits of non-static classes, such as dependency injection and unit-testability.
  • There is no difference between static and non-static methods from the threading/multithreading standpoint, both of them can be called by multiple threads at the same time and all of them will execute simultaneously (unless using synchronization constructs). However, there is common design recommendation that you should make static methods thread-safe if you expect race conditions. Non-static methods don't have to worry about this, as this would put them into too many assumptions.
Tengiz
  • 8,011
  • 30
  • 39
1

Using static methods is equivalent of having a global behaviour. It comes with benefits: ease of access for simple scenarios.

It also comes with all the problems that global data and state have. Among them you cannot substitute an implementation with another (for example for tests). See https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil

While you might consider that you don't have a global state ... conceptually you have. You have a unique, predetermined, unconfigurable, hard coded way of accessing some behaviour. You published it and you cannot change it ... ever. You break the open-close principle. You break the liskov substitution principle.

Java has this but scala amended that. More on this here: Why doesn't Scala have static members inside a class?

Community
  • 1
  • 1
raisercostin
  • 8,777
  • 5
  • 67
  • 76