Jakie są wasze opinie nt małych haczków/odstąpień od paradygmatu

2

Pytanko kierowane głównie do ludzi, którzy znają różnice pomiędzy paradygmatami obiektowymi, funkcyjnymi i pozostałymi; średnio interesuje mnie opinia ludzi w stylu "Piszę w OOP ale czasem zrobię zmienną globalną".

A więc tak, mam kilka projektów, które napisałem całkowicie obiektowo w TDD; język nie istotny. I zrobiłem to najbardziej obiektowo jak mogłem; czyli:

  • Zero zmiennych i metod statycznych, brak zmiennych globalnych
  • Prawie wszystkie obiekty są immutable (kolekcje, parsery, etc.), oprócz kilku które dotykają IO, bo się nie dało
  • Każdy obiekt coś enkapsuluje, i ma swoją tożsamość.
  • Nie ma getterów, obiekty rodzą tylko inne obiekty
  • Wszystkie klasy są krótsze niż 100 linijek
  • Wszystkie funkcje są krótsze niż 6-7 linijek, większość 2-4.
  • Nie ma żadnych service'ów, singletonów, etc.
  • Nie mam obiektów typu Manager, Producer, Parser, Controller, Sender, Fetcher, Reader, tylko prawdziwie obiektowe nazwy jak np Subpattern, SentMail, FilePermission, ClassName, etc.

Zrobiłem sobie to jako taki exercise czy się da, bo sądziłem że się da, i się da. Wydaje mi się że cały projekt jest obiektowy.

I teraz doszedłem do dziwnego przypadku. Mam sparsować string; string którego format jak 150 jest zbudowany tak żeby dało się go łatwo i iteratywnie parsować w C.

Zasady jakimi rządzi się parsowanie tego stringa to:

  • Możę zawierać cyfty, litery a-z, i kilka znaków specjalnych, ale nie może zacząć się od cyfry
  • Znaki na początku muszą być z małej litery, potem, po pewnym znaku specjalnym muszą być od wielkiej
  • jest też jeden znak który jest takim "wildcard"em i znaczy to samo co wszystkie wielkie litery

Muszę też ogarnąć przypadki żeby program się wywalił jak jest więcej niż jeden znak specjalny, i jeśli znak specjalny wystąpi po wildcardzie. Iteratywnie to jest mega prosto zrobić, zresztą po samym zadaniu to widać "po", "więcej niż jeden", "na początku", etc.

I teraz; na początku zrobiłem pod to testy i napisałem całość całkowicie immutable, czyli split najpierw całego stringa po tym znaku specjalnym, + wyjątek jak jest ich więcej, potem split po wildcardzie, potem parsowanie liter najpierw dużych i małych, straszny burdel się z tego zrobił. Całość faktycznie moim zdaniem wyglądała na obiektową, bo wszystko było immutable, wszystkie funkcje były bez stanowe, takie "pure", i próbowałem to potem zrefaktorować, bo idea tego kodu jest prosta; wydawałoby się że powinno się to móc łatwo sparsować, ale maksymalnie mi się to udało zrefaktorować do 6 funkcji po 3-4 linijki.

Potem stwierdziłęm, jak by to wyglądało proceduralnie. Czyli zrobiłem sobie stanowy obiekt, coś jak StringBuilder, tylko dopasowany pod ten string, i zrobiłęm fora. For leciał po każdym znaku, i zmieniał stan. I co :o Cały algorytm w jednej funkcji na 8 linijek, bo to był for, z trzema ifami który wołał metody tego mutable buildera.

No właśnie, tylko builder był mutable. Tak to wyglądało

private function parsedSet(string $flagString): Set
{
   $syntax = new ConnectionStringSyntax($this->flags);
   foreach (\str_split($flagString) as $letter) {
     if ($letter === '|') {
         $syntax->wildcardAllUppercase();
     } else if ($letter === '>') {
         $syntax->onlyUppercase();
     } else {
         $syntax->addNextLetter($letter); // ten dodaje uppercase lub lowercase zależnie od tego czy ->onlyUppercase() było już zawołane
     }
   }
   return $syntax->entities();
}

