SlideShare una empresa de Scribd logo
1 de 46
Eduardo Granados Ch.
CLEAN CODE
Eduardo Granados Ch.
Twitter: @odraudek99
Eduardo Granados Ch.
Topics
Meaningful names
Use Pronounceable Names
Member Prefixes
Class and method names
Constructors
Functions
Switch Statements
Function arguments
Flag Arguments
Have no side effects
Prefer Exceptions to returning Error Codes
Comments
Format
Format
Objects and Data Structures
Exceptions vs errors
Duplicade code
SOLID
GRASP Patterns
Class
High Cohesion - Before
Eduardo Granados Ch.
Meaningful names
Don’t use Use
int d; // elapsed time in days
int i; // a day
int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList)
if (x[0] == 4)
list1.add(x);
return list1;
}
public List<int[]> getFlaggedCells() {
List<int[]> flaggedCells = new ArrayList<int[]>();
for (int[] cell : gameBoard)
if (cell[STATUS_VALUE] == FLAGGED)
flaggedCells.add(cell);
return flaggedCells;
}
Eduardo Granados Ch.
Meaningful names - Hide the magic numbers
Good Best
public List<int[]> getFlaggedCells() {
List<int[]> flaggedCells = new ArrayList<int[]>();
for (int[] cell : gameBoard)
if (cell[STATUS_VALUE] == FLAGGED)
flaggedCells.add(cell);
return flaggedCells;
}
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList<Cell>();
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells;
}
Eduardo Granados Ch.
Use Pronounceable Names
Don’t use Use
private Date genymdhms;
private Date modymdhms;
private final String pszqint = "102";
private Date generationTimestamp;
private Date modificationTimestamp;;
private final String recordId = "102";
Eduardo Granados Ch.
Member Prefixes
You also don’t need to prefix member variables with m_ anymore.
Classes and functions should be small enough that you don’t need them
Don’t use Use
public class Part {
private String m_dsc; // The textual description
void setName(String name) {
m_dsc = name;
}
}
public class Part {
String description;
void setDescription(String description) {
this.description = description;
}
}
Eduardo Granados Ch.
Class and method names
Classes and objects should have noun or noun phrase names like Customer, WikiPage, Account, and
AddressParser. Avoid words like Manager, Processor, Data, or Info in the name of a class. A class name
should not be a verb
Methods should have verb or verb phrase names like postPayment, deletePage, or save. Accessors,
mutators, and predicates should be named for their value and prefixed with get, set, and is according to the
javabean standard
string name = employee.getName();
customer.setName("mike");
if (paycheck.isPosted())...
Eduardo Granados Ch.
CONSTRUCTORS
When constructors are overloaded, use static factory methods with names that describe the arguments.
Consider enforcing their use by making the corresponding constructors private
Don’t use Use
Complex fulcrumPoint = new Complex(23.0); Complex fulcrumPoint = Complex.FromRealNumber(23.0);
Eduardo Granados Ch.
EXAMPLE
Eduardo Granados Ch.
FUNCTIONS
1.The first rule of functions is that they should be small.
2.The second rule of functions is that they should be smaller than that. This is not an assertion that I can
justify.
FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT
WELL. THEY SHOULD DO IT ONLY.
Eduardo Granados Ch.
Switch Statements
public Money calculatePay(Employee e) throws InvalidEmployeeType {
switch (e.type) {
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeType(e.type);
}
}
Problems:
1.it’s large, and when new employee types are
added, it will grow
2.Does more than one thing
3.It violates the Single Responsibility Principle
(SRP) because there is more than one reason for it
to change.
4.It violates the Open Closed Principle (OCP)
because it must change whenever new types are
added.
We could have isPayday(Employee e, Date date),
or deliverPay(Employee e, Money pay), etc. All of
which would have the same deleterious structure.
The solution to this problem is to bury the switch
statement in the basement of an ABSTRACT
FACTORY
Eduardo Granados Ch.
Switch Statements 2
public abstract class Employee {
public abstract boolean isPayday();
public abstract Money calculatePay();
public abstract void deliverPay(Money pay);
}
public interface EmployeeFactory {
public Employee makeEmployee(EmployeeRecord r) throws
InvalidEmployeeType;
}
public class EmployeeFactoryImpl implements EmployeeFactory {
public Employee makeEmployee(EmployeeRecord r) throws
InvalidEmployeeType {
switch (r.type) {
case COMMISSIONED:
return new CommissionedEmployee(r) ;
case HOURLY:
return new HourlyEmployee(r);
case SALARIED:
return new SalariedEmploye(r);
default:
throw new InvalidEmployeeType(r.type);
}
}
}
•Switch statements appear only once
•Used to create polymorphic objects, hidden behind
an inheritance relationship so that the rest of the
system can’t see them.
•Of course every circumstance is unique, and there
are times when I violate one or more parts of that
rule.
Eduardo Granados Ch.
Function arguments
The ideal number of arguments for a function is zero
Next comes one or two arguments
Three arguments should be avoided where possible
More than three (polyadic) requires very special justification and then shouldn’t be used anyway
When a function seems to need more than two or three arguments, it is likely that some of those
arguments ought to be wrapped into a class of their own:
Circle makeCircle(double x, double y, double radius);
Circle makeCircle(Point center, double radius);
Eduardo Granados Ch.
Eduardo Granados Ch.
Functions
Don’t use Use
void transform(StringBuffer out); StringBuffer transform(StringBuffer in);
Eduardo Granados Ch.
Eduardo Granados Ch.
Flag Arguments
Passing a boolean into a function is a truly terrible practice
Split the function into two
Don’t use Use
render(boolean isSuite); renderForSuite()
renderForSingleTest();
Eduardo Granados Ch.
Have No Side Effects
Your function promises to do one thing, but it also does other hidden Things
Functions should either do something or answer something, but not both
public class UserValidator {
private Cryptographer cryptographer;
public boolean checkPassword(String userName, String password) {
User user = UserGateway.findByName(userName);
if (user != User.NULL) {
String codedPhrase = user.getPhraseEncodedByPassword();
String phrase = cryptographer.decrypt(codedPhrase, password);
if ("Valid Password".equals(phrase)) {
Session.initialize();
return true;
}
}
return false;
}
}
Eduardo Granados Ch.
Prefer Exceptions to Returning Error Codes
Don’t use Use
if (deletePage(page) == E_OK) {
if (registry.deleteReference(page.name) == E_OK) {
if (configKeys.deleteKey(page.name.makeKey()) == E_OK) {
logger.log("page deleted");
} else {
logger.log("configKey not deleted");
}
} else {
logger.log("deleteReference from registry failed");
}
} else {
logger.log("delete failed");
return E_ERROR;
}
try {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
} catch (Exception e) {
logger.log(e.getMessage());
}
Eduardo Granados Ch.
COMENTS
The proper use of comments is to compensate for our failure to express ourself in code
Ooh, I’d better comment that!” No! You’d better clean it!
Don’t use Use
// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
if (employee.isEligibleForFullBenefits())
A comment like this can sometimes be useful, but it is better to
use the name of the function
to convey the information where possible.
// Returns an instance of the Responder being tested.
protected abstract Responder responderInstance();
Here’s a case that’s a bit better: // format matched kk:mm:ss EEE, MMM dd, yyyy
Pattern timeMatcher = Pattern.compile("d*:d*:d* w*,
w* d*, d*");
Eduardo Granados Ch.
Eduardo Granados Ch.
COMMENTS - Clarification
Clarification: Sometimes it is just helpful to translate the meaning
assertTrue(a.compareTo(a) == 0); // a == a
assertTrue(a.compareTo(b) != 0); // a != b
assertTrue(ab.compareTo(ab) == 0); // ab == ab
Warning of Consequences: Sometimes it is useful to warn about certain consequences here is a comment
that explains why a particular test case is turned off:
// Don't run unless you
// have some time to kill.
public void _testWithReallyBigFile();
Eduardo Granados Ch.
FORMAT
choose a set of simple rules that govern the format of code
If you are working on a team, then the team should agree to a single set of formatting rules and all
members should comply
Eduardo Granados Ch.
Objects and Data Structures
Procedural Shape Polymorphic Shapes
public class Square {
public Point topLeft;
public double side;
}
public class Rectangle {
public Point topLeft;
public double height;
public double width;
}
public class Circle {
public Point center;
public double radius;
}
public class Geometry {
public final double PI = 3.141592653589793;
public double area(Object shape) throws NoSuchShapeException {
if (shape instanceof Square) {
Square s = (Square)shape;
return s.side * s.side;
} else if (shape instanceof Rectangle) {
Rectangle r = (Rectangle)shape;
return r.height * r.width;
} else if (shape instanceof Circle) {
Circle c = (Circle)shape;
return PI * c.radius * c.radius;
}
throw new NoSuchShapeException();
}
public class Square implements Shape {
private Point topLeft;
private double side;
public double area() {
return side*side;
}
}
public class Rectangle implements Shape {
private Point topLeft;
private double height;
private double width;
public double area() {
return height * width;
}
}
public class Circle implements Shape {
private Point center;
private double radius;
public final double PI = 3.141592653589793;
public double area() {
return PI * radius * radius;
}
}
Eduardo Granados Ch.
Objects and Data Structures
Objects expose behavior and hide data. This makes it easy to add new kinds of objects without changing
existing behaviors. It also makes it hard to add new behaviors to existing objects. Data structures expose
data and have no significant behavior
Eduardo Granados Ch.
EXCEPTIONS VS ERRORS
Define the Normal Flow
Don’t Return Null
Don’t Pass Null
Eduardo Granados Ch.
Eduardo Granados Ch.
Eduardo Granados Ch.
Eduardo Granados Ch.
Eduardo Granados Ch.
DUPLICATED CODE
Eduardo Granados Ch.
Eduardo Granados Ch.
Eduardo Granados Ch.
Eduardo Granados Ch.
Eduardo Granados Ch.
SOLID
Single responsibility
A class should have only a single responsibility (i.e. only one potential change in the software's specification should be able to
affect the specification of the class)
Open-closed
software entities … should be open for extension, but closed for modification
Liskov substitution
objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program
Interface segregation
many client-specific interfaces are better than one general-purpose interface
Dependency inversion
one should “Depend upon Abstractions. Do not depend upon concretions”
Eduardo Granados Ch.
GRASP PATTERNS
Creator
Information Expert (or just Expert)
Low Coupling
High Cohesion
Controller
Polymorphism
Pure Fabrication
Indirection
Protected Variations
Eduardo Granados Ch.
Class
a class should begin with a list of variables. Public static constants, if any, should come first. Then private static
variables, followed by private instance variables. There is seldom a good reason to have a public variable.
Public functions should follow the list of variables. We like to put the private utilities called by a public function right
after the public function itself. This follows the stepdown rule and helps the program read like a newspaper article.
Eduardo Granados Ch.
High Cohesion - Before
package literatePrimes;
public class PrintPrimes {
public static void main(String[] args) {
final int M = 1000;
final int RR = 50;
final int CC = 4;
final int WW = 10;
final int ORDMAX = 30;
int P[] = new int[M + 1];
int PAGENUMBER;
int PAGEOFFSET;
int ROWOFFSET;
int C;
int J;
int K;
boolean JPRIME;
int ORD;
int SQUARE;
int N;
int MULT[] = new int[ORDMAX + 1];
J = 1;
K = 1;
P[1] = 2;
ORD = 2;
SQUARE = 9;
while (K < M) {
do {
J = J + 2;
if (J == SQUARE) {
ORD = ORD + 1;
SQUARE = P[ORD] * P[ORD];
MULT[ORD - 1] = J;
}
N = 2;
JPRIME = true;
while (N < ORD && JPRIME) {
while (MULT[N] < J)
MULT[N] = MULT[N] + P[N] + P[N];
if (MULT[N] == J)
JPRIME = false;
N = N + 1;
}
} while (!JPRIME);
K = K + 1;
P[K] = J;
}
{
PAGENUMBER = 1;
PAGEOFFSET = 1;
while (PAGEOFFSET <= M) {
System.out.println("The First " + M +
" Prime Numbers --- Page " + PAGENUMBER);
System.out.println("");
for (ROWOFFSET = PAGEOFFSET; ROWOFFSET < PAGEOFFSET + RR;
ROWOFFSET++){
for (C = 0; C < CC;C++)
if (ROWOFFSET + C * RR <= M)
System.out.format("%10d", P[ROWOFFSET + C * RR]);
System.out.println("");
}
System.out.println("f");
PAGENUMBER = PAGENUMBER + 1;
PAGEOFFSET = PAGEOFFSET + RR * CC;
}
}
}
}
Eduardo Granados Ch.
High Cohesion – After (1/4)
Slit into three main responsibilities
1.The main program is contained in the PrimePrinter class all by itself. Its responsibility is to handle the execution
environment. It will change if the method of invocation changes. For example, if this program were converted to a
SOAP service, this is the class that would be affected
2.The RowColumnPagePrinter knows all about how to format a list of numbers into pages with a certain number of
rows and columns. If the formatting of the output needed changing, then this is the class that would be affected.
3.The PrimeGenerator class knows how to generate a list prime numbers. Notice that it is not meant to be
instantiated as an object. The class is just a useful scope in which its variables can be declared and kept hidden.
This class will change if the algorithm for computing prime numbers changes.
Eduardo Granados Ch.
High Cohesion – After (2/4)
package literatePrimes;
public class PrimePrinter {
public static void main(String[] args) {
final int NUMBER_OF_PRIMES = 1000;
int[] primes = PrimeGenerator.generate(NUMBER_OF_PRIMES);
final int ROWS_PER_PAGE = 50;
final int COLUMNS_PER_PAGE = 4;
RowColumnPagePrinter tablePrinter = new RowColumnPagePrinter(ROWS_PER_PAGE,
COLUMNS_PER_PAGE, "The First " + NUMBER_OF_PRIMES +" Prime Numbers");
tablePrinter.print(primes);
}
}
Eduardo Granados Ch.
High Cohesion – After (3/4)
package literatePrimes;
import java.io.PrintStream;
public class RowColumnPagePrinter {
private int rowsPerPage, columnsPerPage,numbersPerPage;
private String pageHeader;
private PrintStream printStream;
public RowColumnPagePrinter(int rowsPerPage, int columnsPerPage,
String pageHeader) {
this.rowsPerPage = rowsPerPage;
this.columnsPerPage = columnsPerPage;
this.pageHeader = pageHeader;
numbersPerPage = rowsPerPage * columnsPerPage;
printStream = System.out;
}
public void print(int data[]) {
int pageNumber = 1;
for (int firstIndexOnPage = 0; firstIndexOnPage < data.length;
firstIndexOnPage += numbersPerPage) {
int lastIndexOnPage = Math.min(firstIndexOnPage +
numbersPerPage - 1, data.length - 1);
printPageHeader(pageHeader, pageNumber);
printPage(firstIndexOnPage, lastIndexOnPage, data);
printStream.println("f");
pageNumber++;
}
}
private void printPage(int firstIndexOnPage, int lastIndexOnPage, int[] data) {
int firstIndexOfLastRowOnPage = firstIndexOnPage + rowsPerPage - 1;
for (int firstIndexInRow = firstIndexOnPage;
firstIndexInRow <= firstIndexOfLastRowOnPage;
firstIndexInRow++) {
printRow(firstIndexInRow, lastIndexOnPage, data);
printStream.println("");
}
}
private void printRow(int firstIndexInRow, int lastIndexOnPage, int[] data) {
for (int column = 0; column < columnsPerPage; column++) {
int index = firstIndexInRow + column * rowsPerPage;
if (index <= lastIndexOnPage)
printStream.format("%10d", data[index]);
}
}
private void printPageHeader(String pageHeader, int pageNumber) {
printStream.println(pageHeader + " --- Page " + pageNumber);
printStream.println("");
}
public void setOutput(PrintStream printStream) {
this.printStream = printStream;
}
}
Eduardo Granados Ch.
High Cohesion – After (4/4)
package literatePrimes;
import java.util.ArrayList;
public class PrimeGenerator {
private static int[] primes;
private static ArrayList<Integer> multiplesOfPrimeFactors;
protected static int[] generate(int n) {
primes = new int[n];
multiplesOfPrimeFactors = new ArrayList<Integer>();
set2AsFirstPrime();
checkOddNumbersForSubsequentPrimes();
return primes;
}
private static void set2AsFirstPrime() {
primes[0] = 2;
multiplesOfPrimeFactors.add(2);
}
private static void checkOddNumbersForSubsequentPrimes() {
int primeIndex = 1;
for (int candidate = 3; primeIndex < primes.length; candidate += 2) {
if (isPrime(candidate))
primes[primeIndex++] = candidate;
}
}
private static boolean isPrime(int candidate) {
if (isLeastRelevantMultipleOfNextLargerPrimeFactor(candidate)) {
multiplesOfPrimeFactors.add(candidate);
return false;
}
return isNotMultipleOfAnyPreviousPrimeFactor(candidate);
}
private static boolean isLeastRelevantMultipleOfNextLargerPrimeFactor(int candidate) {
int nextLargerPrimeFactor = primes[multiplesOfPrimeFactors.size()];
int leastRelevantMultiple = nextLargerPrimeFactor * nextLargerPrimeFactor;
return candidate == leastRelevantMultiple;
}
private static boolean isNotMultipleOfAnyPreviousPrimeFactor(int candidate) {
for (int n = 1; n < multiplesOfPrimeFactors.size(); n++) {
if (isMultipleOfNthPrimeFactor(candidate, n))
return false;
}
return true;
}
private static boolean isMultipleOfNthPrimeFactor(int candidate, int n) {
return candidate == smallestOddNthMultipleNotLessThanCandidate(candidate, n);
}
private static int smallestOddNthMultipleNotLessThanCandidate(int candidate, int n) {
int multiple = multiplesOfPrimeFactors.get(n);
while (multiple < candidate)
multiple += 2 * primes[n];
multiplesOfPrimeFactors.set(n, multiple);
return multiple;
}
}
Eduardo Granados Ch.
Eduardo Granados Ch.
Preguntas
Eduardo Granados Ch.
Thanks

Más contenido relacionado

La actualidad más candente

ES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesDavid Rodenas
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYCMike Dirolf
 
IP project for class 12 cbse
IP project for class 12 cbseIP project for class 12 cbse
IP project for class 12 cbsesiddharthjha34
 
Ip project work test your knowledge
Ip project work test your knowledgeIp project work test your knowledge
Ip project work test your knowledgeKïShørê Choudhary
 
ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)David Rodenas
 
TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingDavid Rodenas
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012Yaqi Zhao
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionKent Huang
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedPascal-Louis Perez
 
Inheritance and-polymorphism
Inheritance and-polymorphismInheritance and-polymorphism
Inheritance and-polymorphismUsama Malik
 
JAVA AND MYSQL QUERIES
JAVA AND MYSQL QUERIES JAVA AND MYSQL QUERIES
JAVA AND MYSQL QUERIES Aditya Shah
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable codeGeshan Manandhar
 
Design pattern - part 1
Design pattern - part 1Design pattern - part 1
Design pattern - part 1Jieyi Wu
 

La actualidad más candente (19)

ES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesES3-2020-07 Testing techniques
ES3-2020-07 Testing techniques
 
Ip project visual mobile
Ip project visual mobileIp project visual mobile
Ip project visual mobile
 
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYC
 
IP project for class 12 cbse
IP project for class 12 cbseIP project for class 12 cbse
IP project for class 12 cbse
 
Ip project work test your knowledge
Ip project work test your knowledgeIp project work test your knowledge
Ip project work test your knowledge
 
ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)
 
TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving Testing
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012
 
Clean code
Clean codeClean code
Clean code
 
Magic methods
Magic methodsMagic methods
Magic methods
 
PHP 5 Magic Methods
PHP 5 Magic MethodsPHP 5 Magic Methods
PHP 5 Magic Methods
 
Test Engine
Test EngineTest Engine
Test Engine
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
 
Inheritance and-polymorphism
Inheritance and-polymorphismInheritance and-polymorphism
Inheritance and-polymorphism
 
JAVA AND MYSQL QUERIES
JAVA AND MYSQL QUERIES JAVA AND MYSQL QUERIES
JAVA AND MYSQL QUERIES
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
 
7
77
7
 
Design pattern - part 1
Design pattern - part 1Design pattern - part 1
Design pattern - part 1
 

Similar a Clean Code Concepts and Best Practices

Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003R696
 
Clean code & design patterns
Clean code & design patternsClean code & design patterns
Clean code & design patternsPascal Larocque
 
Jeremiah Caballero - Introduction of Clean Code
Jeremiah Caballero - Introduction of Clean CodeJeremiah Caballero - Introduction of Clean Code
Jeremiah Caballero - Introduction of Clean CodeAwesome Ars Academia
 
Finding bugs that matter with Findbugs
Finding bugs that matter with FindbugsFinding bugs that matter with Findbugs
Finding bugs that matter with FindbugsCarol McDonald
 
