1202
Picking the Best Code Pattern

Go back to 0000 Index

Picking the best code pattern is usually up to personal preference, however some patterns work better than others depending on the task.

Introduction

Notes

Code Patterns

Now it's time to get into the actual design patterns. Each one of these has their own pros and cons, but each should work for most tasks you give it.

Singletons

The only rule for the singleton design pattern is that, when possible, each class should only have one instance. For example, you might have a Robot class. Using the singleton design pattern, that Robot class could have a static method named getInstance. This method returns the global instance, or, if there is no instance, creates one and returns it. Here's how that would look in practice:

public class Robot {
	private static Robot robotInstance = null;
	
	public static Robot getInstance() {
		if (Robot.robotInstance == null) {
			Robot.robotInstance = new Robot();
		}
		return Robot.robotInstance;
	}
	
	private Robot() {
		// initialize the robot
	}
	
	// ...
}

By doing this, the program ensures that there is only ever one singular instance of the Robot class. If there is no instance, it will create one. Otherwise, it will return the already created instance.

Benefits

Downsides

Notes

Global States

Similar to singletons, these also avoid creating multiple instances of the same class. However, with using global states, it is still possible to create multiple instances. The key difference between global states and singletons is where they are stored. Singletons are stored in the class their own class. Global states are generally stored in the OpMode or another parenting class (e.g. Robot to Outtake).

Benefits

Downsides

Notes

Managers

Instead of making classes that have many fields with child classes, you could take a more functional (as in functional oriented programming) approach. While this is generally not a good design due to Java being an object oriented language, this can function well.

Using this approach, you could store the motors and other hardware in a storage class or just as fields in your OpMode. Then, you could make managers with utility functions that do specific actions when called with an argument. For example:

@Autonomous(name = "Example")
public class ExampleAuto {
	public DcMotor motor;
	
	@Override
	public void init() {
		motor = hardwareMap.get(DcMotor.class, "motor");
	}
	
	@Override
	public void start() {
		MotorManager.rotate(motor, 360);
	}
}

Here, we have an example auto mode. Once the mode is started, we call a method on the MotorManager to rotate the motor by 360 degrees. Of course, this assumes we have logic in the MotorManager to calculate ticks from degrees and to stop the rotation once it has completed.

Benefits

Downsides

Notes