Po rozważaniach zrozumiałem: tak się dzieje dlatego że format tego stringa został stworzony z myślą o tym, żeby go iteratywnie parsować, jak w C; a nie z myślą o tym żeby osobnymi funkcjami dało się łatwo coś z niego wyciągnąć.

I tu pytanie o waszą opinie:

  • Z jednej strony, mutable w OOP złe. OOP nie dopuszczam mutowalności.
  • Z drugiej jednak, cała "mutowalność" tego ConnectionStringSyntax jest zamknięta w tej jednej funkcji parsedSet()
  • Z trzeciej jednak, żeby to podzielić bardziej na funkcyjki należałoby i tak "rozprzestrzenić" tą mutowalność na więcej funkcji, co mi się wydaje nie do końca dobre.
  • Z czwartej jednak, nie po to się pisze w OOP żeby mieć mutowalność gdziekolwiek
  • Z piątej jednak; kod iteratywny jest 3-4 razy krótszy
  • Z szósetej zaś; może jest jakiś sposób żę da się sparsować całkowicie immutable ten string, tylko nie wpadłem na to i to jest okazja dla mnie żeby się czegoś nauczyć?

I proszę mi nie wyjeżdżać z żadnymi "pragmatyzm vs puryzm", uprzejmie dziękuję.

Wszelakim głosicielom "hybrydowych paradygmatów" też dziękuję bo nie tego tyczy się wątek.

Mam inne projekty których nie pisze w zgodzie z jednym paradygmatem, ale ten wątek i ten projekt jest o całkowicie obiektowym kodzie, więc proszę nie schodzić na off-top i odradzać takie podejście w tym wątku, dziękuję.

Podsumowanie wątku

  • Argumenty za:

    • @Afish: złamanie paradygmatu nie budzi wtf'ów
  • Argumenty przeciw:

    • soon
0

array leksemów zamiast buildera
jako że jest to basic primitve, to można zignorować tą "złą" mutability którą popełniasz w swoim builderze

No właśnie, tylko builder był mutable. Tak to wyglądało
Z jednej strony, mutable w OOP złe.

W jaki sposób tutaj to jest złe?

Serio, to wygląda tak jakbyś wbijał gwoździa za pomocą młotka, piły i buta, przemyślał sobie wady i zalety każdego z nich, ale się z nimi nie zgadzał i chciał aby to but wygrał.

Uwiązywanie się do jednego podejścia/paradygmatu/architektury/sposobu/wybranych/principles to ograniczanie się, imo.

3
TomRiddle napisał(a):
  • Z jednej strony, mutable w OOP złe.

Nie - to zdaniem niektórych OOP jest złe, bo jest z definicji mutowalne.

I proszę mi nie wyjeżdżać z żadnymi "pragmatyzm vs puryzm", uprzejmie dziękuję.

W takim razie nie da się odpowiedzieć na zadane pytanie.

Zadam więc swoje - czemu "nieważne jaki język" wygląda jak PHP?

0
somekind napisał(a):
TomRiddle napisał(a):
  • Z jednej strony, mutable w OOP złe.

Nie - to zdaniem niektórych OOP jest złe, bo jest z definicji mutowalne.

Miałem na myśli "z jednej strony OOP nie dopuszcza mutowalności". Poprawiłem w poście.

I proszę mi nie wyjeżdżać z żadnymi "pragmatyzm vs puryzm", uprzejmie dziękuję.

W takim razie nie da się odpowiedzieć na zadane pytanie.

To jeszcze poczekajmy na opinię tych, którzy twierdzą odwrotnie :>

Zadam więc swoje - czemu "nieważne jaki język" wygląda jak PHP?

Jestem zdania że paradygmat jest nie zależny od języka.

0

A wziales pod uwage fakt, że OOP nie do wszystkiego zawsze idealnie pasuje? :)