20.1 Java working with abstraction
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstractionIntro C# Book
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy codeShriKant Vashishtha
 
Addressing Scenario
Addressing ScenarioAddressing Scenario
Addressing ScenarioTara Hardin
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerSrikanth Shreenivas
 
JavaScript lesson 1.pptx
JavaScript lesson 1.pptxJavaScript lesson 1.pptx
JavaScript lesson 1.pptxMuqaddarNiazi1
 
Does your code spark joy? Refactoring techniques to make your life easier.
Does your code spark joy? Refactoring techniques to make your life easier.Does your code spark joy? Refactoring techniques to make your life easier.
Does your code spark joy? Refactoring techniques to make your life easier.Juciellen Cabrera
 
Core Java Programming Language (JSE) : Chapter VI - Class Design
Core Java Programming Language (JSE) : Chapter VI - Class DesignCore Java Programming Language (JSE) : Chapter VI - Class Design
Core Java Programming Language (JSE) : Chapter VI - Class DesignWebStackAcademy
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonCodemotion
 
Struts 2 + Spring
Struts 2 + SpringStruts 2 + Spring
Struts 2 + SpringBryan Hsueh
 

Similar a Clean Code Concepts and Best Practices (20)

Clean code
Clean codeClean code
Clean code
 
Clean Code
Clean CodeClean Code
Clean Code
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
 
