SlideShare a Scribd company logo
1 of 161
softwaretester.blog | Benjamin Bischoff
TestCon Europe 2023
Identifying Code Smells
softwaretester.blog | Benjamin Bischoff
Law of Two Feet
• If this is not for you, please don’t stay!
• I mean it!
• Really!
softwaretester.blog | Benjamin Bischoff
About me
• Benjamin Bischoff
• Test Automation Engineer @ trivago N.V.
• 23 years in IT
• Last 8 years in testing
softwaretester.blog | Benjamin Bischoff
I wrote a book
• “Writing API Tests with Karate”
• Available since 05/2023
• Packt Publishing
softwaretester.blog | Benjamin Bischoff
I wrote a book
• “Writing API Tests with Karate”
• Available since 05/2023
• Packt Publishing
softwaretester.blog | Benjamin Bischoff
Disclaimer
• This is only about identi
fi
cation
• Lots of code
• All Java
softwaretester.blog | Benjamin Bischoff
Smelly Code
Smelly code, smelly code
How are they treating you?
Smelly code, smelly code
It’s not your fault.
softwaretester.blog | Benjamin Bischoff
The term
softwaretester.blog | Benjamin Bischoff
The term
softwaretester.blog | Benjamin Bischoff
–Martin Fowler
„A code smell is a surface indication that usually
corresponds to a deeper problem in the system.“
softwaretester.blog | Benjamin Bischoff
Why should you care?
• Communication
Speak a common language
• A step towards better code
Clean code principles and design patterns
• Less technical debt
Clean code principles and design patterns
• Testability
Testable code is maintainable code!
softwaretester.blog | Benjamin Bischoff
TAXONOMY OF
CODE SMELLS
Mika V. Mäntylä & Casper Lassenius,
Helsinki University of Technology
softwaretester.blog | Benjamin Bischoff
TAXONOMY OF
CODE SMELLS
Mika V. Mäntylä & Casper Lassenius,
Helsinki University of Technology
softwaretester.blog | Benjamin Bischoff
Classi
fi
cation
softwaretester.blog | Benjamin Bischoff
Classi
fi
cation
Bloaters
Long Method
Large Class
Primitive
Obsession
Long Parameter
List
Data Clumps
OOP
Abusers
Switch Statements
Temporary
Field
Refused
Bequest
Alternative classes
with di
ff
erent
Interfaces
Change
Preventers
Divergent Change
Shotgun Surgery
Parallel Inheritance
Hierarchy
Dispensables
Lazy Class
Data Class
Duplicate Code
Dead Code
Speculative
Generality
Couplers
Feature Envy
Inappropriate
Intimacy
Message Chains
Middleman
softwaretester.blog | Benjamin Bischoff
Bloaters
Too large to handle.
softwaretester.blog | Benjamin Bischoff
public class WebShop {
private final List<Customer> customers = new ArrayList<>();
public String saveCustomer(final Customer customer) {
customers.add(customer);
return String.format(
"We have a new customer called %",
customer.name());
}
}
Bloaters Long Method
A method that does
too much
softwaretester.blog | Benjamin Bischoff
public class WebShop {
private final List<Customer> customers = new ArrayList<>();
public String saveCustomer(final Customer customer) {
customers.add(customer);
return String.format(
"We have a new customer called %",
customer.name());
}
}
Bloaters Long Method
A method that does
too much
softwaretester.blog | Benjamin Bischoff
public class WebShop {
private final List<Customer> customers = new ArrayList<>();
public String saveCustomer(final Customer customer) {
customers.add(customer);
return String.format(
"We have a new customer called %",
customer.name());
}
}
Bloaters Long Method
A method that does
too much
softwaretester.blog | Benjamin Bischoff
public class WebShop {
private final List<Customer> customers = new ArrayList<>();
public String saveCustomer(final Customer customer) {
customers.add(customer);
return String.format(
"We have a new customer called %",
customer.name());
}
}
Bloaters Long Method
A method that does
too much
softwaretester.blog | Benjamin Bischoff
public class WebShop {
private final List<Customer> customers = new ArrayList<>();
public String saveCustomer(final Customer customer) {
customers.add(customer);
return String.format(
"We have a new customer called %",
customer.name());
}
}
Bloaters Long Method
A method that does
too much
softwaretester.blog | Benjamin Bischoff
public class ShoppingCart {
public void addProduct(final Product product) {}
public void removeProduct(final Product product) {}
public void checkOut() {}
public void enterVoucherCode() {}
public void contactSupport() {}
}
Bloaters Large Class
A class that does too
much
softwaretester.blog | Benjamin Bischoff
public class ShoppingCart {
public void addProduct(final Product product) {}
public void removeProduct(final Product product) {}
public void checkOut() {}
public void enterVoucherCode() {}
public void contactSupport() {}
}
Bloaters Large Class
A class that does too
much
softwaretester.blog | Benjamin Bischoff
public class ShoppingCart {
public void addProduct(final Product product) {}
public void removeProduct(final Product product) {}
public void checkOut() {}
public void enterVoucherCode() {}
public void contactSupport() {}
}
Bloaters Large Class
A class that does too
much
softwaretester.blog | Benjamin Bischoff
public class ShoppingCart {
public void addProduct(final Product product) {}
public void removeProduct(final Product product) {}
public void checkOut() {}
public void enterVoucherCode() {}
public void contactSupport() {}
}
Bloaters Large Class
A class that does too
much
softwaretester.blog | Benjamin Bischoff
public class ShoppingCart {
public void addProduct(final Product product) {}
public void removeProduct(final Product product) {}
public void checkOut() {}
public void enterVoucherCode() {}
public void contactSupport() {}
}
Bloaters Large Class
A class that does too
much
softwaretester.blog | Benjamin Bischoff
record Customer(
String name,
int age,
String street,
String city,
int zipCode,
String country
) {
}
Bloaters Primitive Obsession
Favouring primitive
data types
softwaretester.blog | Benjamin Bischoff
record Customer(
String name,
int age,
String street,
String city,
int zipCode,
String country
) {
}
Bloaters Primitive Obsession
Favouring primitive
data types
softwaretester.blog | Benjamin Bischoff
record Customer(
String name,
int age,
String street,
String city,
int zipCode,
String country
) {
}
Bloaters Primitive Obsession
Favouring primitive
data types
softwaretester.blog | Benjamin Bischoff
public class CadTool {
public static void main(String[] args) {
int result =
CadTool.calculateResult(13, false, true, -1, null);
}
public static int calculateResult(final int baseValue,
final boolean isMetric,
final boolean is2D,
final int offset,
final Integer height) {
return 0; // some calculation
}
}
Bloaters Long Parameter List
Too many method
parameters
softwaretester.blog | Benjamin Bischoff
public class CadTool {
public static void main(String[] args) {
int result =
CadTool.calculateResult(13, false, true, -1, null);
}
public static int calculateResult(final int baseValue,
final boolean isMetric,
final boolean is2D,
final int offset,
final Integer height) {
return 0; // some calculation
}
}
Bloaters Long Parameter List
Too many method
parameters
softwaretester.blog | Benjamin Bischoff
public class CadTool {
public static void main(String[] args) {
int result =
CadTool.calculateResult(13, false, true, -1, null);
}
public static int calculateResult(final int baseValue,
final boolean isMetric,
final boolean is2D,
final int offset,
final Integer height) {
return 0; // some calculation
}
}
Bloaters Long Parameter List
Too many method
parameters
softwaretester.blog | Benjamin Bischoff
public class CadTool {
public static void main(String[] args) {
int result =
CadTool.calculateResult(13, false, true, -1, null);
}
public static int calculateResult(final int baseValue,
final boolean isMetric,
final boolean is2D,
final int offset,
final Integer height) {
return 0; // some calculation
}
}
Bloaters Long Parameter List
Too many method
parameters
softwaretester.blog | Benjamin Bischoff
public class CadTool {
public static void main(String[] args) {
int result =
CadTool.calculateResult(13, false, true, -1, null);
}
public static int calculateResult(final int baseValue,
final boolean isMetric,
final boolean is2D,
final int offset,
final Integer height) {
return 0; // some calculation
}
}
Bloaters Long Parameter List
Too many method
parameters
softwaretester.blog | Benjamin Bischoff
record Customer(
String lastName,
String firstName,
String middleName,
String salutation,
String streetAddress,
String city,
String state,
String country,
boolean isEmployed,
boolean isHomeOwner
) {
}
Bloaters Data Clumps
Grouping unrelated
data
softwaretester.blog | Benjamin Bischoff
record Customer(
String lastName,
String firstName,
String middleName,
String salutation,
String streetAddress,
String city,
String state,
String country,
boolean isEmployed,
boolean isHomeOwner
) {
}
Bloaters Data Clumps
Grouping unrelated
data
softwaretester.blog | Benjamin Bischoff
record Customer(
String lastName,
String firstName,
String middleName,
String salutation,
String streetAddress,
String city,
String state,
String country,
boolean isEmployed,
boolean isHomeOwner
) {
}
Bloaters Data Clumps
Grouping unrelated
data
softwaretester.blog | Benjamin Bischoff
record Customer(
String lastName,
String firstName,
String middleName,
String salutation,
String streetAddress,
String city,
String state,
String country,
boolean isEmployed,
boolean isHomeOwner
) {
}
Bloaters Data Clumps
Grouping unrelated
data
softwaretester.blog | Benjamin Bischoff
record Customer(
String lastName,
String firstName,
String middleName,
String salutation,
String streetAddress,
String city,
String state,
String country,
boolean isEmployed,
boolean isHomeOwner
) {
}
Bloaters Data Clumps
Grouping unrelated
data
softwaretester.blog | Benjamin Bischoff
record Customer(
String lastName,
String firstName,
String middleName,
String salutation,
String streetAddress,
String city,
String state,
String country,
boolean isEmployed,
boolean isHomeOwner
) {
}
Bloaters Data Clumps
Grouping unrelated
data
softwaretester.blog | Benjamin Bischoff
record Customer(
String lastName,
String firstName,
String middleName,
String salutation,
String streetAddress,
String city,
String state,
String country,
boolean isEmployed,
boolean isHomeOwner
) {
}
Bloaters Data Clumps
Grouping unrelated
data
softwaretester.blog | Benjamin Bischoff
OOP Abusers
Missing object-oriented design possibilities.
softwaretester.blog | Benjamin Bischoff
public class Vehicles {
public int numberOfWheels(final String vehicle)
throws Exception {
return switch (vehicle) {
case "car" -> 4;
case "boat" -> 0;
case "bike" -> 2;
case "bicycle" -> 2;
default -> throw new Exception("Unknown");
};
}
}
OOP Abusers Switch Statements
Branching out too
much
softwaretester.blog | Benjamin Bischoff
public class Vehicles {
public int numberOfWheels(final String vehicle)
throws Exception {
return switch (vehicle) {
case "car" -> 4;
case "boat" -> 0;
case "bike" -> 2;
case "bicycle" -> 2;
default -> throw new Exception("Unknown");
};
}
}
OOP Abusers Switch Statements
Branching out too
much
softwaretester.blog | Benjamin Bischoff
public class Vehicles {
public int numberOfWheels(final String vehicle)
throws Exception {
return switch (vehicle) {
case "car" -> 4;
case "boat" -> 0;
case "bike" -> 2;
case "bicycle" -> 2;
default -> throw new Exception("Unknown");
};
}
}
OOP Abusers Switch Statements
Branching out too
much
softwaretester.blog | Benjamin Bischoff
public class Vehicles {
public int numberOfWheels(final String vehicle)
throws Exception {
return switch (vehicle) {
case "car" -> 4;
case "boat" -> 0;
case "bike" -> 2;
case "bicycle" -> 2;
default -> throw new Exception("Unknown");
};
}
}
OOP Abusers Switch Statements
Branching out too
much
softwaretester.blog | Benjamin Bischoff
public class Vehicles {
public int numberOfWheels(final String vehicle)
throws Exception {
return switch (vehicle) {
case "car" -> 4;
case "boat" -> 0;
case "bike" -> 2;
case "bicycle" -> 2;
default -> throw new Exception("Unknown");
};
}
}
OOP Abusers Switch Statements
Branching out too
much
softwaretester.blog | Benjamin Bischoff
public class Rectangle {
private float sideA;
private float sideB;
public void setSideA(float sideA) {
this.sideA = sideA;
}
public void setSideB(float sideB) {
this.sideB = sideB;
}
public double getAreaSize() {
return sideA * sideB;
}
}
OOP Abusers Temporary Field
Fields that are only
used once
softwaretester.blog | Benjamin Bischoff
public class Rectangle {
private float sideA;
private float sideB;
public void setSideA(float sideA) {
this.sideA = sideA;
}
public void setSideB(float sideB) {
this.sideB = sideB;
}
public double getAreaSize() {
return sideA * sideB;
}
}
OOP Abusers Temporary Field
Fields that are only
used once
softwaretester.blog | Benjamin Bischoff
public class Rectangle {
private float sideA;
private float sideB;
public void setSideA(float sideA) {
this.sideA = sideA;
}
public void setSideB(float sideB) {
this.sideB = sideB;
}
public double getAreaSize() {
return sideA * sideB;
}
}
OOP Abusers Temporary Field
Fields that are only
used once
softwaretester.blog | Benjamin Bischoff
public class Rectangle {
private float sideA;
private float sideB;
public void setSideA(float sideA) {
this.sideA = sideA;
}
public void setSideB(float sideB) {
this.sideB = sideB;
}
public double getAreaSize() {
return sideA * sideB;
}
}
OOP Abusers Temporary Field
Fields that are only
used once
softwaretester.blog | Benjamin Bischoff
public class Rectangle {
private float sideA;
private float sideB;
public void setSideA(float sideA) {
this.sideA = sideA;
}
public void setSideB(float sideB) {
this.sideB = sideB;
}
public double getAreaSize() {
return sideA * sideB;
}
}
OOP Abusers Temporary Field
Fields that are only
used once
softwaretester.blog | Benjamin Bischoff
public class Rectangle {
private float sideA;
private float sideB;
public void setSideA(float sideA) {
this.sideA = sideA;
}
public void setSideB(float sideB) {
this.sideB = sideB;
}
public double getAreaSize() {
return sideA * sideB;
}
}
OOP Abusers Temporary Field
Fields that are only
used once
softwaretester.blog | Benjamin Bischoff
public class Rectangle {
private float sideA;
private float sideB;
public void setSideA(float sideA) {
this.sideA = sideA;
}
public void setSideB(float sideB) {
this.sideB = sideB;
}
public double getAreaSize() {
return sideA * sideB;
}
}
OOP Abusers Temporary Field
Fields that are only
used once
softwaretester.blog | Benjamin Bischoff
public class Animals {
interface Animal { void speak(); }
static class Dog implements Animal {
@Override
public void speak() {
System.out.println("Woof");
}
}
static class Fish implements Animal {
@Override
public void speak() {
}
}
}
OOP Abusers Refused Bequest
Passing unneeded
behaviour to classes
softwaretester.blog | Benjamin Bischoff
public class Animals {
interface Animal { void speak(); }
static class Dog implements Animal {
@Override
public void speak() {
System.out.println("Woof");
}
}
static class Fish implements Animal {
@Override
public void speak() {
}
}
}
OOP Abusers Refused Bequest
Passing unneeded
behaviour to classes
softwaretester.blog | Benjamin Bischoff
public class Animals {
interface Animal { void speak(); }
static class Dog implements Animal {
@Override
public void speak() {
System.out.println("Woof");
}
}
static class Fish implements Animal {
@Override
public void speak() {
}
}
}
OOP Abusers Refused Bequest
Passing unneeded
behaviour to classes
softwaretester.blog | Benjamin Bischoff
public class Animals {
interface Animal { void speak(); }
static class Dog implements Animal {
@Override
public void speak() {
System.out.println("Woof");
}
}
static class Fish implements Animal {
@Override
public void speak() {
}
}
}
OOP Abusers Refused Bequest
Passing unneeded
behaviour to classes
softwaretester.blog | Benjamin Bischoff
public class Animals {
interface Animal { void speak(); }
static class Dog implements Animal {
@Override
public void speak() {
System.out.println("Woof");
}
}
static class Fish implements Animal {
@Override
public void speak() {
}
}
}
OOP Abusers Refused Bequest
Passing unneeded
behaviour to classes
softwaretester.blog | Benjamin Bischoff
public class Animals {
interface Animal { void speak(); }
static class Dog implements Animal {
@Override
public void speak() {
System.out.println("Woof");
}
}
static class Fish implements Animal {
@Override
public void speak() {
}
}
}
OOP Abusers Refused Bequest
Passing unneeded
behaviour to classes
softwaretester.blog | Benjamin Bischoff
public class Animals {
interface Animal { void speak(); }
static class Dog implements Animal {
@Override
public void speak() {
System.out.println("Woof");
}
}
static class Fish implements Animal {
@Override
public void speak() {
}
}
}
OOP Abusers Refused Bequest
Passing unneeded
behaviour to classes
softwaretester.blog | Benjamin Bischoff
public class Shapes {
record Circle(float radius) {
public double getAreaSize() {
return radius * radius * Math.PI;
}
}
record Rectangle(float a, float b) {
public double getSurfaceSize() {
return a * b;
}
}
}
OOP Abusers Different Interfaces
Confusing naming of
similar functions
softwaretester.blog | Benjamin Bischoff
public class Shapes {
record Circle(float radius) {
public double getAreaSize() {
return radius * radius * Math.PI;
}
}
record Rectangle(float a, float b) {
public double getSurfaceSize() {
return a * b;
}
}
}
OOP Abusers Different Interfaces
Confusing naming of
similar functions
softwaretester.blog | Benjamin Bischoff
public class Shapes {
record Circle(float radius) {
public double getAreaSize() {
return radius * radius * Math.PI;
}
}
record Rectangle(float a, float b) {
public double getSurfaceSize() {
return a * b;
}
}
}
OOP Abusers Different Interfaces
Confusing naming of
similar functions
softwaretester.blog | Benjamin Bischoff
public class Shapes {
record Circle(float radius) {
public double getAreaSize() {
return radius * radius * Math.PI;
}
}
record Rectangle(float a, float b) {
public double getSurfaceSize() {
return a * b;
}
}
}
OOP Abusers Different Interfaces
Confusing naming of
similar functions
softwaretester.blog | Benjamin Bischoff
public class Shapes {
record Circle(float radius) {
public double getAreaSize() {
return radius * radius * Math.PI;
}
}
record Rectangle(float a, float b) {
public double getSurfaceSize() {
return a * b;
}
}
}
OOP Abusers Different Interfaces
Confusing naming of
similar functions
softwaretester.blog | Benjamin Bischoff
Change Preventers
Hindering further development.
softwaretester.blog | Benjamin Bischoff
public class AnimalInformation {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Divergent Change
Changes across
methods
softwaretester.blog | Benjamin Bischoff
public class AnimalInformation {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Divergent Change
Changes across
methods
softwaretester.blog | Benjamin Bischoff
public class AnimalInformation {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Divergent Change
Changes across
methods
softwaretester.blog | Benjamin Bischoff
public class AnimalInformation {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Divergent Change
Changes across
methods
softwaretester.blog | Benjamin Bischoff
public class AnimalInformation {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Divergent Change
Changes across
methods
softwaretester.blog | Benjamin Bischoff
public class Classification {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
}
public class BodyParts {
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Shotgun Surgery
Changes across
classes
softwaretester.blog | Benjamin Bischoff
public class Classification {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
}
public class BodyParts {
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Shotgun Surgery
Changes across
classes
softwaretester.blog | Benjamin Bischoff
public class Classification {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
}
public class BodyParts {
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Shotgun Surgery
Changes across
classes
softwaretester.blog | Benjamin Bischoff
public class Classification {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
}
public class BodyParts {
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Shotgun Surgery
Changes across
classes
softwaretester.blog | Benjamin Bischoff
public class Classification {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
}
public class BodyParts {
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Shotgun Surgery
Changes across
classes
softwaretester.blog | Benjamin Bischoff
public class Classification {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
}
public class BodyParts {
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Shotgun Surgery
Changes across
classes
softwaretester.blog | Benjamin Bischoff
public class Classification {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
}
public class BodyParts {
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Shotgun Surgery
Changes across
classes
softwaretester.blog | Benjamin Bischoff
public class Classification {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
}
public class BodyParts {
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Shotgun Surgery
Changes across
classes
softwaretester.blog | Benjamin Bischoff
public class Classification {
public static String getLatinName(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return "Equus caballus";
return "";
}
}
public class BodyParts {
public static int getNumberOfLegs(final String animal) {
if (animal.equalsIgnoreCase("horse"))
return 4;
return -1;
}
}
Change Preventers Shotgun Surgery
Changes across
classes
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
public class Birds {
private static class Bird {}
private static class Egg {}
private static class Sparrow extends Bird {
private SparrowEgg layEgg() {
return new SparrowEgg();
}
}
private static class SparrowEgg extends Egg {
}
}
Change Preventers Parallel Hierarchy
Implementing
parallel interfaces
softwaretester.blog | Benjamin Bischoff
Dispensables
Unnecessary things that can be removed.
softwaretester.blog | Benjamin Bischoff
public class WebShopCheckOut {
public static void checkOut(final ShoppingCart cart) {
// Some implementation
}
}
record ShoppingCart(Product... products) {
}
record Product(String id) {
}
Dispensables Lazy Class
A class with a single
method
softwaretester.blog | Benjamin Bischoff
public class WebShopCheckOut {
public static void checkOut(final ShoppingCart cart) {
// Some implementation
}
}
record ShoppingCart(Product... products) {
}
record Product(String id) {
}
Dispensables Lazy Class
A class with a single
method
softwaretester.blog | Benjamin Bischoff
public class WebShopCheckOut {
public static void checkOut(final ShoppingCart cart) {
// Some implementation
}
}
record ShoppingCart(Product... products) {
}
record Product(String id) {
}
Dispensables Lazy Class
A class with a single
method
softwaretester.blog | Benjamin Bischoff
public class WebShopCheckOut {
public static void checkOut(final ShoppingCart cart) {
// Some implementation
}
}
record ShoppingCart(Product... products) {
}
record Product(String id) {
}
Dispensables Lazy Class
A class with a single
method
softwaretester.blog | Benjamin Bischoff
public class WebShopCheckOut {
public static void checkOut(final ShoppingCart cart) {
// Some implementation
}
}
record ShoppingCart(Product... products) {
}
record Product(String id) {
}
Dispensables Lazy Class
A class with a single
method
softwaretester.blog | Benjamin Bischoff
public class DataClass {
record Rectangle(int sideA, int sideB) {
}
public static void main(String[] args) {
Rectangle rectangle = new Rectangle(5, 20);
int rectangleArea = rectangle.sideA * rectangle.sideB;
}
}
Dispensables Data Class
Class holding data
but not its own logic
softwaretester.blog | Benjamin Bischoff
public class DataClass {
record Rectangle(int sideA, int sideB) {
}
public static void main(String[] args) {
Rectangle rectangle = new Rectangle(5, 20);
int rectangleArea = rectangle.sideA * rectangle.sideB;
}
}
Dispensables Data Class
Class holding data
but not its own logic
softwaretester.blog | Benjamin Bischoff
public class DataClass {
record Rectangle(int sideA, int sideB) {
}
public static void main(String[] args) {
Rectangle rectangle = new Rectangle(5, 20);
int rectangleArea = rectangle.sideA * rectangle.sideB;
}
}
Dispensables Data Class
Class holding data
but not its own logic
softwaretester.blog | Benjamin Bischoff
public class DataClass {
record Rectangle(int sideA, int sideB) {
}
public static void main(String[] args) {
Rectangle rectangle = new Rectangle(5, 20);
int rectangleArea = rectangle.sideA * rectangle.sideB;
}
}
Dispensables Data Class
Class holding data
but not its own logic
softwaretester.blog | Benjamin Bischoff
public class DataClass {
record Rectangle(int sideA, int sideB) {
}
public static void main(String[] args) {
Rectangle rectangle = new Rectangle(5, 20);
int rectangleArea = rectangle.sideA * rectangle.sideB;
}
}
Dispensables Data Class
Class holding data
but not its own logic
softwaretester.blog | Benjamin Bischoff
public class DataClass {
record Rectangle(int sideA, int sideB) {
}
public static void main(String[] args) {
Rectangle rectangle = new Rectangle(5, 20);
int rectangleArea = rectangle.sideA * rectangle.sideB;
}
}
Dispensables Data Class
Class holding data
but not its own logic
softwaretester.blog | Benjamin Bischoff
public class DataClass {
record Rectangle(int sideA, int sideB) {
}
public static void main(String[] args) {
Rectangle rectangle = new Rectangle(5, 20);
int rectangleArea = rectangle.sideA * rectangle.sideB;
}
}
Dispensables Data Class
Class holding data
but not its own logic
softwaretester.blog | Benjamin Bischoff
public class Customers {
private List<Customer> customers;
public void addCustomer(Customer customer) {
customers.add(customer);
customers.forEach(System.out::println);
}
public void removeCustomer(Customer customer) {
customers.remove(customer);
customers.forEach(System.out::println);
}
}
Dispensables Duplicate Code
The same code
multiple times
softwaretester.blog | Benjamin Bischoff
public class Customers {
private List<Customer> customers;
public void addCustomer(Customer customer) {
customers.add(customer);
customers.forEach(System.out::println);
}
public void removeCustomer(Customer customer) {
customers.remove(customer);
customers.forEach(System.out::println);
}
}
Dispensables Duplicate Code
The same code
multiple times
softwaretester.blog | Benjamin Bischoff
public class Customers {
private List<Customer> customers;
public void addCustomer(Customer customer) {
customers.add(customer);
customers.forEach(System.out::println);
}
public void removeCustomer(Customer customer) {
customers.remove(customer);
customers.forEach(System.out::println);
}
}
Dispensables Duplicate Code
The same code
multiple times
softwaretester.blog | Benjamin Bischoff
public class Customers {
private List<Customer> customers;
public void addCustomer(Customer customer) {
customers.add(customer);
customers.forEach(System.out::println);
}
public void removeCustomer(Customer customer) {
customers.remove(customer);
customers.forEach(System.out::println);
}
}
Dispensables Duplicate Code
The same code
multiple times
softwaretester.blog | Benjamin Bischoff
public class Customers {
private List<Customer> customers;
public void addCustomer(Customer customer) {
customers.add(customer);
customers.forEach(System.out::println);
}
public void removeCustomer(Customer customer) {
customers.remove(customer);
customers.forEach(System.out::println);
}
}
Dispensables Duplicate Code
The same code
multiple times
softwaretester.blog | Benjamin Bischoff
public class DeadCode {
public static void main(String[] args) {
System.out.println("Pi = " + Math.PI);
}
private double getPi() {
return 3.141592;
System.out.println("Returning Pi");
}
}
Dispensables Dead Code
Code that cannot be
reached
softwaretester.blog | Benjamin Bischoff
public class DeadCode {
public static void main(String[] args) {
System.out.println("Pi = " + Math.PI);
}
private double getPi() {
return 3.141592;
System.out.println("Returning Pi");
}
}
Dispensables Dead Code
Code that cannot be
reached
softwaretester.blog | Benjamin Bischoff
public class DeadCode {
public static void main(String[] args) {
System.out.println("Pi = " + Math.PI);
}
private double getPi() {
return 3.141592;
System.out.println("Returning Pi");
}
}
Dispensables Dead Code
Code that cannot be
reached
softwaretester.blog | Benjamin Bischoff
public class DeadCode {
public static void main(String[] args) {
System.out.println("Pi = " + Math.PI);
}
private double getPi() {
return 3.141592;
System.out.println("Returning Pi");
}
}
Dispensables Dead Code
Code that cannot be
reached
softwaretester.blog | Benjamin Bischoff
public class DeadCode {
public static void main(String[] args) {
System.out.println("Pi = " + Math.PI);
}
private double getPi() {
return 3.141592;
System.out.println("Returning Pi");
}
}
Dispensables Dead Code
Code that cannot be
reached
softwaretester.blog | Benjamin Bischoff
public class DeadCode {
public static void main(String[] args) {
System.out.println("Pi = " + Math.PI);
}
private double getPi() {
return 3.141592;
System.out.println("Returning Pi");
}
}
Dispensables Dead Code
Code that cannot be
reached
softwaretester.blog | Benjamin Bischoff
public class DeadCode {
public static void main(String[] args) {
System.out.println("Pi = " + Math.PI);
}
private double getPi() {
return 3.141592;
System.out.println("Returning Pi");
}
}
Dispensables Dead Code
Code that cannot be
reached
softwaretester.blog | Benjamin Bischoff
public class LaserPrinter implements Printer {
@Override
public void print(final String textToPrint) {
// Implementation
}
@Override
public void turnOnOrOff() {
//Implementation
}
}
interface Printer {
void print(String textToPrint);
void turnOnOrOff();
}
Dispensables Speculative Generality
Premature future-
proo
fi
ng
softwaretester.blog | Benjamin Bischoff
public class LaserPrinter implements Printer {
@Override
public void print(final String textToPrint) {
// Implementation
}
@Override
public void turnOnOrOff() {
//Implementation
}
}
interface Printer {
void print(String textToPrint);
void turnOnOrOff();
}
Dispensables Speculative Generality
Premature future-
proo
fi
ng
softwaretester.blog | Benjamin Bischoff
public class LaserPrinter implements Printer {
@Override
public void print(final String textToPrint) {
// Implementation
}
@Override
public void turnOnOrOff() {
//Implementation
}
}
interface Printer {
void print(String textToPrint);
void turnOnOrOff();
}
Dispensables Speculative Generality
Premature future-
proo
fi
ng
softwaretester.blog | Benjamin Bischoff
public class LaserPrinter implements Printer {
@Override
public void print(final String textToPrint) {
// Implementation
}
@Override
public void turnOnOrOff() {
//Implementation
}
}
interface Printer {
void print(String textToPrint);
void turnOnOrOff();
}
Dispensables Speculative Generality
Premature future-
proo
fi
ng
softwaretester.blog | Benjamin Bischoff
public class LaserPrinter implements Printer {
@Override
public void print(final String textToPrint) {
// Implementation
}
@Override
public void turnOnOrOff() {
//Implementation
}
}
interface Printer {
void print(String textToPrint);
void turnOnOrOff();
}
Dispensables Speculative Generality
Premature future-
proo
fi
ng
softwaretester.blog | Benjamin Bischoff
public class LaserPrinter implements Printer {
@Override
public void print(final String textToPrint) {
// Implementation
}
@Override
public void turnOnOrOff() {
//Implementation
}
}
interface Printer {
void print(String textToPrint);
void turnOnOrOff();
}
Dispensables Speculative Generality
Premature future-
proo
fi
ng
softwaretester.blog | Benjamin Bischoff
public class LaserPrinter implements Printer {
@Override
public void print(final String textToPrint) {
// Implementation
}
@Override
public void turnOnOrOff() {
//Implementation
}
}
interface Printer {
void print(String textToPrint);
void turnOnOrOff();
}
Dispensables Speculative Generality
Premature future-
proo
fi
ng
softwaretester.blog | Benjamin Bischoff
Couplers
Too much or too little coupling.
softwaretester.blog | Benjamin Bischoff
public class UsersAndAddresses {
record User(Address address) {
public String getAddressString() {
return
address.street() + ", "
+ address.city() + ", "
+ address.country();
}
}
record Address(String street, String city, String country) { }
}
Couplers Feature Envy
Class implementing
features of another
softwaretester.blog | Benjamin Bischoff
public class UsersAndAddresses {
record User(Address address) {
public String getAddressString() {
return
address.street() + ", "
+ address.city() + ", "
+ address.country();
}
}
record Address(String street, String city, String country) { }
}
Couplers Feature Envy
Class implementing
features of another
softwaretester.blog | Benjamin Bischoff
public class UsersAndAddresses {
record User(Address address) {
public String getAddressString() {
return
address.street() + ", "
+ address.city() + ", "
+ address.country();
}
}
record Address(String street, String city, String country) { }
}
Couplers Feature Envy
Class implementing
features of another
softwaretester.blog | Benjamin Bischoff
public class UsersAndAddresses {
record User(Address address) {
public String getAddressString() {
return
address.street() + ", "
+ address.city() + ", "
+ address.country();
}
}
record Address(String street, String city, String country) { }
}
Couplers Feature Envy
Class implementing
features of another
softwaretester.blog | Benjamin Bischoff
public class UsersAndAddresses {
record User(Address address) {
public String getAddressString() {
return
address.street() + ", "
+ address.city() + ", "
+ address.country();
}
}
record Address(String street, String city, String country) { }
}
Couplers Feature Envy
Class implementing
features of another
softwaretester.blog | Benjamin Bischoff
public class Book {
private final String title;
private Author author;
public Book(String title) { this.title = title;}
public void setAuthor(Author author) { this.author = author; }
}
public class Author {
private final String name;
private Book book;
public Author(String name) { this.name = name; }
public void setBook(Book book) { this.book = book; }
}
Couplers Inappropriate Intimacy
Classes knowing
each other too well
softwaretester.blog | Benjamin Bischoff
public class Book {
private final String title;
private Author author;
public Book(String title) { this.title = title;}
public void setAuthor(Author author) { this.author = author; }
}
public class Author {
private final String name;
private Book book;
public Author(String name) { this.name = name; }
public void setBook(Book book) { this.book = book; }
}
Couplers Inappropriate Intimacy
Classes knowing
each other too well
softwaretester.blog | Benjamin Bischoff
public class Book {
private final String title;
private Author author;
public Book(String title) { this.title = title;}
public void setAuthor(Author author) { this.author = author; }
}
public class Author {
private final String name;
private Book book;
public Author(String name) { this.name = name; }
public void setBook(Book book) { this.book = book; }
}
Couplers Inappropriate Intimacy
Classes knowing
each other too well
softwaretester.blog | Benjamin Bischoff
public class Book {
private final String title;
private Author author;
public Book(String title) { this.title = title;}
public void setAuthor(Author author) { this.author = author; }
}
public class Author {
private final String name;
private Book book;
public Author(String name) { this.name = name; }
public void setBook(Book book) { this.book = book; }
}
Couplers Inappropriate Intimacy
Classes knowing
each other too well
softwaretester.blog | Benjamin Bischoff
public class Book {
private final String title;
private Author author;
public Book(String title) { this.title = title;}
public void setAuthor(Author author) { this.author = author; }
}
public class Author {
private final String name;
private Book book;
public Author(String name) { this.name = name; }
public void setBook(Book book) { this.book = book; }
}
Couplers Inappropriate Intimacy
Classes knowing
each other too well
softwaretester.blog | Benjamin Bischoff
public class Book {
private final String title;
private Author author;
public Book(String title) { this.title = title;}
public void setAuthor(Author author) { this.author = author; }
}
public class Author {
private final String name;
private Book book;
public Author(String name) { this.name = name; }
public void setBook(Book book) { this.book = book; }
}
Couplers Inappropriate Intimacy
Classes knowing
each other too well
softwaretester.blog | Benjamin Bischoff
public class Book {
private final String title;
private Author author;
public Book(String title) { this.title = title;}
public void setAuthor(Author author) { this.author = author; }
}
public class Author {
private final String name;
private Book book;
public Author(String name) { this.name = name; }
public void setBook(Book book) { this.book = book; }
}
Couplers Inappropriate Intimacy
Classes knowing
each other too well
softwaretester.blog | Benjamin Bischoff
public class Book {
private final String title;
private Author author;
public Book(String title) { this.title = title;}
public void setAuthor(Author author) { this.author = author; }
}
public class Author {
private final String name;
private Book book;
public Author(String name) { this.name = name; }
public void setBook(Book book) { this.book = book; }
}
Couplers Inappropriate Intimacy
Classes knowing
each other too well
softwaretester.blog | Benjamin Bischoff
public class Book {
private final String title;
private Author author;
public Book(String title) { this.title = title;}
public void setAuthor(Author author) { this.author = author; }
}
public class Author {
private final String name;
private Book book;
public Author(String name) { this.name = name; }
public void setBook(Book book) { this.book = book; }
}
Couplers Inappropriate Intimacy
Classes knowing
each other too well
softwaretester.blog | Benjamin Bischoff
public class Storehouse {
public static void main(String[] args) {
List<Product> products = List.of(
new Product("Cheese", "Tasty cheese"));
List<Shelf> shelves = List.of(new Shelf(products));
String description =
shelves.get(0).products().get(0).description();
}
record Shelf(List<Product> products) { }
record Product(String name, String description) { }
}
Couplers Message Chains
Returning objects
that return objects…
softwaretester.blog | Benjamin Bischoff
public class Storehouse {
public static void main(String[] args) {
List<Product> products = List.of(
new Product("Cheese", "Tasty cheese"));
List<Shelf> shelves = List.of(new Shelf(products));
String description =
shelves.get(0).products().get(0).description();
}
record Shelf(List<Product> products) { }
record Product(String name, String description) { }
}
Couplers Message Chains
Returning objects
that return objects…
softwaretester.blog | Benjamin Bischoff
public class Storehouse {
public static void main(String[] args) {
List<Product> products = List.of(
new Product("Cheese", "Tasty cheese"));
List<Shelf> shelves = List.of(new Shelf(products));
String description =
shelves.get(0).products().get(0).description();
}
record Shelf(List<Product> products) { }
record Product(String name, String description) { }
}
Couplers Message Chains
Returning objects
that return objects…
softwaretester.blog | Benjamin Bischoff
public record Customer(String name, Address address) {
public String getCity() {
return address.city();
}
public String getStreet() {
return address.street();
}
record Address(String street, String city) { }
}
Dispensables Middle Man
Class accessing
another one on its
behalf
softwaretester.blog | Benjamin Bischoff
public record Customer(String name, Address address) {
public String getCity() {
return address.city();
}
public String getStreet() {
return address.street();
}
record Address(String street, String city) { }
}
Dispensables Middle Man
Class accessing
another one on its
behalf
softwaretester.blog | Benjamin Bischoff
public record Customer(String name, Address address) {
public String getCity() {
return address.city();
}
public String getStreet() {
return address.street();
}
record Address(String street, String city) { }
}
Dispensables Middle Man
Class accessing
another one on its
behalf
softwaretester.blog | Benjamin Bischoff
public record Customer(String name, Address address) {
public String getCity() {
return address.city();
}
public String getStreet() {
return address.street();
}
record Address(String street, String city) { }
}
Dispensables Middle Man
Class accessing
another one on its
behalf
softwaretester.blog | Benjamin Bischoff
public record Customer(String name, Address address) {
public String getCity() {
return address.city();
}
public String getStreet() {
return address.street();
}
record Address(String street, String city) { }
}
Dispensables Middle Man
Class accessing
another one on its
behalf
softwaretester.blog | Benjamin Bischoff
Classi
fi
cation
Bloaters
OOP
Abusers
Change
Preventers
Dispensables Couplers
Long Method
Large Class
Primitive
Obsession
Long Parameter
List
Data Clumps
Switch Statements
Temporary
Field
Refused
Bequest
Alternative classes
with di
ff
erent
Interfaces
Divergent Change
Shotgun Surgery
Parallel Inheritance
Hierarchy
Lazy Class
Data Class
Duplicate Code
Dead Code
Speculative
Generality
Feature Envy
Inappropriate
Intimacy
Message Chains
Middleman
softwaretester.blog | Benjamin Bischoff
Example Code
github.com/bischoffdev/code-smells
softwaretester.blog | Benjamin Bischoff
When to tackle code smells?
softwaretester.blog | Benjamin Bischoff
Broken window
Long-term effects of un
fi
xed
code.
softwaretester.blog | Benjamin Bischoff
YAGNI
Wasting time with future
requirements.
softwaretester.blog | Benjamin Bischoff
Campground Rule
Later never comes…
softwaretester.blog | Benjamin Bischoff
Code Reviews
Point out smells before it is too
late!
softwaretester.blog | Benjamin Bischoff
More information
softwaretester.blog | Benjamin Bischoff
Refactoring catalog
refactoring.com/catalog
softwaretester.blog | Benjamin Bischoff
Refactoring Guru
refactoring.guru/refactoring
softwaretester.blog | Benjamin Bischoff
Marcel Jerzyk
luzkan.github.io/smells/
softwaretester.blog | Benjamin Bischoff
Smelly Code
Smelly code, smelly code
How are they treating you?
Smelly code, smelly code
It’s not your fault.
softwaretester.blog | Benjamin Bischoff
Thank you!
softwaretester.blog | Benjamin Bischoff
Thank you!

More Related Content

Similar to Identifying Code Smells

Refactoring domain driven design way
Refactoring domain driven design wayRefactoring domain driven design way
Refactoring domain driven design wayAndi Pangeran
 
Do you really need a Child Theme?
Do you really need a Child Theme?Do you really need a Child Theme?
Do you really need a Child Theme?pixolin
 
Html Server Input Checkbox Control VB
Html Server Input Checkbox Control VBHtml Server Input Checkbox Control VB
Html Server Input Checkbox Control VBsunmitraeducation
 
MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system Tarin Gamberini
 
PT1420 Decision Structures in Pseudocode and Visual Basic .docx
PT1420 Decision Structures in Pseudocode and Visual Basic .docxPT1420 Decision Structures in Pseudocode and Visual Basic .docx
PT1420 Decision Structures in Pseudocode and Visual Basic .docxamrit47
 
C#7, 7.1, 7.2, 7.3 e C# 8
C#7, 7.1, 7.2, 7.3 e C# 8C#7, 7.1, 7.2, 7.3 e C# 8
C#7, 7.1, 7.2, 7.3 e C# 8Giovanni Bassi
 
Microservices Chaos Testing at Jet
Microservices Chaos Testing at JetMicroservices Chaos Testing at Jet
Microservices Chaos Testing at JetC4Media
 
How do you create a programming language for the JVM?
How do you create a programming language for the JVM?How do you create a programming language for the JVM?
How do you create a programming language for the JVM?Federico Tomassetti
 
Cis 115 Education Redefined-snaptutorial.com
Cis 115 Education Redefined-snaptutorial.comCis 115 Education Redefined-snaptutorial.com
Cis 115 Education Redefined-snaptutorial.comrobertledwes38
 
Cis 170 c ilab 5 of 7 arrays and strings
Cis 170 c ilab 5 of 7 arrays and stringsCis 170 c ilab 5 of 7 arrays and strings
Cis 170 c ilab 5 of 7 arrays and stringsCIS321
 
Automatically Assessing Code Understandability: How Far Are We?
Automatically Assessing Code Understandability: How Far Are We?Automatically Assessing Code Understandability: How Far Are We?
Automatically Assessing Code Understandability: How Far Are We?sscalabrino
 
Devry cis 170 c i lab 5 of 7 arrays and strings
Devry cis 170 c i lab 5 of 7 arrays and stringsDevry cis 170 c i lab 5 of 7 arrays and strings
Devry cis 170 c i lab 5 of 7 arrays and stringsjody zoll
 
Code quailty metrics demystified
Code quailty metrics demystifiedCode quailty metrics demystified
Code quailty metrics demystifiedJeroen Resoort
 
Week 8
Week 8Week 8
Week 8A VD
 
The case for consumer-driven contracts
The case for consumer-driven contractsThe case for consumer-driven contracts
The case for consumer-driven contractsDiUS
 
Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)Sameer Rathoud
 
Annotation processor and compiler plugin
Annotation processor and compiler pluginAnnotation processor and compiler plugin
Annotation processor and compiler pluginOleksandr Radchykov
 

Similar to Identifying Code Smells (20)

Refactoring domain driven design way
Refactoring domain driven design wayRefactoring domain driven design way
Refactoring domain driven design way
 
visualbasic.ppt
visualbasic.pptvisualbasic.ppt
visualbasic.ppt
 
Bot builder v4 HOL
Bot builder v4 HOLBot builder v4 HOL
Bot builder v4 HOL
 
Do you really need a Child Theme?
Do you really need a Child Theme?Do you really need a Child Theme?
Do you really need a Child Theme?
 
Html Server Input Checkbox Control VB
Html Server Input Checkbox Control VBHtml Server Input Checkbox Control VB
Html Server Input Checkbox Control VB
 
MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system MUTANTS KILLER - PIT: state of the art of mutation testing system
MUTANTS KILLER - PIT: state of the art of mutation testing system
 
PT1420 Decision Structures in Pseudocode and Visual Basic .docx
PT1420 Decision Structures in Pseudocode and Visual Basic .docxPT1420 Decision Structures in Pseudocode and Visual Basic .docx
PT1420 Decision Structures in Pseudocode and Visual Basic .docx
 
C#7, 7.1, 7.2, 7.3 e C# 8
C#7, 7.1, 7.2, 7.3 e C# 8C#7, 7.1, 7.2, 7.3 e C# 8
C#7, 7.1, 7.2, 7.3 e C# 8
 
Microservices Chaos Testing at Jet
Microservices Chaos Testing at JetMicroservices Chaos Testing at Jet
Microservices Chaos Testing at Jet
 
How do you create a programming language for the JVM?
How do you create a programming language for the JVM?How do you create a programming language for the JVM?
How do you create a programming language for the JVM?
 
Cis 115 Education Redefined-snaptutorial.com
Cis 115 Education Redefined-snaptutorial.comCis 115 Education Redefined-snaptutorial.com
Cis 115 Education Redefined-snaptutorial.com
 
Cis 170 c ilab 5 of 7 arrays and strings
Cis 170 c ilab 5 of 7 arrays and stringsCis 170 c ilab 5 of 7 arrays and strings
Cis 170 c ilab 5 of 7 arrays and strings
 
Automatically Assessing Code Understandability: How Far Are We?
Automatically Assessing Code Understandability: How Far Are We?Automatically Assessing Code Understandability: How Far Are We?
Automatically Assessing Code Understandability: How Far Are We?
 
Devry cis 170 c i lab 5 of 7 arrays and strings
Devry cis 170 c i lab 5 of 7 arrays and stringsDevry cis 170 c i lab 5 of 7 arrays and strings
Devry cis 170 c i lab 5 of 7 arrays and strings
 
Code quailty metrics demystified
Code quailty metrics demystifiedCode quailty metrics demystified
Code quailty metrics demystified
 
Week 8
Week 8Week 8
Week 8
 
The case for consumer-driven contracts
The case for consumer-driven contractsThe case for consumer-driven contracts
The case for consumer-driven contracts
 
Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)Factory method pattern (Virtual Constructor)
Factory method pattern (Virtual Constructor)
 
Java day 2016.pptx
Java day 2016.pptxJava day 2016.pptx
Java day 2016.pptx
 
Annotation processor and compiler plugin
Annotation processor and compiler pluginAnnotation processor and compiler plugin
Annotation processor and compiler plugin
 

More from Benjamin Bischoff

Public Speaking and Procrastination
Public Speaking and ProcrastinationPublic Speaking and Procrastination
Public Speaking and ProcrastinationBenjamin Bischoff
 
Simplifying your test runs with „Make“
Simplifying your test runs with „Make“Simplifying your test runs with „Make“
Simplifying your test runs with „Make“Benjamin Bischoff
 
Of plugins and decorators - trivago's e2e test framework in the spotlight
Of plugins and decorators - trivago's e2e test framework in the spotlightOf plugins and decorators - trivago's e2e test framework in the spotlight
Of plugins and decorators - trivago's e2e test framework in the spotlightBenjamin Bischoff
 
The Bumpy Road Towards Continuous Delivery
The Bumpy Road Towards Continuous DeliveryThe Bumpy Road Towards Continuous Delivery
The Bumpy Road Towards Continuous DeliveryBenjamin Bischoff
 

More from Benjamin Bischoff (7)

Public Speaking and Procrastination
Public Speaking and ProcrastinationPublic Speaking and Procrastination
Public Speaking and Procrastination
 
Simplifying your test runs with „Make“
Simplifying your test runs with „Make“Simplifying your test runs with „Make“
Simplifying your test runs with „Make“
 
All about Cluecumber
All about CluecumberAll about Cluecumber
All about Cluecumber
 
The Road to QA
The Road to QAThe Road to QA
The Road to QA
 
Smoke tests and mirrors
Smoke tests and mirrorsSmoke tests and mirrors
Smoke tests and mirrors
 
Of plugins and decorators - trivago's e2e test framework in the spotlight
Of plugins and decorators - trivago's e2e test framework in the spotlightOf plugins and decorators - trivago's e2e test framework in the spotlight
Of plugins and decorators - trivago's e2e test framework in the spotlight
 
The Bumpy Road Towards Continuous Delivery
The Bumpy Road Towards Continuous DeliveryThe Bumpy Road Towards Continuous Delivery
The Bumpy Road Towards Continuous Delivery
 

Recently uploaded

Microsoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdfMicrosoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdfMarkus Moeller
 
Software Engineering - Introduction + Process Models + Requirements Engineering
Software Engineering - Introduction + Process Models + Requirements EngineeringSoftware Engineering - Introduction + Process Models + Requirements Engineering
Software Engineering - Introduction + Process Models + Requirements EngineeringPrakhyath Rai
 
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
Workshop -  Architecting Innovative Graph Applications- GraphSummit MilanWorkshop -  Architecting Innovative Graph Applications- GraphSummit Milan
Workshop - Architecting Innovative Graph Applications- GraphSummit MilanNeo4j
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletAndrea Goulet
 
Test Automation Design Patterns_ A Comprehensive Guide.pdf
Test Automation Design Patterns_ A Comprehensive Guide.pdfTest Automation Design Patterns_ A Comprehensive Guide.pdf
Test Automation Design Patterns_ A Comprehensive Guide.pdfkalichargn70th171
 
The Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationThe Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationElement34
 
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...Flutter Agency
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AIAGATSoftware
 
Evolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI EraEvolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI Eraconfluent
 
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024SimonedeGijt
 
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4jGraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4jNeo4j
 
From Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIFrom Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIInflectra
 
Novo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMsNovo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMsNeo4j
 
Transformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksTransformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksJinanKordab
 
GraphSummit Milan - Neo4j: The Art of the Possible with Graph
GraphSummit Milan - Neo4j: The Art of the Possible with GraphGraphSummit Milan - Neo4j: The Art of the Possible with Graph
GraphSummit Milan - Neo4j: The Art of the Possible with GraphNeo4j
 
Effective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeConEffective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeConNatan Silnitsky
 
architecting-ai-in-the-enterprise-apis-and-applications.pdf
architecting-ai-in-the-enterprise-apis-and-applications.pdfarchitecting-ai-in-the-enterprise-apis-and-applications.pdf
architecting-ai-in-the-enterprise-apis-and-applications.pdfWSO2
 

Recently uploaded (20)

Microsoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdfMicrosoft365_Dev_Security_2024_05_16.pdf
Microsoft365_Dev_Security_2024_05_16.pdf
 
Software Engineering - Introduction + Process Models + Requirements Engineering
Software Engineering - Introduction + Process Models + Requirements EngineeringSoftware Engineering - Introduction + Process Models + Requirements Engineering
Software Engineering - Introduction + Process Models + Requirements Engineering
 
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
Workshop -  Architecting Innovative Graph Applications- GraphSummit MilanWorkshop -  Architecting Innovative Graph Applications- GraphSummit Milan
Workshop - Architecting Innovative Graph Applications- GraphSummit Milan
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea Goulet
 
Test Automation Design Patterns_ A Comprehensive Guide.pdf
Test Automation Design Patterns_ A Comprehensive Guide.pdfTest Automation Design Patterns_ A Comprehensive Guide.pdf
Test Automation Design Patterns_ A Comprehensive Guide.pdf
 
The Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationThe Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test Automation
 
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
Navigation in flutter – how to add stack, tab, and drawer navigators to your ...
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AI
 
Evolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI EraEvolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI Era
 
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
 
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4jGraphSummit Milan - Visione e roadmap del prodotto Neo4j
GraphSummit Milan - Visione e roadmap del prodotto Neo4j
 
Abortion Pill Prices Mthatha (@](+27832195400*)[ 🏥 Women's Abortion Clinic In...
Abortion Pill Prices Mthatha (@](+27832195400*)[ 🏥 Women's Abortion Clinic In...Abortion Pill Prices Mthatha (@](+27832195400*)[ 🏥 Women's Abortion Clinic In...
Abortion Pill Prices Mthatha (@](+27832195400*)[ 🏥 Women's Abortion Clinic In...
 
From Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIFrom Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST API
 
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
Abortion Pill Prices Germiston ](+27832195400*)[ 🏥 Women's Abortion Clinic in...
 
Novo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMsNovo Nordisk: When Knowledge Graphs meet LLMs
Novo Nordisk: When Knowledge Graphs meet LLMs
 
Transformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksTransformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with Links
 
GraphSummit Milan - Neo4j: The Art of the Possible with Graph
GraphSummit Milan - Neo4j: The Art of the Possible with GraphGraphSummit Milan - Neo4j: The Art of the Possible with Graph
GraphSummit Milan - Neo4j: The Art of the Possible with Graph
 
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
Abortion Clinic In Pretoria ](+27832195400*)[ 🏥 Safe Abortion Pills in Pretor...
 
Effective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeConEffective Strategies for Wix's Scaling challenges - GeeCon
Effective Strategies for Wix's Scaling challenges - GeeCon
 
architecting-ai-in-the-enterprise-apis-and-applications.pdf
architecting-ai-in-the-enterprise-apis-and-applications.pdfarchitecting-ai-in-the-enterprise-apis-and-applications.pdf
architecting-ai-in-the-enterprise-apis-and-applications.pdf
 

Identifying Code Smells

  • 1. softwaretester.blog | Benjamin Bischoff TestCon Europe 2023 Identifying Code Smells
  • 2. softwaretester.blog | Benjamin Bischoff Law of Two Feet • If this is not for you, please don’t stay! • I mean it! • Really!
  • 3. softwaretester.blog | Benjamin Bischoff About me • Benjamin Bischoff • Test Automation Engineer @ trivago N.V. • 23 years in IT • Last 8 years in testing
  • 4. softwaretester.blog | Benjamin Bischoff I wrote a book • “Writing API Tests with Karate” • Available since 05/2023 • Packt Publishing
  • 5. softwaretester.blog | Benjamin Bischoff I wrote a book • “Writing API Tests with Karate” • Available since 05/2023 • Packt Publishing
  • 6. softwaretester.blog | Benjamin Bischoff Disclaimer • This is only about identi fi cation • Lots of code • All Java
  • 7. softwaretester.blog | Benjamin Bischoff Smelly Code Smelly code, smelly code How are they treating you? Smelly code, smelly code It’s not your fault.
  • 8. softwaretester.blog | Benjamin Bischoff The term
  • 9. softwaretester.blog | Benjamin Bischoff The term
  • 10. softwaretester.blog | Benjamin Bischoff –Martin Fowler „A code smell is a surface indication that usually corresponds to a deeper problem in the system.“
  • 11. softwaretester.blog | Benjamin Bischoff Why should you care? • Communication Speak a common language • A step towards better code Clean code principles and design patterns • Less technical debt Clean code principles and design patterns • Testability Testable code is maintainable code!
  • 12. softwaretester.blog | Benjamin Bischoff TAXONOMY OF CODE SMELLS Mika V. Mäntylä & Casper Lassenius, Helsinki University of Technology
  • 13. softwaretester.blog | Benjamin Bischoff TAXONOMY OF CODE SMELLS Mika V. Mäntylä & Casper Lassenius, Helsinki University of Technology
  • 14. softwaretester.blog | Benjamin Bischoff Classi fi cation
  • 15. softwaretester.blog | Benjamin Bischoff Classi fi cation Bloaters Long Method Large Class Primitive Obsession Long Parameter List Data Clumps OOP Abusers Switch Statements Temporary Field Refused Bequest Alternative classes with di ff erent Interfaces Change Preventers Divergent Change Shotgun Surgery Parallel Inheritance Hierarchy Dispensables Lazy Class Data Class Duplicate Code Dead Code Speculative Generality Couplers Feature Envy Inappropriate Intimacy Message Chains Middleman
  • 16. softwaretester.blog | Benjamin Bischoff Bloaters Too large to handle.
  • 17. softwaretester.blog | Benjamin Bischoff public class WebShop { private final List<Customer> customers = new ArrayList<>(); public String saveCustomer(final Customer customer) { customers.add(customer); return String.format( "We have a new customer called %", customer.name()); } } Bloaters Long Method A method that does too much
  • 18. softwaretester.blog | Benjamin Bischoff public class WebShop { private final List<Customer> customers = new ArrayList<>(); public String saveCustomer(final Customer customer) { customers.add(customer); return String.format( "We have a new customer called %", customer.name()); } } Bloaters Long Method A method that does too much
  • 19. softwaretester.blog | Benjamin Bischoff public class WebShop { private final List<Customer> customers = new ArrayList<>(); public String saveCustomer(final Customer customer) { customers.add(customer); return String.format( "We have a new customer called %", customer.name()); } } Bloaters Long Method A method that does too much
  • 20. softwaretester.blog | Benjamin Bischoff public class WebShop { private final List<Customer> customers = new ArrayList<>(); public String saveCustomer(final Customer customer) { customers.add(customer); return String.format( "We have a new customer called %", customer.name()); } } Bloaters Long Method A method that does too much
  • 21. softwaretester.blog | Benjamin Bischoff public class WebShop { private final List<Customer> customers = new ArrayList<>(); public String saveCustomer(final Customer customer) { customers.add(customer); return String.format( "We have a new customer called %", customer.name()); } } Bloaters Long Method A method that does too much
  • 22. softwaretester.blog | Benjamin Bischoff public class ShoppingCart { public void addProduct(final Product product) {} public void removeProduct(final Product product) {} public void checkOut() {} public void enterVoucherCode() {} public void contactSupport() {} } Bloaters Large Class A class that does too much
  • 23. softwaretester.blog | Benjamin Bischoff public class ShoppingCart { public void addProduct(final Product product) {} public void removeProduct(final Product product) {} public void checkOut() {} public void enterVoucherCode() {} public void contactSupport() {} } Bloaters Large Class A class that does too much
  • 24. softwaretester.blog | Benjamin Bischoff public class ShoppingCart { public void addProduct(final Product product) {} public void removeProduct(final Product product) {} public void checkOut() {} public void enterVoucherCode() {} public void contactSupport() {} } Bloaters Large Class A class that does too much
  • 25. softwaretester.blog | Benjamin Bischoff public class ShoppingCart { public void addProduct(final Product product) {} public void removeProduct(final Product product) {} public void checkOut() {} public void enterVoucherCode() {} public void contactSupport() {} } Bloaters Large Class A class that does too much
  • 26. softwaretester.blog | Benjamin Bischoff public class ShoppingCart { public void addProduct(final Product product) {} public void removeProduct(final Product product) {} public void checkOut() {} public void enterVoucherCode() {} public void contactSupport() {} } Bloaters Large Class A class that does too much
  • 27. softwaretester.blog | Benjamin Bischoff record Customer( String name, int age, String street, String city, int zipCode, String country ) { } Bloaters Primitive Obsession Favouring primitive data types
  • 28. softwaretester.blog | Benjamin Bischoff record Customer( String name, int age, String street, String city, int zipCode, String country ) { } Bloaters Primitive Obsession Favouring primitive data types
  • 29. softwaretester.blog | Benjamin Bischoff record Customer( String name, int age, String street, String city, int zipCode, String country ) { } Bloaters Primitive Obsession Favouring primitive data types
  • 30. softwaretester.blog | Benjamin Bischoff public class CadTool { public static void main(String[] args) { int result = CadTool.calculateResult(13, false, true, -1, null); } public static int calculateResult(final int baseValue, final boolean isMetric, final boolean is2D, final int offset, final Integer height) { return 0; // some calculation } } Bloaters Long Parameter List Too many method parameters
  • 31. softwaretester.blog | Benjamin Bischoff public class CadTool { public static void main(String[] args) { int result = CadTool.calculateResult(13, false, true, -1, null); } public static int calculateResult(final int baseValue, final boolean isMetric, final boolean is2D, final int offset, final Integer height) { return 0; // some calculation } } Bloaters Long Parameter List Too many method parameters
  • 32. softwaretester.blog | Benjamin Bischoff public class CadTool { public static void main(String[] args) { int result = CadTool.calculateResult(13, false, true, -1, null); } public static int calculateResult(final int baseValue, final boolean isMetric, final boolean is2D, final int offset, final Integer height) { return 0; // some calculation } } Bloaters Long Parameter List Too many method parameters
  • 33. softwaretester.blog | Benjamin Bischoff public class CadTool { public static void main(String[] args) { int result = CadTool.calculateResult(13, false, true, -1, null); } public static int calculateResult(final int baseValue, final boolean isMetric, final boolean is2D, final int offset, final Integer height) { return 0; // some calculation } } Bloaters Long Parameter List Too many method parameters
  • 34. softwaretester.blog | Benjamin Bischoff public class CadTool { public static void main(String[] args) { int result = CadTool.calculateResult(13, false, true, -1, null); } public static int calculateResult(final int baseValue, final boolean isMetric, final boolean is2D, final int offset, final Integer height) { return 0; // some calculation } } Bloaters Long Parameter List Too many method parameters
  • 35. softwaretester.blog | Benjamin Bischoff record Customer( String lastName, String firstName, String middleName, String salutation, String streetAddress, String city, String state, String country, boolean isEmployed, boolean isHomeOwner ) { } Bloaters Data Clumps Grouping unrelated data
  • 36. softwaretester.blog | Benjamin Bischoff record Customer( String lastName, String firstName, String middleName, String salutation, String streetAddress, String city, String state, String country, boolean isEmployed, boolean isHomeOwner ) { } Bloaters Data Clumps Grouping unrelated data
  • 37. softwaretester.blog | Benjamin Bischoff record Customer( String lastName, String firstName, String middleName, String salutation, String streetAddress, String city, String state, String country, boolean isEmployed, boolean isHomeOwner ) { } Bloaters Data Clumps Grouping unrelated data
  • 38. softwaretester.blog | Benjamin Bischoff record Customer( String lastName, String firstName, String middleName, String salutation, String streetAddress, String city, String state, String country, boolean isEmployed, boolean isHomeOwner ) { } Bloaters Data Clumps Grouping unrelated data
  • 39. softwaretester.blog | Benjamin Bischoff record Customer( String lastName, String firstName, String middleName, String salutation, String streetAddress, String city, String state, String country, boolean isEmployed, boolean isHomeOwner ) { } Bloaters Data Clumps Grouping unrelated data
  • 40. softwaretester.blog | Benjamin Bischoff record Customer( String lastName, String firstName, String middleName, String salutation, String streetAddress, String city, String state, String country, boolean isEmployed, boolean isHomeOwner ) { } Bloaters Data Clumps Grouping unrelated data
  • 41. softwaretester.blog | Benjamin Bischoff record Customer( String lastName, String firstName, String middleName, String salutation, String streetAddress, String city, String state, String country, boolean isEmployed, boolean isHomeOwner ) { } Bloaters Data Clumps Grouping unrelated data
  • 42. softwaretester.blog | Benjamin Bischoff OOP Abusers Missing object-oriented design possibilities.
  • 43. softwaretester.blog | Benjamin Bischoff public class Vehicles { public int numberOfWheels(final String vehicle) throws Exception { return switch (vehicle) { case "car" -> 4; case "boat" -> 0; case "bike" -> 2; case "bicycle" -> 2; default -> throw new Exception("Unknown"); }; } } OOP Abusers Switch Statements Branching out too much
  • 44. softwaretester.blog | Benjamin Bischoff public class Vehicles { public int numberOfWheels(final String vehicle) throws Exception { return switch (vehicle) { case "car" -> 4; case "boat" -> 0; case "bike" -> 2; case "bicycle" -> 2; default -> throw new Exception("Unknown"); }; } } OOP Abusers Switch Statements Branching out too much
  • 45. softwaretester.blog | Benjamin Bischoff public class Vehicles { public int numberOfWheels(final String vehicle) throws Exception { return switch (vehicle) { case "car" -> 4; case "boat" -> 0; case "bike" -> 2; case "bicycle" -> 2; default -> throw new Exception("Unknown"); }; } } OOP Abusers Switch Statements Branching out too much
  • 46. softwaretester.blog | Benjamin Bischoff public class Vehicles { public int numberOfWheels(final String vehicle) throws Exception { return switch (vehicle) { case "car" -> 4; case "boat" -> 0; case "bike" -> 2; case "bicycle" -> 2; default -> throw new Exception("Unknown"); }; } } OOP Abusers Switch Statements Branching out too much
  • 47. softwaretester.blog | Benjamin Bischoff public class Vehicles { public int numberOfWheels(final String vehicle) throws Exception { return switch (vehicle) { case "car" -> 4; case "boat" -> 0; case "bike" -> 2; case "bicycle" -> 2; default -> throw new Exception("Unknown"); }; } } OOP Abusers Switch Statements Branching out too much
  • 48. softwaretester.blog | Benjamin Bischoff public class Rectangle { private float sideA; private float sideB; public void setSideA(float sideA) { this.sideA = sideA; } public void setSideB(float sideB) { this.sideB = sideB; } public double getAreaSize() { return sideA * sideB; } } OOP Abusers Temporary Field Fields that are only used once
  • 49. softwaretester.blog | Benjamin Bischoff public class Rectangle { private float sideA; private float sideB; public void setSideA(float sideA) { this.sideA = sideA; } public void setSideB(float sideB) { this.sideB = sideB; } public double getAreaSize() { return sideA * sideB; } } OOP Abusers Temporary Field Fields that are only used once
  • 50. softwaretester.blog | Benjamin Bischoff public class Rectangle { private float sideA; private float sideB; public void setSideA(float sideA) { this.sideA = sideA; } public void setSideB(float sideB) { this.sideB = sideB; } public double getAreaSize() { return sideA * sideB; } } OOP Abusers Temporary Field Fields that are only used once
  • 51. softwaretester.blog | Benjamin Bischoff public class Rectangle { private float sideA; private float sideB; public void setSideA(float sideA) { this.sideA = sideA; } public void setSideB(float sideB) { this.sideB = sideB; } public double getAreaSize() { return sideA * sideB; } } OOP Abusers Temporary Field Fields that are only used once
  • 52. softwaretester.blog | Benjamin Bischoff public class Rectangle { private float sideA; private float sideB; public void setSideA(float sideA) { this.sideA = sideA; } public void setSideB(float sideB) { this.sideB = sideB; } public double getAreaSize() { return sideA * sideB; } } OOP Abusers Temporary Field Fields that are only used once
  • 53. softwaretester.blog | Benjamin Bischoff public class Rectangle { private float sideA; private float sideB; public void setSideA(float sideA) { this.sideA = sideA; } public void setSideB(float sideB) { this.sideB = sideB; } public double getAreaSize() { return sideA * sideB; } } OOP Abusers Temporary Field Fields that are only used once
  • 54. softwaretester.blog | Benjamin Bischoff public class Rectangle { private float sideA; private float sideB; public void setSideA(float sideA) { this.sideA = sideA; } public void setSideB(float sideB) { this.sideB = sideB; } public double getAreaSize() { return sideA * sideB; } } OOP Abusers Temporary Field Fields that are only used once
  • 55. softwaretester.blog | Benjamin Bischoff public class Animals { interface Animal { void speak(); } static class Dog implements Animal { @Override public void speak() { System.out.println("Woof"); } } static class Fish implements Animal { @Override public void speak() { } } } OOP Abusers Refused Bequest Passing unneeded behaviour to classes
  • 56. softwaretester.blog | Benjamin Bischoff public class Animals { interface Animal { void speak(); } static class Dog implements Animal { @Override public void speak() { System.out.println("Woof"); } } static class Fish implements Animal { @Override public void speak() { } } } OOP Abusers Refused Bequest Passing unneeded behaviour to classes
  • 57. softwaretester.blog | Benjamin Bischoff public class Animals { interface Animal { void speak(); } static class Dog implements Animal { @Override public void speak() { System.out.println("Woof"); } } static class Fish implements Animal { @Override public void speak() { } } } OOP Abusers Refused Bequest Passing unneeded behaviour to classes
  • 58. softwaretester.blog | Benjamin Bischoff public class Animals { interface Animal { void speak(); } static class Dog implements Animal { @Override public void speak() { System.out.println("Woof"); } } static class Fish implements Animal { @Override public void speak() { } } } OOP Abusers Refused Bequest Passing unneeded behaviour to classes
  • 59. softwaretester.blog | Benjamin Bischoff public class Animals { interface Animal { void speak(); } static class Dog implements Animal { @Override public void speak() { System.out.println("Woof"); } } static class Fish implements Animal { @Override public void speak() { } } } OOP Abusers Refused Bequest Passing unneeded behaviour to classes
  • 60. softwaretester.blog | Benjamin Bischoff public class Animals { interface Animal { void speak(); } static class Dog implements Animal { @Override public void speak() { System.out.println("Woof"); } } static class Fish implements Animal { @Override public void speak() { } } } OOP Abusers Refused Bequest Passing unneeded behaviour to classes
  • 61. softwaretester.blog | Benjamin Bischoff public class Animals { interface Animal { void speak(); } static class Dog implements Animal { @Override public void speak() { System.out.println("Woof"); } } static class Fish implements Animal { @Override public void speak() { } } } OOP Abusers Refused Bequest Passing unneeded behaviour to classes
  • 62. softwaretester.blog | Benjamin Bischoff public class Shapes { record Circle(float radius) { public double getAreaSize() { return radius * radius * Math.PI; } } record Rectangle(float a, float b) { public double getSurfaceSize() { return a * b; } } } OOP Abusers Different Interfaces Confusing naming of similar functions
  • 63. softwaretester.blog | Benjamin Bischoff public class Shapes { record Circle(float radius) { public double getAreaSize() { return radius * radius * Math.PI; } } record Rectangle(float a, float b) { public double getSurfaceSize() { return a * b; } } } OOP Abusers Different Interfaces Confusing naming of similar functions
  • 64. softwaretester.blog | Benjamin Bischoff public class Shapes { record Circle(float radius) { public double getAreaSize() { return radius * radius * Math.PI; } } record Rectangle(float a, float b) { public double getSurfaceSize() { return a * b; } } } OOP Abusers Different Interfaces Confusing naming of similar functions
  • 65. softwaretester.blog | Benjamin Bischoff public class Shapes { record Circle(float radius) { public double getAreaSize() { return radius * radius * Math.PI; } } record Rectangle(float a, float b) { public double getSurfaceSize() { return a * b; } } } OOP Abusers Different Interfaces Confusing naming of similar functions
  • 66. softwaretester.blog | Benjamin Bischoff public class Shapes { record Circle(float radius) { public double getAreaSize() { return radius * radius * Math.PI; } } record Rectangle(float a, float b) { public double getSurfaceSize() { return a * b; } } } OOP Abusers Different Interfaces Confusing naming of similar functions
  • 67. softwaretester.blog | Benjamin Bischoff Change Preventers Hindering further development.
  • 68. softwaretester.blog | Benjamin Bischoff public class AnimalInformation { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Divergent Change Changes across methods
  • 69. softwaretester.blog | Benjamin Bischoff public class AnimalInformation { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Divergent Change Changes across methods
  • 70. softwaretester.blog | Benjamin Bischoff public class AnimalInformation { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Divergent Change Changes across methods
  • 71. softwaretester.blog | Benjamin Bischoff public class AnimalInformation { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Divergent Change Changes across methods
  • 72. softwaretester.blog | Benjamin Bischoff public class AnimalInformation { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Divergent Change Changes across methods
  • 73. softwaretester.blog | Benjamin Bischoff public class Classification { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } } public class BodyParts { public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Shotgun Surgery Changes across classes
  • 74. softwaretester.blog | Benjamin Bischoff public class Classification { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } } public class BodyParts { public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Shotgun Surgery Changes across classes
  • 75. softwaretester.blog | Benjamin Bischoff public class Classification { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } } public class BodyParts { public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Shotgun Surgery Changes across classes
  • 76. softwaretester.blog | Benjamin Bischoff public class Classification { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } } public class BodyParts { public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Shotgun Surgery Changes across classes
  • 77. softwaretester.blog | Benjamin Bischoff public class Classification { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } } public class BodyParts { public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Shotgun Surgery Changes across classes
  • 78. softwaretester.blog | Benjamin Bischoff public class Classification { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } } public class BodyParts { public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Shotgun Surgery Changes across classes
  • 79. softwaretester.blog | Benjamin Bischoff public class Classification { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } } public class BodyParts { public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Shotgun Surgery Changes across classes
  • 80. softwaretester.blog | Benjamin Bischoff public class Classification { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } } public class BodyParts { public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Shotgun Surgery Changes across classes
  • 81. softwaretester.blog | Benjamin Bischoff public class Classification { public static String getLatinName(final String animal) { if (animal.equalsIgnoreCase("horse")) return "Equus caballus"; return ""; } } public class BodyParts { public static int getNumberOfLegs(final String animal) { if (animal.equalsIgnoreCase("horse")) return 4; return -1; } } Change Preventers Shotgun Surgery Changes across classes
  • 82. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 83. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 84. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 85. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 86. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 87. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 88. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 89. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 90. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 91. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 92. softwaretester.blog | Benjamin Bischoff public class Birds { private static class Bird {} private static class Egg {} private static class Sparrow extends Bird { private SparrowEgg layEgg() { return new SparrowEgg(); } } private static class SparrowEgg extends Egg { } } Change Preventers Parallel Hierarchy Implementing parallel interfaces
  • 93. softwaretester.blog | Benjamin Bischoff Dispensables Unnecessary things that can be removed.
  • 94. softwaretester.blog | Benjamin Bischoff public class WebShopCheckOut { public static void checkOut(final ShoppingCart cart) { // Some implementation } } record ShoppingCart(Product... products) { } record Product(String id) { } Dispensables Lazy Class A class with a single method
  • 95. softwaretester.blog | Benjamin Bischoff public class WebShopCheckOut { public static void checkOut(final ShoppingCart cart) { // Some implementation } } record ShoppingCart(Product... products) { } record Product(String id) { } Dispensables Lazy Class A class with a single method
  • 96. softwaretester.blog | Benjamin Bischoff public class WebShopCheckOut { public static void checkOut(final ShoppingCart cart) { // Some implementation } } record ShoppingCart(Product... products) { } record Product(String id) { } Dispensables Lazy Class A class with a single method
  • 97. softwaretester.blog | Benjamin Bischoff public class WebShopCheckOut { public static void checkOut(final ShoppingCart cart) { // Some implementation } } record ShoppingCart(Product... products) { } record Product(String id) { } Dispensables Lazy Class A class with a single method
  • 98. softwaretester.blog | Benjamin Bischoff public class WebShopCheckOut { public static void checkOut(final ShoppingCart cart) { // Some implementation } } record ShoppingCart(Product... products) { } record Product(String id) { } Dispensables Lazy Class A class with a single method
  • 99. softwaretester.blog | Benjamin Bischoff public class DataClass { record Rectangle(int sideA, int sideB) { } public static void main(String[] args) { Rectangle rectangle = new Rectangle(5, 20); int rectangleArea = rectangle.sideA * rectangle.sideB; } } Dispensables Data Class Class holding data but not its own logic
  • 100. softwaretester.blog | Benjamin Bischoff public class DataClass { record Rectangle(int sideA, int sideB) { } public static void main(String[] args) { Rectangle rectangle = new Rectangle(5, 20); int rectangleArea = rectangle.sideA * rectangle.sideB; } } Dispensables Data Class Class holding data but not its own logic
  • 101. softwaretester.blog | Benjamin Bischoff public class DataClass { record Rectangle(int sideA, int sideB) { } public static void main(String[] args) { Rectangle rectangle = new Rectangle(5, 20); int rectangleArea = rectangle.sideA * rectangle.sideB; } } Dispensables Data Class Class holding data but not its own logic
  • 102. softwaretester.blog | Benjamin Bischoff public class DataClass { record Rectangle(int sideA, int sideB) { } public static void main(String[] args) { Rectangle rectangle = new Rectangle(5, 20); int rectangleArea = rectangle.sideA * rectangle.sideB; } } Dispensables Data Class Class holding data but not its own logic
  • 103. softwaretester.blog | Benjamin Bischoff public class DataClass { record Rectangle(int sideA, int sideB) { } public static void main(String[] args) { Rectangle rectangle = new Rectangle(5, 20); int rectangleArea = rectangle.sideA * rectangle.sideB; } } Dispensables Data Class Class holding data but not its own logic
  • 104. softwaretester.blog | Benjamin Bischoff public class DataClass { record Rectangle(int sideA, int sideB) { } public static void main(String[] args) { Rectangle rectangle = new Rectangle(5, 20); int rectangleArea = rectangle.sideA * rectangle.sideB; } } Dispensables Data Class Class holding data but not its own logic
  • 105. softwaretester.blog | Benjamin Bischoff public class DataClass { record Rectangle(int sideA, int sideB) { } public static void main(String[] args) { Rectangle rectangle = new Rectangle(5, 20); int rectangleArea = rectangle.sideA * rectangle.sideB; } } Dispensables Data Class Class holding data but not its own logic
  • 106. softwaretester.blog | Benjamin Bischoff public class Customers { private List<Customer> customers; public void addCustomer(Customer customer) { customers.add(customer); customers.forEach(System.out::println); } public void removeCustomer(Customer customer) { customers.remove(customer); customers.forEach(System.out::println); } } Dispensables Duplicate Code The same code multiple times
  • 107. softwaretester.blog | Benjamin Bischoff public class Customers { private List<Customer> customers; public void addCustomer(Customer customer) { customers.add(customer); customers.forEach(System.out::println); } public void removeCustomer(Customer customer) { customers.remove(customer); customers.forEach(System.out::println); } } Dispensables Duplicate Code The same code multiple times
  • 108. softwaretester.blog | Benjamin Bischoff public class Customers { private List<Customer> customers; public void addCustomer(Customer customer) { customers.add(customer); customers.forEach(System.out::println); } public void removeCustomer(Customer customer) { customers.remove(customer); customers.forEach(System.out::println); } } Dispensables Duplicate Code The same code multiple times
  • 109. softwaretester.blog | Benjamin Bischoff public class Customers { private List<Customer> customers; public void addCustomer(Customer customer) { customers.add(customer); customers.forEach(System.out::println); } public void removeCustomer(Customer customer) { customers.remove(customer); customers.forEach(System.out::println); } } Dispensables Duplicate Code The same code multiple times
  • 110. softwaretester.blog | Benjamin Bischoff public class Customers { private List<Customer> customers; public void addCustomer(Customer customer) { customers.add(customer); customers.forEach(System.out::println); } public void removeCustomer(Customer customer) { customers.remove(customer); customers.forEach(System.out::println); } } Dispensables Duplicate Code The same code multiple times
  • 111. softwaretester.blog | Benjamin Bischoff public class DeadCode { public static void main(String[] args) { System.out.println("Pi = " + Math.PI); } private double getPi() { return 3.141592; System.out.println("Returning Pi"); } } Dispensables Dead Code Code that cannot be reached
  • 112. softwaretester.blog | Benjamin Bischoff public class DeadCode { public static void main(String[] args) { System.out.println("Pi = " + Math.PI); } private double getPi() { return 3.141592; System.out.println("Returning Pi"); } } Dispensables Dead Code Code that cannot be reached
  • 113. softwaretester.blog | Benjamin Bischoff public class DeadCode { public static void main(String[] args) { System.out.println("Pi = " + Math.PI); } private double getPi() { return 3.141592; System.out.println("Returning Pi"); } } Dispensables Dead Code Code that cannot be reached
  • 114. softwaretester.blog | Benjamin Bischoff public class DeadCode { public static void main(String[] args) { System.out.println("Pi = " + Math.PI); } private double getPi() { return 3.141592; System.out.println("Returning Pi"); } } Dispensables Dead Code Code that cannot be reached
  • 115. softwaretester.blog | Benjamin Bischoff public class DeadCode { public static void main(String[] args) { System.out.println("Pi = " + Math.PI); } private double getPi() { return 3.141592; System.out.println("Returning Pi"); } } Dispensables Dead Code Code that cannot be reached
  • 116. softwaretester.blog | Benjamin Bischoff public class DeadCode { public static void main(String[] args) { System.out.println("Pi = " + Math.PI); } private double getPi() { return 3.141592; System.out.println("Returning Pi"); } } Dispensables Dead Code Code that cannot be reached
  • 117. softwaretester.blog | Benjamin Bischoff public class DeadCode { public static void main(String[] args) { System.out.println("Pi = " + Math.PI); } private double getPi() { return 3.141592; System.out.println("Returning Pi"); } } Dispensables Dead Code Code that cannot be reached
  • 118. softwaretester.blog | Benjamin Bischoff public class LaserPrinter implements Printer { @Override public void print(final String textToPrint) { // Implementation } @Override public void turnOnOrOff() { //Implementation } } interface Printer { void print(String textToPrint); void turnOnOrOff(); } Dispensables Speculative Generality Premature future- proo fi ng
  • 119. softwaretester.blog | Benjamin Bischoff public class LaserPrinter implements Printer { @Override public void print(final String textToPrint) { // Implementation } @Override public void turnOnOrOff() { //Implementation } } interface Printer { void print(String textToPrint); void turnOnOrOff(); } Dispensables Speculative Generality Premature future- proo fi ng
  • 120. softwaretester.blog | Benjamin Bischoff public class LaserPrinter implements Printer { @Override public void print(final String textToPrint) { // Implementation } @Override public void turnOnOrOff() { //Implementation } } interface Printer { void print(String textToPrint); void turnOnOrOff(); } Dispensables Speculative Generality Premature future- proo fi ng
  • 121. softwaretester.blog | Benjamin Bischoff public class LaserPrinter implements Printer { @Override public void print(final String textToPrint) { // Implementation } @Override public void turnOnOrOff() { //Implementation } } interface Printer { void print(String textToPrint); void turnOnOrOff(); } Dispensables Speculative Generality Premature future- proo fi ng
  • 122. softwaretester.blog | Benjamin Bischoff public class LaserPrinter implements Printer { @Override public void print(final String textToPrint) { // Implementation } @Override public void turnOnOrOff() { //Implementation } } interface Printer { void print(String textToPrint); void turnOnOrOff(); } Dispensables Speculative Generality Premature future- proo fi ng
  • 123. softwaretester.blog | Benjamin Bischoff public class LaserPrinter implements Printer { @Override public void print(final String textToPrint) { // Implementation } @Override public void turnOnOrOff() { //Implementation } } interface Printer { void print(String textToPrint); void turnOnOrOff(); } Dispensables Speculative Generality Premature future- proo fi ng
  • 124. softwaretester.blog | Benjamin Bischoff public class LaserPrinter implements Printer { @Override public void print(final String textToPrint) { // Implementation } @Override public void turnOnOrOff() { //Implementation } } interface Printer { void print(String textToPrint); void turnOnOrOff(); } Dispensables Speculative Generality Premature future- proo fi ng
  • 125. softwaretester.blog | Benjamin Bischoff Couplers Too much or too little coupling.
  • 126. softwaretester.blog | Benjamin Bischoff public class UsersAndAddresses { record User(Address address) { public String getAddressString() { return address.street() + ", " + address.city() + ", " + address.country(); } } record Address(String street, String city, String country) { } } Couplers Feature Envy Class implementing features of another
  • 127. softwaretester.blog | Benjamin Bischoff public class UsersAndAddresses { record User(Address address) { public String getAddressString() { return address.street() + ", " + address.city() + ", " + address.country(); } } record Address(String street, String city, String country) { } } Couplers Feature Envy Class implementing features of another
  • 128. softwaretester.blog | Benjamin Bischoff public class UsersAndAddresses { record User(Address address) { public String getAddressString() { return address.street() + ", " + address.city() + ", " + address.country(); } } record Address(String street, String city, String country) { } } Couplers Feature Envy Class implementing features of another
  • 129. softwaretester.blog | Benjamin Bischoff public class UsersAndAddresses { record User(Address address) { public String getAddressString() { return address.street() + ", " + address.city() + ", " + address.country(); } } record Address(String street, String city, String country) { } } Couplers Feature Envy Class implementing features of another
  • 130. softwaretester.blog | Benjamin Bischoff public class UsersAndAddresses { record User(Address address) { public String getAddressString() { return address.street() + ", " + address.city() + ", " + address.country(); } } record Address(String street, String city, String country) { } } Couplers Feature Envy Class implementing features of another
  • 131. softwaretester.blog | Benjamin Bischoff public class Book { private final String title; private Author author; public Book(String title) { this.title = title;} public void setAuthor(Author author) { this.author = author; } } public class Author { private final String name; private Book book; public Author(String name) { this.name = name; } public void setBook(Book book) { this.book = book; } } Couplers Inappropriate Intimacy Classes knowing each other too well
  • 132. softwaretester.blog | Benjamin Bischoff public class Book { private final String title; private Author author; public Book(String title) { this.title = title;} public void setAuthor(Author author) { this.author = author; } } public class Author { private final String name; private Book book; public Author(String name) { this.name = name; } public void setBook(Book book) { this.book = book; } } Couplers Inappropriate Intimacy Classes knowing each other too well
  • 133. softwaretester.blog | Benjamin Bischoff public class Book { private final String title; private Author author; public Book(String title) { this.title = title;} public void setAuthor(Author author) { this.author = author; } } public class Author { private final String name; private Book book; public Author(String name) { this.name = name; } public void setBook(Book book) { this.book = book; } } Couplers Inappropriate Intimacy Classes knowing each other too well
  • 134. softwaretester.blog | Benjamin Bischoff public class Book { private final String title; private Author author; public Book(String title) { this.title = title;} public void setAuthor(Author author) { this.author = author; } } public class Author { private final String name; private Book book; public Author(String name) { this.name = name; } public void setBook(Book book) { this.book = book; } } Couplers Inappropriate Intimacy Classes knowing each other too well
  • 135. softwaretester.blog | Benjamin Bischoff public class Book { private final String title; private Author author; public Book(String title) { this.title = title;} public void setAuthor(Author author) { this.author = author; } } public class Author { private final String name; private Book book; public Author(String name) { this.name = name; } public void setBook(Book book) { this.book = book; } } Couplers Inappropriate Intimacy Classes knowing each other too well
  • 136. softwaretester.blog | Benjamin Bischoff public class Book { private final String title; private Author author; public Book(String title) { this.title = title;} public void setAuthor(Author author) { this.author = author; } } public class Author { private final String name; private Book book; public Author(String name) { this.name = name; } public void setBook(Book book) { this.book = book; } } Couplers Inappropriate Intimacy Classes knowing each other too well
  • 137. softwaretester.blog | Benjamin Bischoff public class Book { private final String title; private Author author; public Book(String title) { this.title = title;} public void setAuthor(Author author) { this.author = author; } } public class Author { private final String name; private Book book; public Author(String name) { this.name = name; } public void setBook(Book book) { this.book = book; } } Couplers Inappropriate Intimacy Classes knowing each other too well
  • 138. softwaretester.blog | Benjamin Bischoff public class Book { private final String title; private Author author; public Book(String title) { this.title = title;} public void setAuthor(Author author) { this.author = author; } } public class Author { private final String name; private Book book; public Author(String name) { this.name = name; } public void setBook(Book book) { this.book = book; } } Couplers Inappropriate Intimacy Classes knowing each other too well
  • 139. softwaretester.blog | Benjamin Bischoff public class Book { private final String title; private Author author; public Book(String title) { this.title = title;} public void setAuthor(Author author) { this.author = author; } } public class Author { private final String name; private Book book; public Author(String name) { this.name = name; } public void setBook(Book book) { this.book = book; } } Couplers Inappropriate Intimacy Classes knowing each other too well
  • 140. softwaretester.blog | Benjamin Bischoff public class Storehouse { public static void main(String[] args) { List<Product> products = List.of( new Product("Cheese", "Tasty cheese")); List<Shelf> shelves = List.of(new Shelf(products)); String description = shelves.get(0).products().get(0).description(); } record Shelf(List<Product> products) { } record Product(String name, String description) { } } Couplers Message Chains Returning objects that return objects…
  • 141. softwaretester.blog | Benjamin Bischoff public class Storehouse { public static void main(String[] args) { List<Product> products = List.of( new Product("Cheese", "Tasty cheese")); List<Shelf> shelves = List.of(new Shelf(products)); String description = shelves.get(0).products().get(0).description(); } record Shelf(List<Product> products) { } record Product(String name, String description) { } } Couplers Message Chains Returning objects that return objects…
  • 142. softwaretester.blog | Benjamin Bischoff public class Storehouse { public static void main(String[] args) { List<Product> products = List.of( new Product("Cheese", "Tasty cheese")); List<Shelf> shelves = List.of(new Shelf(products)); String description = shelves.get(0).products().get(0).description(); } record Shelf(List<Product> products) { } record Product(String name, String description) { } } Couplers Message Chains Returning objects that return objects…
  • 143. softwaretester.blog | Benjamin Bischoff public record Customer(String name, Address address) { public String getCity() { return address.city(); } public String getStreet() { return address.street(); } record Address(String street, String city) { } } Dispensables Middle Man Class accessing another one on its behalf
  • 144. softwaretester.blog | Benjamin Bischoff public record Customer(String name, Address address) { public String getCity() { return address.city(); } public String getStreet() { return address.street(); } record Address(String street, String city) { } } Dispensables Middle Man Class accessing another one on its behalf
  • 145. softwaretester.blog | Benjamin Bischoff public record Customer(String name, Address address) { public String getCity() { return address.city(); } public String getStreet() { return address.street(); } record Address(String street, String city) { } } Dispensables Middle Man Class accessing another one on its behalf
  • 146. softwaretester.blog | Benjamin Bischoff public record Customer(String name, Address address) { public String getCity() { return address.city(); } public String getStreet() { return address.street(); } record Address(String street, String city) { } } Dispensables Middle Man Class accessing another one on its behalf
  • 147. softwaretester.blog | Benjamin Bischoff public record Customer(String name, Address address) { public String getCity() { return address.city(); } public String getStreet() { return address.street(); } record Address(String street, String city) { } } Dispensables Middle Man Class accessing another one on its behalf
  • 148. softwaretester.blog | Benjamin Bischoff Classi fi cation Bloaters OOP Abusers Change Preventers Dispensables Couplers Long Method Large Class Primitive Obsession Long Parameter List Data Clumps Switch Statements Temporary Field Refused Bequest Alternative classes with di ff erent Interfaces Divergent Change Shotgun Surgery Parallel Inheritance Hierarchy Lazy Class Data Class Duplicate Code Dead Code Speculative Generality Feature Envy Inappropriate Intimacy Message Chains Middleman
  • 149. softwaretester.blog | Benjamin Bischoff Example Code github.com/bischoffdev/code-smells
  • 150. softwaretester.blog | Benjamin Bischoff When to tackle code smells?
  • 151. softwaretester.blog | Benjamin Bischoff Broken window Long-term effects of un fi xed code.
  • 152. softwaretester.blog | Benjamin Bischoff YAGNI Wasting time with future requirements.
  • 153. softwaretester.blog | Benjamin Bischoff Campground Rule Later never comes…
  • 154. softwaretester.blog | Benjamin Bischoff Code Reviews Point out smells before it is too late!
  • 155. softwaretester.blog | Benjamin Bischoff More information
  • 156. softwaretester.blog | Benjamin Bischoff Refactoring catalog refactoring.com/catalog
  • 157. softwaretester.blog | Benjamin Bischoff Refactoring Guru refactoring.guru/refactoring
  • 158. softwaretester.blog | Benjamin Bischoff Marcel Jerzyk luzkan.github.io/smells/
  • 159. softwaretester.blog | Benjamin Bischoff Smelly Code Smelly code, smelly code How are they treating you? Smelly code, smelly code It’s not your fault.
  • 160. softwaretester.blog | Benjamin Bischoff Thank you!
  • 161. softwaretester.blog | Benjamin Bischoff Thank you!