0
Charles_Ray napisał(a):

A wziales pod uwage fakt, że OOP nie do wszystkiego zawsze idealnie pasuje? :)

Oczywiście.

Nawet opisałem to jak bardzo nie pasuje w moim pierwszym poście.

4

No to ja sie zgubilem. O jaka opinie prosisz, na temat czego? Przepraszam, ale ze sciany tekstu ciezko mi cherry-pickowac konretne pytania ;)

0

@TomRiddle:

Jestem zdania że paradygmat jest nie zależny od języka.

Język implementuję jakąś tam interpretacje paradygmatu, więc dlaczego nie zależy?

2

Nie do końca rozumiem OP?

Z jednej strony:

Jakie są wasze opinie nt małych haczków/odstąpień od paradygmatu

Z drugiej strony:

I proszę mi nie wyjeżdżać z żadnymi "pragmatyzm vs puryzm", uprzejmie dziękuję.

Wszelakim głosicielom "hybrydowych paradygmatów" też dziękuję bo nie tego tyczy się wątek.

Mam inne projekty których nie pisze w zgodzie z jednym paradygmatem, ale ten wątek i ten projekt jest o całkowicie obiektowym kodzie, więc proszę nie schodzić na off-top i odradzać takie podejście w tym wątku, dziękuję.

Pytasz w tytule o opinie na temat "haczków/odstąpień od paradygmatu", ale w treści stanowczo stwierdzasz, że w tym projekcie nie dopuszczasz żadnych "haczków/odstąpień od paradygmatu" i prosisz, by nikt ci ich nie proponował. To wygląda na sprzeczność?

0
Charles_Ray napisał(a):

No to ja sie zgubilem. O jaka opinie prosisz, na temat czego? Przepraszam, ale ze sciany tekstu ciezko mi cherry-pickowac konretne pytania ;)

YetAnohterone napisał(a):

Pytasz w tytule o opinie na temat "haczków/odstąpień od paradygmatu", ale w treści stanowczo stwierdzasz, że w tym projekcie nie dopuszczasz żadnych "haczków/odstąpień od paradygmatu" i prosisz, by nikt ci ich nie proponował. To wygląda na sprzeczność?

Chciałem opinii ludzi z różnych perspektyw, powodów za i przeciw, zderzenia ze sobą poglądów, porównania dwóch podejść, podawania sensownych argumentów, wniosków płynących z rozumnych rozważań; od osób biorących pod uwagę oba rozwiązania, i potrafiących mieć dystansu do obu na tyle, by móc prowadzić rozmowe na temat ich obu.

Nie interesuję mnie wpisy, których autorzy automatycznie rzucają wyczuone, dychotomiczne, niedoinformowane "tak" albo "nie".

2

Odpowiadajac na pytanie postawione w tytule. Podobnie mozna by spytac, czy trawnik kosic kosiarka czy robic male odstepstwa na chwasty przy krawezniku. Czyli - dobierać narzedzie do problemu, a nie odwrotnie. Simple as that.

Jaki jest benefit z trzymania sie kurczowo jednego paradygmatu w calym code base? To mi smierdzi na kilometr podejsciem 0-1.

0
Charles_Ray napisał(a):

Jaki jest benefit z trzymania sie kurczowo jednego paradygmatu w calym code base? To mi smierdzi na kilometr podejsciem 0-1.

To może być dobry eksperyment.

Z własnego doświadczenia można zobaczyć wady i zalety danego paradygmatu, zobaczyć, do czego on pasuje, a do czego nie.

Gdyby OP zadał pytanie w rodzaju: "Napisałem projekt według mojej interpretacji OOP, która wygląda tak a tak, ale tutaj mam zgrzyt, czy to znaczy, że źle dobrałem narzędzie do problemu, czy też można jakoś sensownie ten problem rozwiązać trzymając się ograniczeń, które sobie narzuciłem (czyli że źle używam narzędzia) i jeśli można, to jak to zrobić?" Wtedy pytanie wydawałoby mi się zrozumiałe.

