One Big Class vs Multiple Classes

Multiple smaller classes is nearly always better than one large class. Learn more in this article.

3043 views
d

By. Jacob

Edited: 2020-04-20 17:11

PHP article

One of the questions beginners in OOP might ask is whether it is better to have one big class or several smaller ones. This is actually very easy to answer. The clear winner is multiple smaller classes in nearly all situations.

If you just have one big class it will get extremely hard to maintain as your project grows. Scrolling up and down to find things can take quite a while, and I personally find that even when working with small classes, lets say below 1000 lines, scrolling tend to disrupt my flow a lot, especially if I am already tired or frustrated about some problem I am trying to solve.

You can, of course, still use the search function in your editor to quickly find what you are looking for; while this does eliminate some of the need to scroll, I am still wasting a significant amount of time on looking for things and getting confused on occasion.

Having smaller classes helps tremendously with this problem, and it also helps you write code that is more flexible and portable.

You should avoid using inheritance to design your objects; instead, try to rely more on dependency injection, as it tends to make your code more flexible. Also, as a rule of thumb, try to stick to one class per .php file.

Directory structure

When you are using multiple classes, you should really think about your directory structure.

In my own projects, I like to have a directory in the root called lib. Inside of this directory I have subdirectories for my objects (classes). I have one subdirectory for each object, which might consist of several classes.

The reason I stick to one subdirectory per object, even when I only got a single class in the directory, is, at some point this class might grow, at which point I might decide to split the class into several smaller ones.

It is often hard to know how many classes you will have before hand, so I will typically just start out with one class, and then split it when I find it makes logical sense.

For inspiration, look at this hypothetical example structure:

  1. lib
    1. content_handler
      1. admin_pages
      2. profile_pages
      3. content_pages
  2. database_handler
    1. database_client
  3. templates
    1. default
      1. admin_pages.php
      2. profile_pages.php
      3. content_pages.php
      4. 404_not_found.php
      5. 503_service_unavailable.php
  4. images
    1. logo.png
    2. social-icons.png

Note. Templates is also commonly referred to as "views", I just think it makes more sense to call it "templates". This directory typically contains HTML templates and CSS files for a website.

Application Architecture

Part of the process in creating your application architecture is to create a suitable directory structure, as well as choosing a design pattern to follow. This may seem intimidating at first, but is actually not that hard, and very often it is a process, so do not expect your architecture to be perfect from the start.

A common design pattern for web applications is MVC (Model-View-Controller).

Even if you are not following a design pattern, a very basic principle that will tend to force you into thinking in patterns without planning for it ahead, is the Don't Repeat Yourself (DRY) principle. This principle is about avoiding repeating yourself when you code. Instead of writing the same code over and over, you create a function (or Method in a class) that can then be called whenever needed.

Multiple classes and code reusability

As your project grows, you will probably start to split your classes into multiple classes. Both because this makes it easier to maintain your code, and because it makes it easier to reuse code in other projects or places. At this point you might have a class that outputs your HTML, and another class that connects to your database. Etc.

When you have worked with multiple classes for awhile, you might also realize that dependency injection (DI) is better then class extends, since it allows you to instantiate your classes independently without having to also instantiate irrelevant child classes that might not be needed.

A good reason why you should avoid class extends is when you have classes that are extended, they tend to loose their flexibility, and you will not be able to easily use them separately. Instead, you can simply create a "factory" class to "build" your objects with all of their dependencies.

Another reason to avoid extends is that the instantiation process tend to get more confusing. You need to name your files in a specific way to know which file/class the object should be instantiated from, which again makes you loose flexibility when naming files or when using an autoloader that requires file names to match class names.

Avoiding the new keyword inside classes

You should nearly always avoid instantiating objects inside other object. Meaning, you should avoid using the new keyword inside other classes–except for your within your factory classes, which are used to instantiate all the required classes, and pass them on where needed.

Completed objects, as in objects made from multiple classes, can either be "build" from your composition root (I.e. index.php), or you can use a factory class to make the objects. It makes sense to have factories that instantiate objects when you have multiple classes with lots of dependencies, because this makes it more clear what exactly is needed to build a certain object.

Using factories is useful when writing loosely coupled code that is very flexible and easy to reuse.

Tell us what you think:

  1. In this Tutorial, it is shown how to redirect all HTTP requests to a index.php file using htaccess or Apache configuration files.
  2. How to create a router in PHP to handle different request types, paths, and request parameters.
  3. Tutorial on how to use proxy servers with cURL and PHP
  4. When using file_get_contents to perform HTTP requests, the server response headers is stored in a reserved variable after each successful request; we can iterate over this when we need to access individual response headers.
  5. How to effectively use variables within strings to insert bits of data where needed.

More in: PHP Tutorials