CleanCode logo
sitemap
SEARCH:
NAVIGATION: first page in sectionprevious pageup one levelnext pagefinal page in section

Guideline RP4: Do not repeat effectively isomorphic code fragments

Going further still with isomorphic code fragments, what if there is a statement that differs in content beyond just a value? That is, previously we've considered two code fragments that could be parameterized to be identical. But how about if we have 10 lines of code in two areas, the only difference being that one has a print statement in the middle, while the other does not (or has a different statement perhaps). You can add logic, via parameters, to restore an isomorphic structure. If, for example, you have a function f with statements A, B, C, D="print abc", E, F and a second with A, B, C, D="store abc", E, F, add a parameter -- f(choice) -- so statement D becomes "if (choice==a) then print abc else store abc".

The example below provides a more real-world study. Here we show three different common means of reading a text file, and we create an isomorphism by using three parameters--not two as you might think at first glance.

EXAMPLEPerl
Instead of:
	# read $file1 as a string...
	my $string = undef;
	if (open(READER, $file1)) {
		local $/; $string = <READER>;
		close(READER);
	}

	# read $file2 as an array...
	my @arr1 = ();
	if (open(READER, $file2)) {
		@arr1 = <READER>;
		close(READER);
	}

	# read $file3 as an array AND remove line terminators...
	my @arr2 = ();
	if (open(READER, $file2)) {
		@arr2 = <READER>;
		chomp(@arr2)
		close(READER);
	}
	# process $string and arrays @arr1 and @arr2...
Use:
	sub readFile {
		my ($fileName, $chompIt) = @_;
		my $contents = undef;
		my @contents = ();
		local *READER;
		if (open(READER, $fileName)) {
			if (wantarray) { @contents = <READER>; chomp(@contents) if $chompIt; }
			else { local $/; $contents = <READER>; }
			close(READER);
		}
		return wantarray ? @contents : $contents;
	}
	my $contents = readFile($file1);
	my @contents = readFile($file2);

The user can direct the function to truncate line endings or not via the chompIt parameter. The second parameter is, of course, the filename, rather than having it hardcoded. Did you spot the third "parameter"? It is implicit--the calling context. Based on whether the context is scalar or array, the function behaves differently.

Valid XHTML 1.0!Valid CSS!Get CleanCode at SourceForge.net. Fast, secure and Free Open Source software downloads
Copyright © 2001-2013 Michael Sorens • Contact usPrivacy Policy
Usage governed by Mozilla Public License 1.1 and CleanCode Courtesy License
CleanCode -- The Website for Clean DesignRevised 2013.06.30