Previous: Organization of Object-Oriented Code

Refactoring is the process of restructuring code, while not changing its original functionality. The goal of refactoring is to improve internal code by making many small changes without altering the code's external behavior.

Refactoring (noun): a change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.

Refactoring (verb): to restructure software by applying a series of refactoring processes without changing its observable behavior.

The following code shows an example of the declaration of the function that renders a sphere named render_sphere and the function that renders a cube named render_cube:

def render_sphere (x, y, z, radius, camera_x, camera_y, camera_z, camera_direction_x,
camera_direction_y, camera_direction_z, camera_vector_x, camera_vector_y,
camera_vector_z, camera_perspective_field_of_view, camera_near_clipping_plane,
camera_far_clipping_plane, directional_light_x, directional_light_y,
directional_light_z, directional_light_color):
pass

def render_cube(x, y, z, edge_length, camera_x, camera_y, camera_z, camera_direction_x,
camera_direction_y, camera_direction_z, camera_vector_x, camera_vector_y,
camera_vector_z, camera_perspective_field_of_view, camera_near_clipping_plane,
camera_far_clipping_plane, directional_light_x, directional_light_y,
directional_light_z, directional_light_color):
pass

Though a Python function can take an unlimited number of parameters, having a function that takes too much parameters causes the program to lose readability and harder to handle and extend. This is why the idea of Object-Oriented Programming comes forward in the first place, where related data and behaviors can be encapsulated in classes.

Refactoring existing code in Python following the UML Diagram:

Screenshot 2025-04-29 at 10.48.50.png

Refactor code:

# Class Vector 3D with Refactoring
# restructuring code, while not changing its original functionality.

class Vector3D:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

class SceneElement:
    def __init__(self, location):
        # location: Vector3D
        self.location = location

class Light(SceneElement):
    def __init__(self, location):
        super().__init__(location)

class DirectionalLight(Light):
    def __init__(self, location, color):
        super().__init__(location)
        self.color = color

class Camera(SceneElement):
    def __init__(self, location):
        super().__init__(location)

class PerspectiveCamera(Camera):
    def __init__(self, location, direction, vector, field_of_view,
                 near_clipping_plane, far_clipping_plane):
        super().__init__(location)
        self.direction = direction
        self.vector = vector
        self.field_of_view = field_of_view
        self.near_clipping_plane = near_clipping_plane
        self.far_clipping_plane = far_clipping_plane

class Shape(SceneElement):
    def __init__(self, location):
        super().__init__(location)

    def render(self, camera, lights):
        pass

class Sphere(Shape):
    def __init__(self, location, radius):
        super().__init__(location)
        self.radius = radius

    def render(self, camera, lights):
        print("Rendering a sphere")

class Cube(Shape):
    def __init__(self, location, edge_length):
        super().__init__(location)
        self.edge_length = edge_length

    def render(self, camera, lights):
        print("Rendering a cube")

class Scene:
    def __init__(self, initial_camera):
        self.active_camera = initial_camera
        self.shapes = []
        self.lights = []

    def add_light(self, light):
        self.lights.append(light)

    def add_shape(self, shape):
        self.shapes.append(shape)

    def render(self):
        for shape in self.shapes:
            shape.render(self.active_camera, self.lights)

def main():
    camera = PerspectiveCamera(Vector3D(30, 30, 30), Vector3D(50, 0, 0),
                               Vector3D(4, 5, 2), 90, 20, 40)
    sphere = Sphere(Vector3D(20, 20, 20), 8)
    cube = Cube(Vector3D(10, 10, 10), 5)
    light = DirectionalLight(Vector3D(2, 2, 5), 235)
    scene = Scene(camera)
    scene.add_shape(sphere)
    scene.add_shape(cube)
    scene.add_light(light)
    scene.render()

main()

Output:

Rendering a sphere
Rendering a cube