Chyba, że OP właśnie o to pyta.

5

W której przypowieści Jezus mówił o immutability w OOP, bo sobie nie przypominam?

1

Dziękuję wszystkim za odpowiadanie na dokładnie nie te pytania o której mi chodziło. Zamykam już wątek.

6
TomRiddle napisał(a):

Dziękuję wszystkim za odpowiadanie na dokładnie nie te pytania o której mi chodziło. Zamykam już wątek.

W swoim tytułowym poście zadałeś jedno pytanie

może jest jakiś sposób żę da się sparsować całkowicie immutable ten string, tylko nie wpadłem na to i to jest okazja dla mnie żeby się czegoś nauczyć?

Tak więc odpowiadam - tak, masz teraz okazję żeby się czegoś nauczyć.

0

Spodziewałem się rozpocząć jakąś inteligentną rozmowę nt paradygmatów; gdzie każdy pomysł spotkałby się z analizą i zrozumieniem.

Jednak w wątku pojawiły się tylko popularne opinie niecierpiące kontrargumentów; ewentualnie zajmowanie skrajnych stanowisk.

0

Czy ty właśnie stworzyłeś hybrydę? Skąd pomysł w ogóle na taki hack? Piszesz w OOP więc się tego trzymaj - koniec kropka.

2

Jestem zdania że paradygmat jest nie zależny od języka.

To poproszę o monady w C - Option, Either, Future, IO.
Albo OOP w Haskellu.

10

Ten cały wątek to jakiś rak, wciskanie ludziom że chcesz dyskutować a potem ich besztanie za dygresje.
Weź zaimplementuj jakikolwiek automat stanowy i nie męcz siebie i innych paradygmatami.
https://robertgawron.blogspot.com/2011/04/finite-state-machine-for-parsing.html

1

Jednak w wątku pojawiły się tylko popularne opinie niecierpiące kontrargumentów; ewentualnie zajmowanie skrajnych stanowisk.

to jest naprawdę genuine question

No właśnie, tylko builder był mutable. Tak to wyglądało
Z jednej strony, mutable w OOP złe.
W jaki sposób tutaj to jest złe?

co jest złego w mutable builderze?

Jeżeli chodzi o lexery, to ja implementuje je przykładowo w taki sposób

public List<LexElement> GenerateLexemes()
{
	Reset();

	do
	{
		if (char.IsWhiteSpace(_Current))
			_State = LexingState.WhiteCharacter;
		else if (char.IsLetter(_Current))
			_State = LexingState.Word;
		else if (char.IsNumber(_Current))
			_State = LexingState.NumericalValue;
		else if (_Current == '"')
			_State = LexingState.String;
		else if (LexingFacts.OtherTokens.Contains(_Current))
			_State = LexingState.Character;
		else
			_State = LexingState.Unknown;

		Handle(_State);
	} while (MoveNext());

	return _Elements;
}

private void Handle(LexingState state)
{
	switch(state)
	{
		case LexingState.Word:
			HandleWord();
			break;
		case LexingState.String:
			HandleString();
			break;
		case LexingState.NumericalValue:
			HandleNumericalValue();
			break;
		case LexingState.Character:
			HandleOtherCharacter();
			break;
		case LexingState.WhiteCharacter:
			HandleWhiteCharacter();
			break;
		case LexingState.Unknown:
			throw new Exception("Unrecognized token");
	}
}

private void HandleWhiteCharacter()
{
	if (_Current.ToString() == Environment.NewLine)
	{
		_CurrentLine++;
		_LastIndexOfNewLine = _Index;

		if (Settings.NewLineAware)
		{
			_Elements.Add(new LexElement(LexingElement.NewLine, GetDiagnostics()));
		}
		return;
	}

	if (_Current == '\r')
	{
		var ahead = TryGetAhead(1);

		if (ahead.Sucess && ahead.Items[0] == '\n')
		{
			_CurrentLine++;
			_LastIndexOfNewLine = _Index;

			if (Settings.NewLineAware)
			{
				_Elements.Add(new LexElement(LexingElement.NewLine, GetDiagnostics()));
			}

			return;
		}
	}
}

private void HandleOtherCharacter()
{
	var diag = GetDiagnostics();
	var ordered = LexingFacts.CombinedMap.OrderByDescending(x => x.Key.Length).ToList();

	void AddElement(string tmp)
	{
		var first = ordered.First(x => x.Key == tmp);
		_Elements.Add(new LexCharacter(first.Value, diag));
	}

	var tmp = "";
	do
	{
		var lookUpValue = tmp + _Current;
		if (LexingFacts.CombinedMapKeys.Contains(lookUpValue))
		{
			tmp += _Current;

			if (IsLast())
			{
				AddElement(tmp);
				return;
			}
		}
		else
		{
			AddElement(tmp);
			MoveBehind();
			return;
		}
	} while (MoveNext());
}

private void HandleNumericalValue()
{
	void AddElement(string tmp)
	{
		if (!int.TryParse(tmp, out var _) && !double.TryParse(tmp, NumberStyles.Float, CultureInfo.InvariantCulture, out var _))
			Error($"'{tmp}' is not correct numerical value");

		var element = new LexNumericalLiteral(tmp, GetDiagnostics());
		_Elements.Add(element);
	}

	var tmp = "";
	var legal = new char[] { '.' };

	do
	{
		if (!char.IsNumber(_Current) && !legal.Contains(_Current))
		{
			AddElement(tmp);
			MoveBehind();
			return;
		}
		else if (IsLast())
		{
			if (IsLast()) tmp += _Current;
			AddElement(tmp);
			return;
		}

		tmp += _Current;
	} while (MoveNext());
}

private void HandleString()
{
	var tmp = "";

	while (MoveNext())
	{
		if (_Current == '"' && HasPreviousElement() && ElementAt(_Index - 1) != LexingFacts.EscapeChar)
		{
			var element = new LexStringLiteral(tmp, GetDiagnostics());
			_Elements.Add(element);
			return;
		}

		tmp += _Current;
	}

	Error("Unclosed string");
}

private void HandleWord()
{
	var tmp = "";

	void AddElement()
	{
		LexElement element;
		if (LanguageFacts.KeywordMapper.TryGetValue(tmp, out var lexingElement))
		{
			element = new LexKeyword(tmp, lexingElement, GetDiagnosticsAtIndex(tmp.Length));
		}
		else
		{
			element = new LexWord(tmp, GetDiagnosticsAtIndex(tmp.Length));
		}

		_Elements.Add(element);
	}

	do
	{
		if (char.IsWhiteSpace(_Current) || IsLast())
		{
			if (IsLast()) tmp += _Current;

			AddElement();

			if (!IsLast())
				MoveBehind();

			return;
		}

		if (LexingFacts.OtherTokens.Contains(_Current))
		{
			AddElement();
			MoveBehind();
			return;
		}

		tmp += _Current;
	} while (MoveNext());
}

0

@1a2b3c4d5e: Dzięki za odpowiedź.

Tylko właśnie, ja nie potrzebuje zrobić parsera, lexera ani tokenizera; i raczej nie będę bo format tego connection stringa jest stały i się raczej nie zmieni.

9
TomRiddle napisał(a):

Miałem na myśli "z jednej strony OOP nie dopuszcza mutowalności". Poprawiłem w poście.

OOP z definicji jest oparte o mutowalność, zasadniczą ideą obiektów jest to, że manipulują one swoim stanem.
Niestety, takie manipulowanie stanem w praktyce często okazuje się problematyczne, więc dobrą praktyką jest ograniczanie jego użycia do miejsc, w których jest to absolutnie niezbędne.
Ale mutowanie w OOP jest normalne, i nie ma go co na siłę unikać. Ja nie widzę problemu z użyciem mutowalnego buildera.

To jeszcze poczekajmy na opinię tych, którzy twierdzą odwrotnie :>

I jak idzie?

Ktoś chyba musi Cię uświadomić, a że chętnych brak, to ja to zrobię.
Ludzie niespecjalnie Cię tutaj szanują za Twój sposób dyskusji, wybujałe ego oraz mędrkowanie. Z tego powodu prawie nikt nie chce z Tobą dyskutować, bo już od dawna uważają, że nie ma sensu.

0
somekind napisał(a):
TomRiddle napisał(a):

Miałem na myśli "z jednej strony OOP nie dopuszcza mutowalności". Poprawiłem w poście.

OOP z definicji jest oparte o mutowalność, zasadniczą ideą obiektów jest to, że manipulują one swoim stanem.

O, good to know. Zawsze byłem zdania że jednak immutability to było takie hailstone OOP.

Niestety, takie manipulowanie stanem w praktyce często okazuje się problematyczne, więc dobrą praktyką jest ograniczanie jego użycia do miejsc, w których jest to absolutnie niezbędne.
Ale mutowanie w OOP jest normalne, i nie ma go co na siłę unikać. Ja nie widzę problemu z użyciem mutowalnego buildera.

No to zkładając że OOP dopuszcza mutowalność, to pojawia się pytanie czy faktycznie przykład który przytoczyłem w wątku na pewno się nie kwalifikuje do tego co nazwałeś "absolutnie niezbedne".

Chyba nie jest to niezbędne, bo udało mi się to napisać tak żeby było immutable - tylko niestety jest przyrost kodu duży.

2
TomRiddle napisał(a):

Zasady jakimi rządzi się parsowanie tego stringa to:

  • Możę zawierać cyfty, litery a-z, i kilka znaków specjalnych, ale nie może zacząć się od cyfry
  • Znaki na początku muszą być z małej litery, potem, po pewnym znaku specjalnym muszą być od wielkiej
  • jest też jeden znak który jest takim "wildcard"em i znaczy to samo co wszystkie wielkie litery

Te zasady spokojnie można ogarnąć wyrażeniem regularnym z zewnętrznej biblioteczki. Teraz jest kilka eksperymentów myślowych:

a) Czy interesuje nas, w jakim paradygmacie jest napisana zewnętrzna biblioteczka? Jeżeli nie, to wtedy chyba mamy niespójność, bo efektywnie nasza aplikacja może być "wieloparadygmatowa", chociaż my będziemy twierdzili, że jest dalej OOP, bo ten inny paradygmat jest w "zewnętrznej biblioteczce".
b) W przypadku, gdy jednak nas interesuje paradygmat biblioteczki, to powstaje pytanie: jak głęboko nas on interesuje? Czy w takim razie będziemy OOP, gdy wszystkie biblioteczki "nad środowiskiem wykonania" są OOP? Czy może środowisko wykonania (maszyna wirtualna, system etc) też mają być OOP? Czy CPU też ma być OOP?

TomRiddle napisał(a):

Z trzeciej jednak, żeby to podzielić bardziej na funkcyjki należałoby i tak "rozprzestrzenić" tą mutowalność na więcej funkcji

Napisz maszynę stanową opartą o zippera i osobny typ dla każdego stanu, wtedy nie masz żadnej mutowalności.

0
Afish napisał(a):

a) Czy interesuje nas, w jakim paradygmacie jest napisana zewnętrzna biblioteczka? Jeżeli nie, to wtedy chyba mamy niespójność, bo efektywnie nasza aplikacja może być "wieloparadygmatowa", chociaż my będziemy twierdzili, że jest dalej OOP, bo ten inny paradygmat jest w "zewnętrznej biblioteczce".

Nie interesuje nas to w ogóle, w jakim konkretnie, aczkolwiek wolałbym żeby była jednoparadygmatowa, gdybym miał wybór.

b) W przypadku, gdy jednak nas interesuje paradygmat biblioteczki, to powstaje pytanie: jak głęboko nas on interesuje? Czy w takim razie będziemy OOP, gdy wszystkie biblioteczki "nad środowiskiem wykonania" są OOP? Czy może środowisko wykonania (maszyna wirtualna, system etc) też mają być OOP? Czy CPU też ma być OOP?

No właśnie nie wiem. To chyba będzie arbitralna granica, i ja bym ją narysował tam gdzie jest kod biblioteki. Język i architektura już niekoniecznie.

TomRiddle napisał(a):

Z trzeciej jednak, żeby to podzielić bardziej na funkcyjki należałoby i tak "rozprzestrzenić" tą mutowalność na więcej funkcji

Napisz maszynę stanową opartą o zippera i osobny typ dla każdego stanu, wtedy nie masz żadnej mutowalności.

Tylko czy to nie będzie jeszcze nawet dłuższe niż to immutable rozwiązanie?

0
TomRiddle napisał(a):

No właśnie nie wiem. To chyba będzie arbitralna granica, i ja bym ją narysował tam gdzie jest kod biblioteki. Język i architektura już niekoniecznie.

No właśnie, skoro to arbitralne, to równie dobrze można arbitralnie stwierdzić, że w tym fragmencie nie używamy OOP (bo jak schowamy to parsowanie do zewnętrznej biblioteczki, to i tak wychodzi na to samo). Zapewne każdy będzie miał inną granicę.

TomRiddle napisał(a):

Tylko czy to nie będzie jeszcze nawet dłuższe niż to immutable rozwiązanie?

No będzie, do tego będzie wolniejsze i bardziej zasobożerne, ale za to będzie w całości immutable. Tylko skoro rozmawiamy o paradygmacie w oderwaniu od języka, to nie powinno mieć to żadnego znaczenia, bo zawsze można zrobić język, gdzie takie rozwiązanie da się wygenerować jedną linijką dzięki wsparciu kompilatora.

0
Afish napisał(a):
TomRiddle napisał(a):

No właśnie nie wiem. To chyba będzie arbitralna granica, i ja bym ją narysował tam gdzie jest kod biblioteki. Język i architektura już niekoniecznie.

No właśnie, skoro to arbitralne, to równie dobrze można arbitralnie stwierdzić, że w tym fragmencie nie używamy OOP (bo jak schowamy to parsowanie do zewnętrznej biblioteczki, to i tak wychodzi na to samo). Zapewne każdy będzie miał inną granicę.

Można, pytanie czy powinniśmy. Na tym polega całe pytanie z wątku.

2
TomRiddle napisał(a):

Można, pytanie czy powinniśmy. Na tym polega całe pytanie z wątku.

Moim zdaniem tak. Nie ma co trzymać się kurczowo paradygmatu. Dla mnie może być fragment nie-OOP (nie musi być w zewnętrznej biblioteczce), o ile tylko jest sensownie oddzielonych od innych podejść.

3
TomRiddle napisał(a):

No dobra, a jakiś argument za tym byś przytoczył?

Moim zdaniem kod ma być prosty dla juniora. Papierkiem lakmusowym skomplikowania projektu jest liczba WTF na minutę (najlepiej właśnie od juniora), więc prostszy kod jest zazwyczaj lepszy. Nie widzę powodu, żeby robić jakąś rozwlekłą maszynę stanów, bo jej cognitive load jest wysoki, a nie daje żadnego zysku ponad zwykłą pętlę.

0
Afish napisał(a):
TomRiddle napisał(a):

No dobra, a jakiś argument za tym byś przytoczył?

Moim zdaniem kod ma być prosty dla juniora. Papierkiem lakmusowym skomplikowania projektu jest liczba WTF na minutę (najlepiej właśnie od juniora), więc prostszy kod jest zazwyczaj lepszy.

Na pewno?

Nie wiem, junior mógłby to samo powiedzieć o smoke testach, covariant generykach, stosunku unitów do logiki, małych funkcji, etc.

Czy największy legacy na jedną gigafunkcję nie wygenerowałby 0wtf/minute u juniora?

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