Quick Index
Overview


Helper methods are simply methods that we add to a class to make the overall logic simpler.

We could also call them "buddy methods", "support methods", "other methods", "sister methods", etc. (just a label -- up to you).

Say we have a method that is twenty lines long and very complex -- time to add helper method(s).

Say we have a method that has multiple purposes and some of the purposes are general (reusable) - time to add helper method(s).

Example 1 - The Disappearing Code Blob Magic Trick 💡


This is the same example as we looked at in Value of Method Summaries. That is because both of these concepts are all about logic reuse and "logic simplification".

Code Without Helper Methods 🐞
Here is a method that has a simple concept: To figure out if two frames (rectangles) intersect, and return true if they do.

A bit complex (to say the least). It's a blob of code! It is heavy, heavy code. Alerts go out that code simplification is needed.
intersects1(other) {
	/*
		Method in "Frame" class
		Return true if this (rectangular) frame intersects "other" (also a Frame)
		Both are simple rectangular frames that have (point object) corners "lt", "rt", "rb" and "lb"
		(i.e. left-top, right-top, right-bottom, and left-bottom).
		We define an intersection if any corner of "other" is in "this" frame object.
		If other corner is "on" any of our edges, we'll call that inside (yes an intersection)
		Assume frame y-axis is downward (common in computer graphics)
	*/
	//Algorithm -- no helper (buddy) methods
	let
		lt = new Point(other.getLeft(), other.getTop()),
		rt = new Point(other.getRight(), other.getTop()),
		rb = new Point(other.getRight(), other.getBottom()),
		lb = new Point(other.getLeft(), other.getBottom());
	return ((lt.getX() >= this.getLeft() && (lt.getX() <= this.getRight()))
		&& (lt.getY() >= this.getTop() && (lt.getY() <= this.getBottom())))
		|| ((rt.getX() >= this.getLeft() && (rt.getX() <= this.getRight()))
			&& (rt.getY() >= this.getTop() && (rt.getY() <= this.getBottom())))
		|| ((rb.getX() >= this.getLeft() && (rb.getX() <= this.getRight()))
			&& (rb.getY() >= this.getTop() && (rb.getY() <= this.getBottom())))
		|| ((lb.getX() >= this.getLeft() && (lb.getX() <= this.getRight()))
			&& (lb.getY() >= this.getTop() && (lb.getY() <= this.getBottom())))
}

Code With Helper Methods ✔
Same method description as above.

But this time we've done a little analysis, and see that adding just a few simple helper methods on Point [getLT(), getRT(), getRB(), and getLB()] and on Frame [contains(aPoint)] makes the logic much, much simpler.

The big blob of code in the previous step has evaporated.

And (very important) testing and bug finding and fixing is magnitudes easier. This is because of nice simple "lightweight code".
intersects2(other) {
	//Method in "Frame" class
	let
		lt = other.getLT(),
		rt = other.getRT(),
		rb = other.getRB(),
		lb = other.getLB();
	return this.contains(lt) || this.contains(rt) || this.contains(rb) || this.contains(lb);
}



Example 2 - The Object 'this' and Helper Methods


The object 'this' is an object we are currently working in. Just like sending messages to another object, we can also send messages to "this" -- and we should -- as often as possible.

Let's say we are part of a team coming up with the logic for rocket launch.

Try 1 -- One Unweildy Method!
Our first cut is one long method -- 1000 lines of logic.

A method with 1,000 lines would be unweildy, confusing, and almost impossible to test, maintain and fix.
launch() {
	//1000 lines of logic
}
Try 2 -- Helpers to The Rescue
We have replaced the massively long method with eight helper methods (and each of them likely calls more helper methods).

The biggest advantage (of many) with this approach may be that we can now isolate testing onto the helper methods. Once these helpers are all green (tests pass) then we are confident in the "launch()" method.
launch() {
	this.checkFuel();
	this.checkSystems();
	this.alertCrewToLockIn();
	this.startFlightComputer();
	this.alignFlight();
	this.pressurizeSystems();
	this.lightIgnition();
	this.blastOff();
}



Navigation