Clean Code 02
Clean Code 02
Clean Code 02
• Klase (Classes)
• Code Smells
public static String testableHtml( PageData pageData, boolean includeSuiteSetup) throws Exception {
WikiPage wikiPage = pageData.getWikiPage();
StringBuffer buffer = new StringBuffer();
if (pageData.hasAttribute("Test")) {
if (includeSuiteSetup) {
WikiPage suiteSetup = PageCrawlerImpl.getInheritedPage(SuiteResponder.SUITE_SETUP_NAME, wikiPage);
if (suiteSetup != null) {
WikiPagePath pagePath = suiteSetup.getPageCrawler().getFullPath(suiteSetup);
String pagePathName = PathParser.render(pagePath);
buffer.append("!include -setup .").append(pagePathName).append("\n");
}
}
if (pageData.hasAttribute("Test")) {
WikiPage teardown = PageCrawlerImpl.getInheritedPage("TearDown", wikiPage);
if (teardown != null) {
WikiPagePath tearDownPath = wikiPage.getPageCrawler().getFullPath(teardown);
String tearDownPathName = PathParser.render(tearDownPath);
buffer.append("\n")
.append("!include -teardown .").append(tearDownPathName).append("\n");
}
if (includeSuiteSetup) {
WikiPage suiteTeardown =
PageCrawlerImpl.getInheritedPage( SuiteResponder.SUITE_TEARDOWN_NAME,wikiPage);
if (suiteTeardown != null) {
WikiPagePath pagePath = suiteTeardown.getPageCrawler().getFullPath (suiteTeardown);
String pagePathName = PathParser.render(pagePath);
buffer.append("!include -teardown .").append(pagePathName).append("\n");
}
}
}
pageData.setContent(buffer.toString());
return pageData.getHtml();
}
* Robert C. Martin - Clean Code: A Handbook of Agile Software Craftsmanship
Ukoliko imate selekcije ili iteracije, one ne bi trebalo da imaju više od jedne linije. Ukoliko je
potrebno da ima više linije, onda bi trebalo da koristite poziv neke druge metode.
Treba izbegavati ugnežđene strukture i ograničiti „dubinu“ na jednu ili dve strukture.
Metode treba da rade jednu stvar. Treba da je rade dobro. То treba da bude jedina stvar koju rade.
The Stepdown Rule – želimo da svaku funkciju prate druge funkcije koje se nalaze na narednom
nivou apstrakcije.
Funkcije koje nisu na istom nivou apstrakcije i koje ne obavljaju samo jednu stvar, teško možete
podeliti u sekcije.
Switch statements:
• Dugačke.
Argumenti funkcije:
• Idealan broj argumenata koje funkcija treba da ima je nula
Razlozi:
• Otežano razumevanje koda
public void trimExtraSpaces(String s) - povratni tip podatka je String nad kojim je vršena operacija
- appendFooter(s)
- appendFooter(s);
- appendFooter(s);
Generalno, bilo bi mnogo bolje kada bi se this koristilo kao povratni argument
• report.appendFooter();
Ukoliko postoji potreba za više argumenata, postoji mogućnost da se neki od argumenata smeste u
objekat:
• public Circle(int x, int y, int radius)
• public Circle(Point p, int radius)
Nazivi argumenata
• write(s)
• write(status)
Metode treba da rade nešto ili da odgovaraju na neko pitanje, ne treba da rade i jedno i drugo.
Postavlja vrednost attribute na value i vraća true ukoliko atribut sa vrednošću attribute postoji, a false
ukoliko ne postoji.
if(set(“username”,“testuser”))
try/catch blokovi
• ukoliko metoda treba da ima try/catch blok neka počne sa try i ne bi trebalo da ima ništa nakon
catch/final
try/catch blokovi
try/catch blokovi
• pre nego što komitujete kod koji ste napisali, uradićete refaktoring/reinženjering, učinićete ga
čistim/čistijim, nastaće nove klase, nove metode, i taj proces ne bi trebalo da bude „strašan“, jer
imati testove koji će vam pomoći u ovom zadatku.
Pitanja?
package shapes;
//prazan konstruktor
public Point() {
}
//konstruktor koji kreira tacku sa koordinatama i bojom koje su prosledjene kao argumenti
public Point(int x, int y, Color color) {
this(x, y);
setColor(color);
}
• Mogu da pomognu
• Mogu da pomognu
assertTrue(a.compareTo(a) == 0); // a == a
assertTrue(a.compareTo(b) != 0); // a != b
assertTrue(ab.compareTo(ab) == 0); // ab == ab
assertTrue(a.compareTo(b) == -1); // a < b
assertTrue(aa.compareTo(ab) == -1); // aa < ab
assertTrue(ba.compareTo(bb) == -1); // ba < bb
assertTrue(b.compareTo(a) == 1); // b > a
assertTrue(ab.compareTo(aa) == 1); // ab > aa
assertTrue(bb.compareTo(ba) == 1); // bb > ba
}*
• Mogu da pomognu
//checks is student has required average grade to enroll into phd studies
if(student.getAverageGrade()>AVERAGE_GRADE_REQUIREMENT)
Vertikalno formatiranje
• Koliko linija koda treba da bude u jednoj klasi?
o zavisi od toga šta klasa rad
▪ najčešće ipak zavisi od toga kako je kod pisan
▪ poželjno je da klase imaju što manji broj linija
public class Point extends Shape { public class Point extends Shape {
private int x; private int x;
private int y; private int y;
public Point(int x, y, Color color) {
public Point(int x, int y, Color color) { this.x = x;
this.x = x; this.y = y;
this.y = y; setColor(color);
setColor(color); }
} public void moveTo(int x, int y) {
this.x = x;
public void moveTo(int x, int y) { this.y = y;
this.x = x; }
this.y = y;
} }
public class Point extends Shape { public class Point extends Shape {
private int x; private int x;
private int y; private int y;
Deklarisanje varijabli
• Varijable treba da budu deklarisane što je moguće bliže kodu u kojem će se koristiti
• Varijable koje se koriste u iteracijama, treba da budu deklarisane unutar iteracije
• Varijable instance treba da budu deklarisane na početku klase
Vertikalno formatiranje
• Metode između kojih postoji zavisnost, treba da budu blizu jedna druge u vertikalnom
formatiranju, naravno, onoliko koliko je to moguće.
• Metode koje pripadaju istim logičkim segmentima, treba da budu vertikalno bliske.
@Override
public void draw(Graphics g) {
g.setColor(getColor());
g.drawOval(this.getCenter().getX() - this.radius, getCenter().getY() - getRadius(),
this.getRadius() * 2, this.getRadius() * 2);
fill(g);
if (isSelected()) {
g.setColor(Color.BLUE);
g.drawRect(getCenter().getX() - 3, getCenter().getY() - 3, 6, 6);
g.drawRect(getCenter().getX() + getRadius() - 3, getCenter().getY() - 3, 6, 6);
g.drawRect(getCenter().getX() - getRadius() - 3, getCenter().getY() - 3, 6, 6);
g.drawRect(getCenter().getX() - 3, getCenter().getY() + getRadius() - 3, 6, 6);
g.drawRect(getCenter().getX() - 3, getCenter().getY() - getRadius() - 3, 6, 6);
g.setColor(Color.BLACK);
}
}
@Override
public void moveBy(int byX, int byY) {
center.moveBy(byX, byY);
}
@Override
public int compareTo(Object o) {
if (o instanceof Circle) {
return (this.radius - ((Circle) o).radius);
}
return 0;
}
@Override
public void fill(Graphics g) {
g.setColor(getInsideColor());
g.fillOval(this.getCenter().getX() + 1 - this.radius, getCenter().getY() + 1 - getRadius(),
(this.getRadius() - 1) * 2, (this.getRadius() - 1) * 2);
}
…
@Override
public void draw(Graphics g) {
…
fill(g);
if (isSelected()) {
drawSelection(g);
}
}
Horizontalno formatiranje
Horizontalno formatiranje
Izbegavati
• pisanje „kratkih“ metoda u jednoj liniji
public CodeAnalyzer() {
lineWidthHistogram = new LineWidthHistogram();
}
Pitanja?