Clean code & design patterns
Clean code & design patternsClean code & design patterns
Clean code & design patterns
 
Jeremiah Caballero - Introduction of Clean Code
Jeremiah Caballero - Introduction of Clean CodeJeremiah Caballero - Introduction of Clean Code
Jeremiah Caballero - Introduction of Clean Code
 
Finding bugs that matter with Findbugs
Finding bugs that matter with FindbugsFinding bugs that matter with Findbugs
Finding bugs that matter with Findbugs
 
20.1 Java working with abstraction
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstraction
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 
Addressing Scenario
Addressing ScenarioAddressing Scenario
Addressing Scenario
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better Programmer
 
Chapter 2
Chapter 2Chapter 2
Chapter 2
 
JavaScript lesson 1.pptx
JavaScript lesson 1.pptxJavaScript lesson 1.pptx
JavaScript lesson 1.pptx
 
Does your code spark joy? Refactoring techniques to make your life easier.
Does your code spark joy? Refactoring techniques to make your life easier.Does your code spark joy? Refactoring techniques to make your life easier.
Does your code spark joy? Refactoring techniques to make your life easier.
 
Core Java Programming Language (JSE) : Chapter VI - Class Design
Core Java Programming Language (JSE) : Chapter VI - Class DesignCore Java Programming Language (JSE) : Chapter VI - Class Design
Core Java Programming Language (JSE) : Chapter VI - Class Design
 
