Object-Oriented design to create Images in Python

  softwareengineering

I’m creating images with centered text. I use Python but I’m faced with many question regarding how to write my class.
I know that

A class must aim to do one thing and do it well.

Well, the one thing I want to do with this class is print centered text on a background image but I think I need help to really understand this since I have many questions:

  • Should I write a class that have a method to create the background
    image?
  • Should I have another method in the same class to put the text centered on the
    background image?
  • And when do I save the image to disk? Should I
    have another method to save the image?

If I’m correct, my class will look like this:

# -*- coding: utf-8 -*-                                                         

class CreateImage():                                                            
    def create_background(self):                                                
        print("Creating background")                                            
    def print_text_image(self, text):                                           
        print("Printing the following text on Image: ")                         
        print(text)                                                             
    def save(self, destination):                                                
        print("Saving the image on disk on: ")                                  
        print(destination)                                                      

my_object = CreateImage()                                                       
my_object.print_text_image("Hello World!")                                      
my_object.save("Images/my_images")                                              
~                                  

It does look fine to me. But the thing is that the print_text_image method has to many responsibilities:

  • Calculate how much pixels on the image we can use (width*height)
  • Calculate how much pixels the text is going to use and if doesn’t fit we reduce the font-size until it fits (trial&error)
  • Calculate margins and finally print the text on the image in a centered way

Looks to me that we can use at least one more method on my CreateImage class:

  • A method to calculate if the font size (text) is small enough to fit in the image (return true or false)

But I’m not sure. I do want to have a good design in my class because later I will use this class as a base for other classes (for example, another class will paste other images into the image that CreateImage creates.)

In definitive, what would be your design for this class? I will really appreciate if you take the time to help me understand this. Thank you so much in advance.

1

Your quote is wrong. It is wrong to say “a class should do one thing and do it well”. A class does not do anything. Better to say “a class should be one thing and be that thing well”.

“Create” is a verb. “CreateImage” sounds like the name of a function, not a class. A class should be the sort of thing you’d describe with a noun, like “Image”.

You can see the problem if you read off your methods.

CreateImage.Save()`

What? You are saving a createimage? Does that make sense?

CreateImage.create_background()

What? You are create_backgrounding a CreateImage? What the hell does that mean?

Let’s rename:

class Image():                                                            
   def add_background(self):                                                
      print("Addinging background")   

   def add_text(self, text):                                           
      print("Adding the following text to Image: ")                         
      print(text)                                  

   def save(self, destination):                                                
      print("Saving the image on disk on: ")                                  
      print(destination)  

Now let’s read:

Image.add_background

Oh, well, obviously that adds a background to the image

Image.add_text

Oh, well, obviously that adds text to an image

Image.save

Oh, well, obviously that saves the image

So your class is just fine. It’s your naming that needs work. If you name appropriately, you can often tell if your class makes sense if it reads naturally.

A class is a noun. It is a thing you do stuff with.

A function/method is a verb. It is a thing that does stuff with other things. (Yes, in some languages a function is an object, but that’s not so important when talking about design at this level.)

If you keep this in mind, and also keep in mind that in each case, a class should be a single conceptual thing, and a function should do a single conceptual thing, you’ll be ok.

1

LEAVE A COMMENT