0% found this document useful (0 votes)
129 views34 pages

Clean Code 04: Reinženjering Informacionih Sistema

This document discusses classes in clean code. It covers organizing classes, keeping classes short, and measuring class size by responsibility rather than lines of code. Large classes may have many methods while small classes may have high responsibility. The document also discusses class cohesion and keeping classes highly cohesive by having methods manipulate a small number of instance variables. Extracting pieces of large classes or methods into new classes or methods can improve cohesion.

Uploaded by

Sandra
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
129 views34 pages

Clean Code 04: Reinženjering Informacionih Sistema

This document discusses classes in clean code. It covers organizing classes, keeping classes short, and measuring class size by responsibility rather than lines of code. Large classes may have many methods while small classes may have high responsibility. The document also discusses class cohesion and keeping classes highly cohesive by having methods manipulate a small number of instance variables. Extracting pieces of large classes or methods into new classes or methods can improve cohesion.

Uploaded by

Sandra
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

CLEAN CODE 04

REINŽENJERING INFORMACIONIH SISTEMA


2
• Uvod
• Nazivi (Names)

• Metode/Funkcije (Functions)
• Komentari (Comments)
• Formatiranje (Formatting)

• Objekti i strukture podataka (Objects and Data Structures)


• Upravljanje greškama (Error Handling)
• Testiranje (Unit Tests)

• Klase (Classes)
• Code Smells

• Junit Internals (primer)


• Refactoring SerialData (primer)

Reinženjering informacionih sistema 2020/2021


3
Klase (Classes)

Organizacija klase:
• Počinju sa listom promenljivih:
• public static
• private static
• private
• public ?
• public metode
• private metode

Reinženjering informacionih sistema 2020/2021


4
Klase (Classes)

Klase treba da budu kratke.

Veličina klase ne meri brojem linija, nego sa odgovornošću koju preuzima.

Velike klase mogu da imaju veliki broj metoda.

„Male” klase, mogu da imaju nekoliko metoda, ali mnogo odgovornosti, pa postaju „velike” klase.

Reinženjering informacionih sistema 2020/2021


5
Klase (Classes)

