Skip to main content

Easing code reuse and refinement through the use of the entity-component pattern

Easing code reuse and refinement through the use of the entity-component pattern

In software development, there's an axiom that states that you should reuse code when it's possible and useful to do so. Common sense, right? Why WOULDN'T you reuse code? Not only does it save you from reimplementing functionality that you may have written before in othe projects, it also plays a big role in ensuring that your code is as bug-free as possible, due to the (obvious) fact that as code is used over and over again, bugs will pop up and be fixed.

In my experience, people typically try to solve the code reuse 'problem' using inheritance chains. By definition, it is true that classes who inherit do reuse code that was written in the parent. HOWEVER, the little bit of code that gets reused in this instance is not worth the inevitable huge, hard-to-see inheritance chain that is created. Inheritance locks your classes into a rigid, fragile system that can be tedious and difficult to break out of. There IS another solution -- composition. Anyone who has taken an undergrad course in software engineering will be familiar with it.

Composition is the 'technique' where, instead of inheriting from a parent, you add an instance of a class containing some functionality you want as a data member to your class. This loosens things up considerably by not enforcing a strict hierarchy on your code. It is common place for a class to contain several data members that represent various pieces of functionality. This system of composition works really well; however, it still doesn't guarantee flexibility and ease of use, as each piece of functionality might have its own interface, and making changes to that interface could require refactoring.

Enter the entity-component pattern, which standardizes interfaces for both consumers (classes which use functionality) and producers (classes which provide functionality) and promotes the reuse and refinement (!!) of bundles of code across a program (or set of programs). In this system, components are little bits of specific functionality (say, a control system, a position tracker, or logging system), which you can add to an entity (basically an empty shell) to create objects with unique behavior.

The benefits of the entity-component pattern are numerous, chief among them being the capability to write bits of code that can be easily reused across a possibly disparate set of use cases. The hierarchy associated with inheritance-based code reuse is also nearly non-existant, as the only inheritance that should be going on is categorical in nature. It also makes it easy to keep track of which entities use a particular piece of functionality, and to create a function that can generate a list of those entities to work with. Crafty.js (a Javascript game programming library) does just this. It provides a jQuery-inspired selector function that allows you to specify a string of components, and it returns a list of objects that contain those components for you to act on.

This blog post is example-less, I know, so my next one will begin documenting my journey to implement a jQuery-inspired entity-component system in either Python or Ruby. You'll have all the sample code you can stomach!

Till next time,
Dustin