DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Data Engineering
  3. Databases
  4. Static Classes Are Evil, Make Your Dependencies Explicit

Static Classes Are Evil, Make Your Dependencies Explicit

According to one developer, static classes are evil. Click here to learn more about one dev's approach to static classes and keeping dependencies explicit.

Vadim Samokhin user avatar by
Vadim Samokhin
·
Aug. 28, 18 · Opinion
Like (10)
Save
Tweet
Share
14.75K Views

Join the DZone community and get the full member experience.

Join For Free

In spite of some languages, e.g. PHP or Java, some languages don’t have (top-level) static classes. However, the concept is still present. A class consisting entirely of static methods is effectively the same thing as a static class.

Besides, static classes are procedural, and their clients are untestable — well, there are some hacks in Java and PHP, but I don’t want to mention them. Because they have even more issues.

Classes Tend to Go From Big to Huge

Since classes with static methods have nothing to do with objects, they don’t know who they are, what they should do, and what they should not do. The boundaries are blurred, so we just write one instruction after another. It’s hard to stop until we’re done with our task. It is inevitably an imperative and non-OOP process.

Dependencies Are Hidden

Code is also less readable. What’s in the class? Database queries, some intense calculations, email sending? You just don’t control how many of them are in one class. One static method here, one there — and here it is, our new God object. And when you realize that, it’s already too late.

Low Cohesion

Hence, the class is getting less and less cohesive. If the class has a lot of dependencies, chances are that it does more than it should. For the sake of justice, I should say that the possible reason for a large number of dependencies is that they are at lower abstraction levels. Composing dependencies in higher-level abstractions could be the way to go.

Tight Coupling

Static methods mean that they can be called from anywhere. They can be called from a lot of contexts. They have a lot of clients. So, if one class needs some little special behavior to be implemented in a static method, you need to make sure that none of the other clients get broken. So, such reuse simply doesn’t work. I can compare it with my noble (and failed) attempt to compose and reuse microservices. The resulting classes are too generic and completely unmaintainable. This results in the whole system being tightly coupled.

Example

As an example, let’s consider a client’s financial balance from my posts about Super PSP architecture. It has all mentioned drawbacks and looks like this:

class FinancialBalanceUtils
{
    static public void reserveBalance()
    {
        if (!shouldReserve()) {
            return;
        }
        assertAllConditionsAreMet();
        queryFinancialBalanceForCurrentClient();
        boolean result = checkFinancialBalance();
        if (!result) {
            return false;
        }
        reserveFinancialBalanceForCurrentClient();
    }
}


So, let’s inspect it from the beginning.

We are not sure where it is called from, as it can be called from absolutely anywhere. So, we need to make sure that this method really should be executed through the  shouldReserve() method.  We are not sure where it is called from, once again! Are all preconditions satisfied? No one knows, so we absolutely must verify this with the  assertAllConditionsAreMet() method. 

Then, we get financial balance by tons of parameters from a database with the  queryFinancialBalanceForCurrentClient() method, as the query and database table serve the needs of every client who needs financial balance.  However, we are still not sure if the financial balance is fine. We need to check what’s in there using the method  checkFinancialBalance().

Now, finally, we reserve the balance with  reserveFinancialBalanceForCurrentClient(). I omitted logging, error handling, and minor code quirks and kept only the essentials. And, it’s already too big.  This class is a hidden dependency itself, and it, therefore, consists of hidden dependencies. How much database queries are executed in this method? I don’t know. 

Try OOP, Instead

Do you still have any doubts that this class does more than it should?  Was it worth it to allegedly avoid copy-paste, which resulted in completely unmaintainable, super-generic code that is difficult to edit? Let's try OOP, instead.

  • Identify your objects. Focus on “what,” not “how.” Focus on objects, not procedures.
  • When objects are identified, make all your dependencies explicit first and limit their number. Limit it to five per method. Why five? I don’t know, it just sounds reasonable. Six feels like too much already. When there are more than five, your class wants to do more than it should. Or, probably, the abstraction level of those dependencies is too low. Anyway, explicit dependencies give you a chance to make your design more solid.
  • Don’t generalize too early, remember the Rule of Three. Implement only some specific scenarios first.
Dependency Database

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Top 5 Data Streaming Trends for 2023
  • Introduction To OpenSSH
  • What Is Advertised Kafka Address?
  • Getting a Private SSL Certificate Free of Cost

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: