Kohezja, a warunki w metodzie

1

Mój przykładowy pseudokod:

class Alpha {
 private int one;
 private int two;


 pub fun doSomething(int x) 
 {
    if (x > 10) {
      return this.one;
    }

    return this.one + this.two;
 }
}

Czy sytuacja, w której klasa ma jedną metodę i dwie właściwości, która wyglada jak powyżej.
Tj. używa jednej właściwości w warunki, ale poza nim już obu łamie kohezje czy nie?
Niby obie właściwości są użyte w metodzie, ale nie zawsze razem.

Szukałem na necie odpowiedzi na to pytanie, ale ciężko było mi znaleźć tego typu przykład.

1

A którą linijkę tak konkretnie podejrzewasz o łamanie kohezji?

0

9, w if'ie wykorzystujemy tylko jedną właściwość, a to łamie spójność metody według autora tej książki -> https://helion.pl/ksiazki/programowanie-zorientowane-obiektowo-wzorce-projektowe-wydanie-ii-alan-shalloway-james-r-trott,prob2v.htm#format/d

wracajac do kohezji, ja wiem, żę chodzi tam o stosunek wykorzystania właściwość w metodach klasy
tutaj zakładamy, że metoda jest jedna i w swoim ciele wykorzystuje wszystkie propertki, ale jednocześnie wchodząc do warunku w linii 8 mamy zakończenie pracy metody z wykorzystaniem jednej właściwości - to mnie zastanawia, czy takie rozwiązanie nie zmniejsza kohezji klasy

Może lekko zmodyfikujemy przykład i zrobimy tak

class Alpha {
 private int one;
 private int two;


 pub fun doSomething(int x) 
 {
    if (x > 10) {
      return this.one;
    }

    return this.two;
 }
}

1

Jak cię to tak boli to może (będzie w Scali bo w pseudokodu nie umiem):

class Alpha(one: Int, two: Int) {
 def doSomething(x: Int) = one + (if (x > 10) 0 else two)
}

Powtórzeń nie ma. Za to zawsze jest dodawanie

1

@Kuba Leman: Jak autor, wspomnianej książki, definiuje kohezję?

Może sens został zatracony gdzieś w tłumaczeniu, w angielskim masz terminy "coherence" i "cohesion", które tłumaczone na polski mogą skończyć jako "spójność".
"cohesion" w pewnym sesnie jest podzbiorem "coherence", żeby coś było spójnie ("coherent") musi mieć odpowiednią (chciałoby się napisać spójną) strukturę ("cohesion").

To, że metoda robi "coś" i w swojej strukturze odnosi się do "właściwości A oraz B", nie mówi nam nic o spójności.
Przykłady z d**y, gdzie obydwa warianty mają tę samą strukturę, ale na pierwszy rzut oka coś jest nie tak w doSomething.

pub fun doSomething(int wiek) 
  if (wiek > 10) {
    return this.waga;
  }

  return this.wzrost;
}
pub fun oblicz_zmiane_napiecia(int opor) 
  if (opor > 10) {
    return this.stopien_zwiekszenia_napiecia;
  }

  return this.stopien_zmniejszenia_napiecia;
}

Czy składowe są pogrupowane w logiczny sposób? Tak = wysoka kohezja, Nie = niska kohezja.

Wracając do Twojego przykładu:

 pub fun doSomething(int x) 
 {
    if (x > 10) {
      return this.one;
    }

    return this.two;
 }

Czy da się jednoznacznie powiedzieć na takim przykładzie, czy te właściwości użyte są w metodzie w logiczny sposób?

1
Kuba Leman napisał(a):

Mój przykładowy pseudokod:

class Alpha {
 private int one;
 private int two;

 pub fun doSomething(int x) 
 {
    if (x > 10) {
      return this.one;
    }

    return this.one + this.two;
 }
}

Czy sytuacja, w której klasa ma jedną metodę i dwie właściwości, która wyglada jak powyżej.
Tj. używa jednej właściwości w warunki, ale poza nim już obu łamie kohezje czy nie?
Niby obie właściwości są użyte w metodzie, ale nie zawsze razem.

Moim zdaniem nie powinieneś się tym przejmować z conajmniej trzech powodów:

  • Po pierwsze, jako użytkownik klasy Alpha nie powinno mnie obchodzić jak liczona jest ta wartość, więc jako użytkownika tej klasy ciężko to ocenić.
  • Po drugie, może powinieneś podać inny przykład, bo ten konkretny co podałeś można bardzo łatwo zmienić tak żeby używał zawsze tyle samo property, tzn zrobić metodę która zwraca this.two albo 0, i potem wynik dodać do this.one.
  • Po trzecie, te zasady o kohezję, one mają sens tylko w pewnym obszarze rozwijania oprogramowania. Jak pociągniesz jakąkolwiek "złotą zasadę" za daleko, to zawsze prędzej czy później dojdziesz do bezsensownych wyników. Np w tym wypadku z mnożeniem, mógłbyś tak zrefaktorować kod, żeby zrobić coś w stylu (1-max(0, min(x/10, 1))) * this.two + this.one i teraz niby linijka używa dwóch zmiennych, ale działa tak samo. To z kolei znowu wraca do punktu 1., czyli jeśli z punktu widzenia interfejsu klasy nie ma różnicy, to ja bym olał temat.

Te "złote zasady" mają sens tylko w pewnym wąskim obszarze, i są bardziej (jak powiedział Gibbs w "Piratach z Karaibów") "are more like guidelines, than actual rules". Nie należy ich brać dosłownie i rozciągać ich obszaru użycia w nieskończoność.

1

Wiadomo, że każdy przypadek jest inny więc ciężko teoryzować. Bardziej szukałbym odpowiedzi na pytanie czy da się to podzielić tak, żeby kohezja była większa. Jak nie, to nie da się lepiej

1 użytkowników online, w tym zalogowanych: 0, gości: 1