public class DrawingController {


//1692 linije
private DrawingFrame view;
private DrawingModel model = new DrawingModel();

public static final int SELECTION = 1;


public static final int POINT = 2;
public static final int LINE = 3;
public static final int CIRCLE = 4;
public static final int SQUARE = 5;
public static final int RECTANGLE = 6;
public static final int HEXAGON = 7;
private int status;

private LinkedList<Command> commands = new LinkedList<Command>();


private int lastCmdIndex = -1;


Reinženjering informacionih sistema 2020/2021
6
Klase (Classes)

public class DrawingController {


//1692 linije

private LinkedList<String> commandsLog = new LinkedList<String>();


private int commandsLogIndex = 0;
private String commandsLogString;
private String[] commandsLogStringParts;
private String[] commandsLogStringPartsInner;
private String[] commandsLogStringPartsInnerParams;

private Point t;
private Line l;
private Circle k;
private Square kv;
private Rectangle p;
private HexagonAdapter h;

Reinženjering informacionih sistema 2020/2021
7
Klase (Classes)

public class DrawingController {


//1692 linije

private Point lt1;


private Point lt2;

private int desni = 1;


private int tackobrojac = 1;

private Point pointStart = new Point(-1, -1);


private Point pointEnd = new Point(-1, -1);

Reinženjering informacionih sistema 2020/2021


8
Klase (Classes)

public class DrawingController {


//1692 linije

public int getStatus(){…}


public void setStatus(int status) {…}
public void btnWhite_mouseClicked(MouseEvent e){…} // 7
public void btnBlue_mouseClicked(MouseEvent e) {…} // 7
public void btnRed_mouseClicked(MouseEvent e) {…} // 7
public void btnYellow_mouseClicked(MouseEvent e) {…} // 7
public void btnGreen_mouseClicked(MouseEvent e) {…} // 7
public void btnBlack_mouseClicked(MouseEvent e) {…} // 7
public void pnlPapir_mouseClicked(MouseEvent e) {…} //280
public void pnlPapir_mouseMoved(MouseEvent e1) {…} //33
public void pnlPapir_mouseDragged(MouseEvent ee) {…} //85

Reinženjering informacionih sistema 2020/2021


9
Klase (Classes)

public class DrawingController {


//1692 linije

public void pnlPapir_mouseDragged(MouseEvent ee) {…} //80


public void btnSet_actionPerformed(ActionEvent e) {…} //90
public void btnDelete_actionPerformed(ActionEvent e) {…} //40
public void btnOpen_actionPerformed(ActionEvent arg0)
throws FileNotFoundException, IOException, ClassNotFoundException {…} //50
public void btnSave_actionPerformed(ActionEvent arg0) {…} //50
public void btnToFront_actionPerformed(ActionEvent arg0) {…} //10
public void btnToBack_actionPerformed(ActionEvent arg0) {…} //10
private String colorTranslate(Color colorEnglish) {…} //10
private void paintOutline(Color colorOutline) {…} //60
}

Reinženjering informacionih sistema 2020/2021


10
Klase (Classes)

public class DrawingController {


//1692 linije

public void paintFill(Color colorFill) {…} //40
public void doCmd(Command c) {…} //30
public void undoCmd() {…} //10
public void redoCmd() {…} //10
public void runLog() {…} //610

Reinženjering informacionih sistema 2020/2021


11
Klase (Classes)

public class SuperDashboard extends JFrame implements MetaDataUser

public Component getLastFocusedComponent()


public void setLastFocused(Component lastFocused)
public int getMajorVersionNumber()
public int getMinorVersionNumber()
public int getBuildNumber()
}

* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship

Reinženjering informacionih sistema 2020/2021


12
Klase (Classes)

public class Version {


public int getMajorVersionNumber()
public int getMinorVersionNumber()
public int getBuildNumber()
}

* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship

Reinženjering informacionih sistema 2020/2021


13
Klase (Classes)

Kohezija (The Single Responsibility Principle)

• Klase treba da imaju mali broj varijabli instance.

• Svaka metoda klase treba da manipuliše sa jednom ili više od tih varijabli instance.

• Što je veći broj varijabli instance, od broja dostupnih, sa kojim metode manipulišu to je veća
kohezija između metoda i klasa.

• Klase u kojima sve metode manipulišu sa svim varijablama instance ima maksimalnu koheziju.

Reinženjering informacionih sistema 2020/2021


14
Klase (Classes)

Kohezija

• Ukoliko su metode kratke i manipulišu sa malim brojem varijabli instance, to može dovesti do
toga da je određene metode moguće grupisati po osnovu varijabli sa kojima manipulišu i to
može biti dobar pokazatelj da se te metode, zajedno sa varijablama instance mogu ekstrahovati
u novu klasu.

• Na taj način i klasa iz koje se vrši ekstrakcija, kao i novonastale klase imaju veću koheziju, što je
poželjna osobina za klase, jer prikazuje da su metode i klasa međusobno zavisne i da
predstavljaju jednu logičnu celinu.

Reinženjering informacionih sistema 2020/2021


15
Klase (Classes)

Kohezija

• Ukoliko imate veliku metodu u kojoj ste definisali veliki broj varijabli, trebalo bi da razmišljate o
tome da se deo metode možda može izdvojiti u neku drugu, posebnu metodu.

• Potencijalni problem je u tome što ta nova metoda treba da koristi deo varijabli definisanih u
staroj, velikoj metodi, pa može izgledati da to nije dobro rešenje i da ćete morati novoj metodi da
prosleđujete sve varijable nad kojima je potrebno vršiti operacije.

• U tom slučaju, dobra praksa bi bila da potrebne promenljive budu „promovisane“ u varijable
instanci. Tada novoj metodi nećete morati da prosleđujete bilo kakve promenljive.

Reinženjering informacionih sistema 2020/2021


16
Klase (Classes)

Kohezija

• Posledica je da imate veliki broj kratkih metoda.

• Posmatranjem tih metoda mogu se prepoznati grupe metoda koje vrše operacije nad istim, ali ne
svim, varijablama instance.

• Ta grupa metoda i varijable instanci nad kojima se vrše operacije su kandidati za izdvajanje u
neku novu klasu.

Reinženjering informacionih sistema 2020/2021


17
Klase (Classes)

Kohezija

• Ukoliko ne možete da opišete šta klasa radi u 25 reči, bez upotrebe „i“, „ili“, „ako“ i „ali“, klasa
verovatno ima previše odgovornosti.

• Napisati kod koji radi i kod koji je čist i pogodan za održavanje su dve različite stvari.

• Kada se napiše kod koji radi, to ne predstavlja završetak rada na kodu.

Reinženjering informacionih sistema 2020/2021


18
Klase (Classes)

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;

Reinženjering informacionih sistema 2020/2021


19
Klase (Classes)

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;

* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship

Reinženjering informacionih sistema 2020/2021


20
Klase (Classes)

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;
* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship
P[K] = J;
}
Reinženjering informacionih sistema 2020/2021
21
Klase (Classes)

{
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;
* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship
}
}
}
Reinženjering informacionih sistema 2020/2021
22
Klase (Classes)

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

* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship

Reinženjering informacionih sistema 2020/2021


23
Klase (Classes)

import java.io.PrintStream;

public class RowColumnPagePrinter {


private int rowsPerPage;
private int columnsPerPage;
private int 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;
}
* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship

Reinženjering informacionih sistema 2020/2021


24
Klase (Classes)

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

* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship

Reinženjering informacionih sistema 2020/2021


25
Klase (Classes)

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("");
}
}

* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship

Reinženjering informacionih sistema 2020/2021


26
Klase (Classes)

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;
}
* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship
}

Reinženjering informacionih sistema 2020/2021


27
Klase (Classes)

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);
* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship
}

Reinženjering informacionih sistema 2020/2021


28
Klase (Classes)

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);
}
* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship

Reinženjering informacionih sistema 2020/2021


29
Klase (Classes)

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

* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship

Reinženjering informacionih sistema 2020/2021


30
Klase (Classes)

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

* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship

Reinženjering informacionih sistema 2020/2021


31
Klase (Classes)

Navedeni primer ne predstavlja novo rešenje problema.

Kreirani su testovi koji pokrili tačno ponašanje aplikacije.

Potom su rađene male izmene i nakon svake male izmene pokretani su testovi.

Reinženjering informacionih sistema 2020/2021


32
Klase (Classes)

Četiri pravila jednostavnog dizajna (Kent Beck)

• Svi testovi prolaze

• Nema dupliciranog koda

• Izražava nameru programera

• Minimizira broj klasa i metoda

Reinženjering informacionih sistema 2020/2021


33
Klase (Classes)

Svi testovi prolaze

• Rezultat uspešnog dizajna je aplikacija koja radi ono što joj je bila namera.

• Možda je sistem u teoriji odlično dizajniran, ali ako ne postoji jednostavan način da se testira
dizajn ne možemo biti sigurni u i dizajn.

• Samo sistem koji je detaljno testiran i koji ima testove koji prolaze i svim uslovima predstavlja
sistem koji se jednostavno može testirati.

• Kreiranje sistema koji je jednostavan za testiranje za posledicu ima kreiranje klasa koje su male,
imaju samo jednu namenu (u skladu sa Single Responsibility Principle).

Reinženjering informacionih sistema 2020/2021


34
Klase (Classes)

Svi testovi prolaze

• Visoka sprega čini sistem teškom za testiranjem, a kreiranje testova i njihovo stalno pokretanje
vodi do niske sprege i visoke kohezije.

Refaktoring

• Kada je kod pokriven testovima, možete se posvetiti čišćenju koda.

• Svakih nekoliko linija možete uraditi refaktoring u kojem treba da primenite sve što znate o
dobrom dizajnu.

• Povećajte koheziju, smanjite spregu, preimenujte klase i metode, smanjite metode i klase itd.

• Radeći refaktoring biće isprunjena tri preosala zahteva dobrog dizajna.

Reinženjering informacionih sistema 2020/2021

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy