visit
You can find all the previous code smells (Part i - XXXVI) here.
Nested or Pseudo-Private Classes seem great for hiding implementation details.
TL;DR: Don't use nested classes
class Address {
String description = "Address: ";
public class City {
String name = "Doha";
}
}
public class Main {
public static void main(String[] args) {
Address homeAddress = new Address();
Address.City homeCity = homeAddress.new City();
System.out.println(homeAddress.description + homeCity.name);
}
}
// The output is "Address: Doha"
//
// If we change privacy to 'private class City'
//
// We get an error " Address.City has private access in Address"
class Address {
String description = "Address: ";
}
class City {
String name = "Doha";
}
public class Main {
public static void main(String[] args) {
Address homeAddress = new Address();
City homeCity = new City();
System.out.println(homeAddress.description + homeCity.name);
}
}
// The output is "Address: Doha"
//
// Now we can reuse and test the City concept
We need to keep a minimal set of concepts.
Code Smells are just my opinion.
Developers are drawn to complexity like moths to a flame, frequently with the same result.
Neal Ford
Software Engineering Great Quotes
We are refactoring fans. Sometimes we need to stop and think.
TL;DR: Don't make generalizations beyond real knowledge.
fn validate_size(value: i32) {
validate_integer(value);
}
fn validate_years(value: i32) {
validate_integer(value);
}
fn validate_integer(value: i32) {
validate_type(value, :integer);
validate_min_integer(value, 0);
}
fn validate_size(value: i32) {
validate_type(value, Type::Integer);
validate_min_integer(value, 0);
}
fn validate_years(value: i32) {
validate_type(value, Type::Integer);
validate_min_integer(value, 0);
}
// Duplication is accidental, therefore we should not abstract it
Code Smells are just my opinion.
Duplication is far cheaper than the wrong abstraction.
Sandi Metz
Comments are a code smell. Obsolete comments are a real danger and nobody maintains what can't be executed.
TL;DR: Don't trust comments. They are dead.
Refactoring 005 - Replace Comment with Function Name
void Widget::displayPlugin(Unit* unit)
{
// TODO the Plugin will be modified soon,
// so I don't implement this right now
if (!isVisible) {
// hide all widgets
return;
}
}
void Widget::displayPlugin(Unit* unit)
{
if (!isVisible) {
return;
}
}
Code Smell 05 - Comment Abusers
Code Smell 152 - Logical Comment
Code Smell 151 - Commented Code
Code Smells are just my opinion.
Obsolete comments tend to migrate away from the code they once described. They become floating islands of irrelevance and misdirection in the code.
Bob Martin
Software Engineering Great Quotes
Arrow code is a code smell. Exception polluting is another. This is a mortal combination.
TL;DR: Don't cascade your exceptions
In the same way arrow code is hard to read, handling exceptions is a usual case when we must address the topics in a cascade way.
class QuotesSaver {
public void Save(string filename) {
if (FileSystem.IsPathValid(filename)) {
if (FileSystem.ParentDirectoryExists(filename)) {
if (!FileSystem.Exists(filename)) {
this.SaveOnValidFilename(filename);
} else {
throw new I0Exception("File exists: " + filename);
}
} else {
throw new I0Exception("Parent directory missing at " + filename);
}
} else {
throw new ArgumentException("Invalid path " + filename);
}
}
}
public class QuotesSaver {
public void Save(string filename) {
if (!FileSystem.IsPathValid(filename)) {
throw new ArgumentException("Invalid path " + filename);
} else if (!FileSystem.ParentDirectoryExists(filename)) {
throw new I0Exception("Parent directory missing at " + filename);
} else if (FileSystem.Exists(filename)) {
throw new I0Exception("File exists: " + filename);
}
this.SaveOnValidFilename(filename);
}
}
Code Smell 26 - Exceptions Polluting
Code Smells are just my opinion.
An error doesn't become a mistake until you refuse to correct it.
Orlando Aloysius Battista
Software Engineering Great Quotes
Regular expressions are a code smell. Sometimes also a vulnerability
TL;DR: Try to minimize Regular Expression's recursive rules.
package main
import (
"regexp"
"fmt"
)
func main() {
var re = regexp.MustCompile(`^(([a-z])+.)+[A-Z]([a-z])+$`)
var str = `aaaaaaaaaaaaaaaaaaaaaaaa!`
for i, match := range re.FindAllString(str, -1) {
fmt.Println(match, "found at index", i)
}
}
package main
import (
"fmt"
"strings"
)
func main() {
var str = `aaaaaaaaaaaaaaaaaaaaaaaa!`
words := strings.Fields(str)
for i, word := range words {
if len(word) >= 2 && word[0] >= 'a' && word[0] <= 'z' && word[len(word)-1] >= 'A'
&& word[len(word)-1] <= 'Z' {
fmt.Println(word, "found at index", i)
}
}
}
Code Smell 41 - Regular Expression Abusers
Code Smells are just my opinion.
Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.
Jamie Zawinski