What's in a name
What's in a nameWhat's in a name
What's in a name
 
Encapsulation
EncapsulationEncapsulation
Encapsulation
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - Warburton
 
Struts 2 + Spring
Struts 2 + SpringStruts 2 + Spring
Struts 2 + Spring
 

Último

Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
How To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROHow To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROmotivationalword821
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfYashikaSharma391629
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...Akihiro Suda
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 

Último (20)

Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
How To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROHow To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTRO
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 

Clean Code Concepts and Best Practices

  • 1. Eduardo Granados Ch. CLEAN CODE Eduardo Granados Ch. Twitter: @odraudek99
  • 2. Eduardo Granados Ch. Topics Meaningful names Use Pronounceable Names Member Prefixes Class and method names Constructors Functions Switch Statements Function arguments Flag Arguments Have no side effects Prefer Exceptions to returning Error Codes Comments Format Format Objects and Data Structures Exceptions vs errors Duplicade code SOLID GRASP Patterns Class High Cohesion - Before
  • 3. Eduardo Granados Ch. Meaningful names Don’t use Use int d; // elapsed time in days int i; // a day int elapsedTimeInDays; int daysSinceCreation; int daysSinceModification; int fileAgeInDays public List<int[]> getThem() { List<int[]> list1 = new ArrayList<int[]>(); for (int[] x : theList) if (x[0] == 4) list1.add(x); return list1; } public List<int[]> getFlaggedCells() { List<int[]> flaggedCells = new ArrayList<int[]>(); for (int[] cell : gameBoard) if (cell[STATUS_VALUE] == FLAGGED) flaggedCells.add(cell); return flaggedCells; }
  • 4. Eduardo Granados Ch. Meaningful names - Hide the magic numbers Good Best public List<int[]> getFlaggedCells() { List<int[]> flaggedCells = new ArrayList<int[]>(); for (int[] cell : gameBoard) if (cell[STATUS_VALUE] == FLAGGED) flaggedCells.add(cell); return flaggedCells; } public List<Cell> getFlaggedCells() { List<Cell> flaggedCells = new ArrayList<Cell>(); for (Cell cell : gameBoard) if (cell.isFlagged()) flaggedCells.add(cell); return flaggedCells; }
  • 5. Eduardo Granados Ch. Use Pronounceable Names Don’t use Use private Date genymdhms; private Date modymdhms; private final String pszqint = "102"; private Date generationTimestamp; private Date modificationTimestamp;; private final String recordId = "102";
  • 6. Eduardo Granados Ch. Member Prefixes You also don’t need to prefix member variables with m_ anymore. Classes and functions should be small enough that you don’t need them Don’t use Use public class Part { private String m_dsc; // The textual description void setName(String name) { m_dsc = name; } } public class Part { String description; void setDescription(String description) { this.description = description; } }
  • 7. Eduardo Granados Ch. Class and method names Classes and objects should have noun or noun phrase names like Customer, WikiPage, Account, and AddressParser. Avoid words like Manager, Processor, Data, or Info in the name of a class. A class name should not be a verb Methods should have verb or verb phrase names like postPayment, deletePage, or save. Accessors, mutators, and predicates should be named for their value and prefixed with get, set, and is according to the javabean standard string name = employee.getName(); customer.setName("mike"); if (paycheck.isPosted())...
  • 8. Eduardo Granados Ch. CONSTRUCTORS When constructors are overloaded, use static factory methods with names that describe the arguments. Consider enforcing their use by making the corresponding constructors private Don’t use Use Complex fulcrumPoint = new Complex(23.0); Complex fulcrumPoint = Complex.FromRealNumber(23.0);
  • 10. Eduardo Granados Ch. FUNCTIONS 1.The first rule of functions is that they should be small. 2.The second rule of functions is that they should be smaller than that. This is not an assertion that I can justify. FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL. THEY SHOULD DO IT ONLY.
  • 11. Eduardo Granados Ch. Switch Statements public Money calculatePay(Employee e) throws InvalidEmployeeType { switch (e.type) { case COMMISSIONED: return calculateCommissionedPay(e); case HOURLY: return calculateHourlyPay(e); case SALARIED: return calculateSalariedPay(e); default: throw new InvalidEmployeeType(e.type); } } Problems: 1.it’s large, and when new employee types are added, it will grow 2.Does more than one thing 3.It violates the Single Responsibility Principle (SRP) because there is more than one reason for it to change. 4.It violates the Open Closed Principle (OCP) because it must change whenever new types are added. We could have isPayday(Employee e, Date date), or deliverPay(Employee e, Money pay), etc. All of which would have the same deleterious structure. The solution to this problem is to bury the switch statement in the basement of an ABSTRACT FACTORY
  • 12. Eduardo Granados Ch. Switch Statements 2 public abstract class Employee { public abstract boolean isPayday(); public abstract Money calculatePay(); public abstract void deliverPay(Money pay); } public interface EmployeeFactory { public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType; } public class EmployeeFactoryImpl implements EmployeeFactory { public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType { switch (r.type) { case COMMISSIONED: return new CommissionedEmployee(r) ; case HOURLY: return new HourlyEmployee(r); case SALARIED: return new SalariedEmploye(r); default: throw new InvalidEmployeeType(r.type); } } } •Switch statements appear only once •Used to create polymorphic objects, hidden behind an inheritance relationship so that the rest of the system can’t see them. •Of course every circumstance is unique, and there are times when I violate one or more parts of that rule.
  • 13. Eduardo Granados Ch. Function arguments The ideal number of arguments for a function is zero Next comes one or two arguments Three arguments should be avoided where possible More than three (polyadic) requires very special justification and then shouldn’t be used anyway When a function seems to need more than two or three arguments, it is likely that some of those arguments ought to be wrapped into a class of their own: Circle makeCircle(double x, double y, double radius); Circle makeCircle(Point center, double radius);
  • 15. Eduardo Granados Ch. Functions Don’t use Use void transform(StringBuffer out); StringBuffer transform(StringBuffer in);
  • 17. Eduardo Granados Ch. Flag Arguments Passing a boolean into a function is a truly terrible practice Split the function into two Don’t use Use render(boolean isSuite); renderForSuite() renderForSingleTest();
  • 18. Eduardo Granados Ch. Have No Side Effects Your function promises to do one thing, but it also does other hidden Things Functions should either do something or answer something, but not both public class UserValidator { private Cryptographer cryptographer; public boolean checkPassword(String userName, String password) { User user = UserGateway.findByName(userName); if (user != User.NULL) { String codedPhrase = user.getPhraseEncodedByPassword(); String phrase = cryptographer.decrypt(codedPhrase, password); if ("Valid Password".equals(phrase)) { Session.initialize(); return true; } } return false; } }
  • 19. Eduardo Granados Ch. Prefer Exceptions to Returning Error Codes Don’t use Use if (deletePage(page) == E_OK) { if (registry.deleteReference(page.name) == E_OK) { if (configKeys.deleteKey(page.name.makeKey()) == E_OK) { logger.log("page deleted"); } else { logger.log("configKey not deleted"); } } else { logger.log("deleteReference from registry failed"); } } else { logger.log("delete failed"); return E_ERROR; } try { deletePage(page); registry.deleteReference(page.name); configKeys.deleteKey(page.name.makeKey()); } catch (Exception e) { logger.log(e.getMessage()); }
  • 20. Eduardo Granados Ch. COMENTS The proper use of comments is to compensate for our failure to express ourself in code Ooh, I’d better comment that!” No! You’d better clean it! Don’t use Use // Check to see if the employee is eligible for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) if (employee.isEligibleForFullBenefits()) A comment like this can sometimes be useful, but it is better to use the name of the function to convey the information where possible. // Returns an instance of the Responder being tested. protected abstract Responder responderInstance(); Here’s a case that’s a bit better: // format matched kk:mm:ss EEE, MMM dd, yyyy Pattern timeMatcher = Pattern.compile("d*:d*:d* w*, w* d*, d*");
  • 22. Eduardo Granados Ch. COMMENTS - Clarification Clarification: Sometimes it is just helpful to translate the meaning assertTrue(a.compareTo(a) == 0); // a == a assertTrue(a.compareTo(b) != 0); // a != b assertTrue(ab.compareTo(ab) == 0); // ab == ab Warning of Consequences: Sometimes it is useful to warn about certain consequences here is a comment that explains why a particular test case is turned off: // Don't run unless you // have some time to kill. public void _testWithReallyBigFile();
  • 23. Eduardo Granados Ch. FORMAT choose a set of simple rules that govern the format of code If you are working on a team, then the team should agree to a single set of formatting rules and all members should comply
  • 24. Eduardo Granados Ch. Objects and Data Structures Procedural Shape Polymorphic Shapes public class Square { public Point topLeft; public double side; } public class Rectangle { public Point topLeft; public double height; public double width; } public class Circle { public Point center; public double radius; } public class Geometry { public final double PI = 3.141592653589793; public double area(Object shape) throws NoSuchShapeException { if (shape instanceof Square) { Square s = (Square)shape; return s.side * s.side; } else if (shape instanceof Rectangle) { Rectangle r = (Rectangle)shape; return r.height * r.width; } else if (shape instanceof Circle) { Circle c = (Circle)shape; return PI * c.radius * c.radius; } throw new NoSuchShapeException(); } public class Square implements Shape { private Point topLeft; private double side; public double area() { return side*side; } } public class Rectangle implements Shape { private Point topLeft; private double height; private double width; public double area() { return height * width; } } public class Circle implements Shape { private Point center; private double radius; public final double PI = 3.141592653589793; public double area() { return PI * radius * radius; } }
  • 25. Eduardo Granados Ch. Objects and Data Structures Objects expose behavior and hide data. This makes it easy to add new kinds of objects without changing existing behaviors. It also makes it hard to add new behaviors to existing objects. Data structures expose data and have no significant behavior
  • 26. Eduardo Granados Ch. EXCEPTIONS VS ERRORS Define the Normal Flow Don’t Return Null Don’t Pass Null
  • 36. Eduardo Granados Ch. SOLID Single responsibility A class should have only a single responsibility (i.e. only one potential change in the software's specification should be able to affect the specification of the class) Open-closed software entities … should be open for extension, but closed for modification Liskov substitution objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program Interface segregation many client-specific interfaces are better than one general-purpose interface Dependency inversion one should “Depend upon Abstractions. Do not depend upon concretions”
  • 37. Eduardo Granados Ch. GRASP PATTERNS Creator Information Expert (or just Expert) Low Coupling High Cohesion Controller Polymorphism Pure Fabrication Indirection Protected Variations
  • 38. Eduardo Granados Ch. Class a class should begin with a list of variables. Public static constants, if any, should come first. Then private static variables, followed by private instance variables. There is seldom a good reason to have a public variable. Public functions should follow the list of variables. We like to put the private utilities called by a public function right after the public function itself. This follows the stepdown rule and helps the program read like a newspaper article.
  • 39. Eduardo Granados Ch. High Cohesion - Before package literatePrimes; public class PrintPrimes { public static void main(String[] args) { final int M = 1000; final int RR = 50; final int CC = 4; final int WW = 10; final int ORDMAX = 30; int P[] = new int[M + 1]; int PAGENUMBER; int PAGEOFFSET; int ROWOFFSET; int C; int J; int K; boolean JPRIME; int ORD; int SQUARE; int N; int MULT[] = new int[ORDMAX + 1]; J = 1; K = 1; P[1] = 2; ORD = 2; SQUARE = 9; while (K < M) { do { J = J + 2; if (J == SQUARE) { ORD = ORD + 1; SQUARE = P[ORD] * P[ORD]; MULT[ORD - 1] = J; } N = 2; JPRIME = true; while (N < ORD && JPRIME) { while (MULT[N] < J) MULT[N] = MULT[N] + P[N] + P[N]; if (MULT[N] == J) JPRIME = false; N = N + 1; } } while (!JPRIME); K = K + 1; P[K] = J; } { PAGENUMBER = 1; PAGEOFFSET = 1; while (PAGEOFFSET <= M) { System.out.println("The First " + M + " Prime Numbers --- Page " + PAGENUMBER); System.out.println(""); for (ROWOFFSET = PAGEOFFSET; ROWOFFSET < PAGEOFFSET + RR; ROWOFFSET++){ for (C = 0; C < CC;C++) if (ROWOFFSET + C * RR <= M) System.out.format("%10d", P[ROWOFFSET + C * RR]); System.out.println(""); } System.out.println("f"); PAGENUMBER = PAGENUMBER + 1; PAGEOFFSET = PAGEOFFSET + RR * CC; } } } }
  • 40. Eduardo Granados Ch. High Cohesion – After (1/4) Slit into three main responsibilities 1.The main program is contained in the PrimePrinter class all by itself. Its responsibility is to handle the execution environment. It will change if the method of invocation changes. For example, if this program were converted to a SOAP service, this is the class that would be affected 2.The RowColumnPagePrinter knows all about how to format a list of numbers into pages with a certain number of rows and columns. If the formatting of the output needed changing, then this is the class that would be affected. 3.The PrimeGenerator class knows how to generate a list prime numbers. Notice that it is not meant to be instantiated as an object. The class is just a useful scope in which its variables can be declared and kept hidden. This class will change if the algorithm for computing prime numbers changes.
  • 41. Eduardo Granados Ch. High Cohesion – After (2/4) package literatePrimes; public class PrimePrinter { public static void main(String[] args) { final int NUMBER_OF_PRIMES = 1000; int[] primes = PrimeGenerator.generate(NUMBER_OF_PRIMES); final int ROWS_PER_PAGE = 50; final int COLUMNS_PER_PAGE = 4; RowColumnPagePrinter tablePrinter = new RowColumnPagePrinter(ROWS_PER_PAGE, COLUMNS_PER_PAGE, "The First " + NUMBER_OF_PRIMES +" Prime Numbers"); tablePrinter.print(primes); } }
  • 42. Eduardo Granados Ch. High Cohesion – After (3/4) package literatePrimes; import java.io.PrintStream; public class RowColumnPagePrinter { private int rowsPerPage, columnsPerPage,numbersPerPage; private String pageHeader; private PrintStream printStream; public RowColumnPagePrinter(int rowsPerPage, int columnsPerPage, String pageHeader) { this.rowsPerPage = rowsPerPage; this.columnsPerPage = columnsPerPage; this.pageHeader = pageHeader; numbersPerPage = rowsPerPage * columnsPerPage; printStream = System.out; } public void print(int data[]) { int pageNumber = 1; for (int firstIndexOnPage = 0; firstIndexOnPage < data.length; firstIndexOnPage += numbersPerPage) { int lastIndexOnPage = Math.min(firstIndexOnPage + numbersPerPage - 1, data.length - 1); printPageHeader(pageHeader, pageNumber); printPage(firstIndexOnPage, lastIndexOnPage, data); printStream.println("f"); pageNumber++; } } private void printPage(int firstIndexOnPage, int lastIndexOnPage, int[] data) { int firstIndexOfLastRowOnPage = firstIndexOnPage + rowsPerPage - 1; for (int firstIndexInRow = firstIndexOnPage; firstIndexInRow <= firstIndexOfLastRowOnPage; firstIndexInRow++) { printRow(firstIndexInRow, lastIndexOnPage, data); printStream.println(""); } } private void printRow(int firstIndexInRow, int lastIndexOnPage, int[] data) { for (int column = 0; column < columnsPerPage; column++) { int index = firstIndexInRow + column * rowsPerPage; if (index <= lastIndexOnPage) printStream.format("%10d", data[index]); } } private void printPageHeader(String pageHeader, int pageNumber) { printStream.println(pageHeader + " --- Page " + pageNumber); printStream.println(""); } public void setOutput(PrintStream printStream) { this.printStream = printStream; } }
  • 43. Eduardo Granados Ch. High Cohesion – After (4/4) package literatePrimes; import java.util.ArrayList; public class PrimeGenerator { private static int[] primes; private static ArrayList<Integer> multiplesOfPrimeFactors; protected static int[] generate(int n) { primes = new int[n]; multiplesOfPrimeFactors = new ArrayList<Integer>(); set2AsFirstPrime(); checkOddNumbersForSubsequentPrimes(); return primes; } private static void set2AsFirstPrime() { primes[0] = 2; multiplesOfPrimeFactors.add(2); } private static void checkOddNumbersForSubsequentPrimes() { int primeIndex = 1; for (int candidate = 3; primeIndex < primes.length; candidate += 2) { if (isPrime(candidate)) primes[primeIndex++] = candidate; } } private static boolean isPrime(int candidate) { if (isLeastRelevantMultipleOfNextLargerPrimeFactor(candidate)) { multiplesOfPrimeFactors.add(candidate); return false; } return isNotMultipleOfAnyPreviousPrimeFactor(candidate); } private static boolean isLeastRelevantMultipleOfNextLargerPrimeFactor(int candidate) { int nextLargerPrimeFactor = primes[multiplesOfPrimeFactors.size()]; int leastRelevantMultiple = nextLargerPrimeFactor * nextLargerPrimeFactor; return candidate == leastRelevantMultiple; } private static boolean isNotMultipleOfAnyPreviousPrimeFactor(int candidate) { for (int n = 1; n < multiplesOfPrimeFactors.size(); n++) { if (isMultipleOfNthPrimeFactor(candidate, n)) return false; } return true; } private static boolean isMultipleOfNthPrimeFactor(int candidate, int n) { return candidate == smallestOddNthMultipleNotLessThanCandidate(candidate, n); } private static int smallestOddNthMultipleNotLessThanCandidate(int candidate, int n) { int multiple = multiplesOfPrimeFactors.get(n); while (multiple < candidate) multiple += 2 * primes[n]; multiplesOfPrimeFactors.set(n, multiple); return multiple; } }