TIL – Term “God/Godlike Object”

Today, I encountered the “godlike object” term, and here is what it is:

In object-oriented programming, a god object (sometimes also called an omniscient or all-knowing object) is an object that references a large number of distinct types, has too many unrelated or uncategorized methods, or some combination of both. The god object is an example of an anti-pattern and a code smell.

https://en.wikipedia.org/wiki/God_object

This is somewhat every developer would avoid, especially when working on a large codebase. Remember two relevant terms: “divide and conquer strategy” in algorithm and “single-responsibility principle” in OOP.

Testing PHP Static Functions with PHPUnit: Challenges and Solutions

Static methods in PHP can be convenient, but they pose significant challenges when it comes to unit testing. This post explores why testing static methods is hard, why it’s advisable to avoid them in testable code, and what strategies can be employed to mitigate these issues.

Why Testing Static Methods is Hard

Static methods are inherently tied to their class and cannot be easily replaced or mocked during testing. This tight coupling makes it difficult to isolate the method under test, leading to tests that are less reliable and harder to maintain.

Why We Should Avoid Static Methods in Testable Code

Using static methods can lead to code that is tightly coupled and difficult to test. This is particularly problematic when static methods perform actions like logging, caching, or interacting with external systems.

For instance, in this WooCommerce Payments PR, I encountered difficulties testing a Logger class that relied on static methods. The inability to mock these methods led to challenges in writing effective unit tests.

Strategies for Testing Static Methods

While it’s best to avoid static methods in testable code, there are scenarios where they are necessary. In such cases, consider the following strategies:

1. Use Dependency Injection – Most Preferred

Dependency Injection (DI) allows injecting dependencies into classes, making them more testable. By injecting a logger or cache handler, it’s possible to replace these dependencies with mocks during testing.

As highlighted in the blog post on Dependency Injection, DI helps in achieving loose coupling and makes unit testing more straightforward.

2. Wrap Static Methods

If you must use static methods, consider wrapping them in instance methods. This approach allows you to mock the wrapper during testing, providing greater flexibility.

3. Use Callables

Another approach is to pass callables (like closures) into your methods. This technique enables you to replace static method calls with mock functions during testing. But it’s not ideal as it makes things complicated.

Conclusion

Try best to avoid injecting static methods for objects you’d like to test with PHP. The only good reason I have seen for it so far is to for utils/helpers. Using Dependency Injection is the most favorable approach to write more testable and maintainable code.

Dependency Injection (plus Inversion of Control, and Dependency Inversion principle)

This is a note for myself to get to know more concrete details about Dependency Injection.

Dependency injection is a design pattern or at least “a set of patterns and principles; i.e. not a single pattern”. The intent behind dependency injection is to achieve separation of concerns of construction and use of objects.

This Wikipedia section is excellent in defining roles in dependency injection (their examples are great too):

  • the service objects, which contain useful functionality
  • the interfaces by which those services are known to other parts of the code
  • the client object, whose behavior depends on the services it uses
  • the injector, which constructs the services and injects them into the client

Three different types of depedency injections:

  • Constructor injection
  • Setter injection
  • Interface injection

Some thoughts from Martin Fowler:

  • Generally, Dependency Injection is better than Service Locator.
  • The choice between them is less important than the principle of separating configuration from use.
  • Prefer constructor injection over setter injection.

References:

Java – My First Sip

When reading Head First Design Patterns, I need to run a few examples in Java. Plus that I also want to learn more about Java for two reasons: it’s well-known as a strongly typed programming language, and I have heard quite a lot that it’s a good language to learn OO (object-oriented) deeply.

Some notes:

Finally, these commands make Java examples of the book work:

$ cd ~/path/to/Head-First-Design-Patterns/src/headfirst/designpatterns/strategy
$ javac *.java
$ cd ~/path/to/Head-First-Design-Patterns/src
$ java headfirst.designpatterns.strategy.MiniDuckSimulator

Quack
Squeak
<< Silence >>
I can't fly
I'm flying with a rocket

Woo Viet 1.5.0 and OnePay Gateways

It has been one year since my previous release 1.4.5 for Woo Viet – WooCommerce for Vietnam. In this version 1.5.0, I focused on two main issues:

I tracked this version with the milestone feature in GitHub.

Continue reading “Woo Viet 1.5.0 and OnePay Gateways”