SlideShare a Scribd company logo
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

More Related Content

What's hot

ES3-2020-07 Testing techniques
ES3-2020-07 Testing techniquesES3-2020-07 Testing techniques
ES3-2020-07 Testing techniques
David Rodenas
 
Ip project visual mobile
Ip project visual mobileIp project visual mobile
Inside PyMongo - MongoNYC
Inside PyMongo - MongoNYCInside PyMongo - MongoNYC
Inside PyMongo - MongoNYC
Mike Dirolf
 
IP project for class 12 cbse
IP project for class 12 cbseIP project for class 12 cbse
IP project for class 12 cbse
siddharthjha34
 
Ip project work test your knowledge
Ip project work test your knowledgeIp project work test your knowledge
Ip project work test your knowledge
Kï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 Testing
David Rodenas
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012Yaqi Zhao
 
Clean code
Clean codeClean code
Clean code
Henrique Smoco
 
Magic methods
Magic methodsMagic methods
Magic methods
Matthew Barlocker
 
PHP 5 Magic Methods
PHP 5 Magic MethodsPHP 5 Magic Methods
PHP 5 Magic Methods
David Stockton
 
Clean Code: Chapter 3 Function
Clean Code: Chapter 3 FunctionClean Code: Chapter 3 Function
Clean Code: Chapter 3 Function
Kent 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 Speed
Pascal-Louis Perez
 
Inheritance and-polymorphism
Inheritance and-polymorphismInheritance and-polymorphism
Inheritance and-polymorphism
Usama 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 code
Geshan Manandhar
 
Design pattern - part 1
Design pattern - part 1Design pattern - part 1
Design pattern - part 1
Jieyi Wu
 

What's hot (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 to Presentacion clean code

Clean code
Clean codeClean code
Clean code
Arturo Herrero
 
Clean Code
Clean CodeClean Code
Clean Code
Nascenia IT
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
R696
 
Clean code & design patterns
Clean code & design patternsClean code & design patterns
Clean code & design patterns
Pascal Larocque
 
Jeremiah Caballero - Introduction of Clean Code
Jeremiah Caballero - Introduction of Clean CodeJeremiah Caballero - Introduction of Clean Code
Jeremiah Caballero - Introduction of Clean Code
Awesome 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 abstraction
Intro 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 Scenario
Tara Hardin
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better Programmer
Srikanth Shreenivas
 
Chapter 2
Chapter 2Chapter 2
JavaScript lesson 1.pptx
JavaScript lesson 1.pptxJavaScript lesson 1.pptx
JavaScript lesson 1.pptx
MuqaddarNiazi1
 
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 Design
WebStackAcademy
 
What's in a name
What's in a nameWhat's in a name
What's in a name
Koby Fruchtnis
 
Encapsulation
EncapsulationEncapsulation
Encapsulation
Ducat India
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
HongAnhNguyn285885
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
ciklum_ods
 
TWINS: OOP and FP - Warburton
TWINS: OOP and FP - WarburtonTWINS: OOP and FP - Warburton
TWINS: OOP and FP - Warburton
Codemotion
 
Struts 2 + Spring
Struts 2 + SpringStruts 2 + Spring
Struts 2 + Spring
Bryan Hsueh
 

Similar to Presentacion clean code (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
 

Recently uploaded

Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
Matt Welsh
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
informapgpstrackings
 
Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)
abdulrafaychaudhry
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Natan Silnitsky
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
abdulrafaychaudhry
 
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi ArabiaTop 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
Yara Milbes
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
Enterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptxEnterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptx
QuickwayInfoSystems3
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 

Recently uploaded (20)

Large Language Models and the End of Programming
Large Language Models and the End of ProgrammingLarge Language Models and the End of Programming
Large Language Models and the End of Programming
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)Introduction to Pygame (Lecture 7 Python Game Development)
Introduction to Pygame (Lecture 7 Python Game Development)
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
 
Pro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp BookPro Unity Game Development with C-sharp Book
Pro Unity Game Development with C-sharp Book
 
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi ArabiaTop 7 Unique WhatsApp API Benefits | Saudi Arabia
Top 7 Unique WhatsApp API Benefits | Saudi Arabia
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
Enterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptxEnterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptx
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 

Presentacion clean code

  • 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; } }