WebDevStudios / oops-wp

A collection of abstract classes, interfaces, and traits to promote object-oriented programming practices in WordPress.
57 stars 9 forks source link

Can we remove interfaces for abstract classes? #27

Open salcode opened 4 years ago

salcode commented 4 years ago

We seem to have two types of interfaces, the Utility interfaces e.g.

and those that refer to abstract classes. e.g.

I see a lot of value in the Utility interfaces but I'm not sure I see the value in the interfaces that refer to abstract classes.

Couldn't we use Plugin in place of PluginInterface when type hinting?

jmichaelward commented 4 years ago

I'm interested in discussing this further.

The goal for this project is to provide as flexible a framework as possible for WordPress developers to practice writing plugins and themes in an object-oriented fashion, with a particular emphasis on SOLID principles. As I know you already know, the Dependency Inversion principle states to rely on abstractions, not concretions. Or, as I've seen it phrased elsewhere, "code to a contract".

Those principles raise some questions - is an abstract class a contract? If WordPress core was updated to abide by SOLID principles, would WP_Post be a concrete implementation of an abstract Post object? Would methods that use a post be type-hinted to Post or PostInterface? Is there something that's not a Post that might want its own structure, but requires the use of a Post interface?

That last question is one I don't know the answer to. My gut feeling is that these interfaces need to exist and be wholly separate from their abstract class partners in the spirit of flexibility. But it also means there are flaws in the library, because code like this should be type-hinted to an interface and not an abstract class, because it would allow you as an engineer to choose whether to extend the default Service class or simply use its interface in your own development. In my view, code to a contract should mean interfaces, because that allows the flexibility of changing the objects if the time comes that those objects need to change, and hence, that's my argument for retaining them.

salcode commented 4 years ago

I agree that code to a contract typically means, type hinting to interfaces (not abstract classes), which means that type hinting to Plugin (an abstract class) would go against this. Therefore, I retract my suggestion that we type hint against Plugin.

Looking at the PluginInterface, it extends the Runnable interface (and doesn't add anything to it). My revised suggestion is:

Couldn't we use Runnable in place of PluginInterface when type hinting?

jmichaelward commented 4 years ago

@salcode We certainly could use Runnable, but what if the interface for a Plugin changes in a future release? I'm opting to leave that flexibility in place so that references that are specific to how a Plugin would operate are specific to that structure.

I'm in the process of updating the Wiki today with additional documentation, including structures/utilities that were added in the 0.2.0 release. You can review my rationale for creating standalone interfaces for structures here: https://github.com/WebDevStudios/oops-wp/wiki/Using-OOPS-WP#structure-interfaces.

jmichaelward commented 4 years ago

As another example, you might examine the ShortcodeInterface, which extends both Registerable and Renderable, without defining any required methods of its own. It's true that custom code could type hint against either of those, but by typehinting against ShortcodeInterface, that codebase is specifying that it expects a Shortcode-like object to operate upon.