it-swarm-eu.dev

Může být funkce příliš krátká?

Kdykoli zjistím, že psám stejnou logiku více než jednou, obvykle ji držím ve funkci, takže v mé aplikaci musím tuto logiku udržovat pouze na jednom místě. Vedlejším účinkem je, že někdy skončím jednou nebo dvěma linkovými funkcemi, jako jsou:

function conditionMet(){
   return x == condition;
}

OR

function runCallback(callback){
   if($.isFunction(callback))
     callback();
}

Je to líný nebo špatný postup? Ptám se jen proto, že to má za následek větší počet funkcí vyžaduje velmi malé kousky logiky.

128
Mark Brown

Hehe, ach, pane Browne, kdybych jen mohl přesvědčit všechny vývojáře, se kterými se setkám, aby si udrželi své funkce tak malé, jako je tohle, věřte mi, svět softwaru by byl lepším místem!

1) Čitelnost kódu se zvyšuje desetkrát.

2) Tak snadné zjistit proces vašeho kódu kvůli čitelnosti.

3) DRY - Neopakujte se) - Tomu se velmi dobře přizpůsobujete!

4) Testovatelné. Drobné funkce jsou milionkrát jednodušší než ty 200 řádkové metody, které vidíme příliš často.

Jo a nebojte se o "funkce hopping", pokud jde o výkon. "Release" sestavení a optimalizace kompilátoru se o to velmi dobře postarají a výkon je 99% času někde jinde v návrhu systémů.

Je to líné? - Přesně naopak!

Je to špatný postup? - Rozhodně ne. Je lepší vytáhnout tento způsob výroby než dehtové koule nebo „Boží objekty“, které jsou tak moc běžné.

Pokračujte v dobré práci mého kolegy řemeslníka;)

166
Martin Blore

Řekl bych, že refactored metoda je příliš krátká jestliže jeden:

  • Duplikuje primitivní operaci, a to pouze za účelem vytvoření metody:

Příklad:

boolean isNotValue() {
   return !isValue();
}

nebo...

  • Kód se používá pouze jednou a jeho záměr je snadno pochopitelný na první pohled.

Příklad:

void showDialog() {
    Dialog singleUseDialog = new ModalDialog();
    configureDialog(singleUseDialog);
    singleUseDialog.show();
}

void configureDialog(Dialog singleUseDialog) {
    singleUseDialog.setDimensions(400, 300);
}

Mohl by to být platný vzorec, ale v tomto příkladu bych jen vložil metodu configureDialog (), pokud jsem ji nezamýšlel potlačit nebo znovu použít tento kód jinde.

64
RMorrisey

Může být funkce příliš krátká? Obecně ne.

Ve skutečnosti jediný způsob, jak zajistit, že:

  1. Našli jste všechny třídy ve svém návrhu
  2. Vaše funkce dělají pouze jednu věc.

Je, aby vaše funkce byly co nejmenší. Nebo jinými slovy, extrahujte funkce z vašich funkcí, dokud už nebudete moci extrahovat. Říkám tomu "Rozbalte, dokud nespadnete."

Vysvětlit to: Funkce je obor s kousky funkčnosti, které komunikují pomocí proměnných. Třída je také oborem s kousky funkčnosti, které komunikují pomocí proměnných. Dlouhá funkce tak může být vždy nahrazena jednou nebo více třídami malou metodou.

Také funkce, která je dostatečně velká, abyste z ní mohli vyjmout další funkci, dělá více než jednu věc podle definice. Takže pokud můžete extrahovat funkci z jiného, ​​měli byste extrahujte tuto funkci.

Někteří lidé se obávají, že to povede k šíření funkcí. Mají pravdu. Bude. To je vlastně dobrá věc. Je to dobré, protože funkce mají jména. Pokud si dáváte pozor na výběr dobrých jmen, pak tyto funkce fungují jako signatury, které prostřednictvím vašeho kódu nasměrují ostatní lidi. Opravdu pojmenované funkce uvnitř dobře pojmenovaných tříd uvnitř dobře pojmenovaných oborů názvů jsou jedním z nejlepších způsobů, jak zajistit, aby se čtenáři neztratili.

V Episode III of Clean Code na webu cleancoders.com je toho mnohem více

59
Uncle Bob.

Páni, většina z těchto odpovědí není vůbec užitečná.

Neměla by být psána žádná funkce, jejíž identita je její definicí . To znamená, že pokud je název funkce jednoduše kódovým blokem funkce napsaným v angličtině, nepište jej jako funkci.

Zvažte svou funkci conditionMet a tuto další funkci, addOne (odpusťte mi můj rezavý JavaScript):

function conditionMet() { return x == condition; }

function addOne(x) { return x + 1; }

conditionMet je správná koncepční definice; addOne je tautologie . conditionMet je dobré, protože nevíte, co conditionMet znamená pouhým vyslovením „podmínka splněna“, ale můžete vidět, proč je addOne hloupé, pokud si jej přečtete v angličtině :

"For the condition to be met is for x to equal condition" <-- explanatory! meaningful! useful!

"To add one to x is to take x and add one." <-- wtf!

Pro lásku všeho, co by mohlo být stále svaté, nepište prosím tautologické funkce!

(A ze stejného důvodu nepište komentáře pro každý řádek kód !)

53
Rei Miyasaka

Řekl bych, že pokud si myslíte, že záměr nějakého kódu lze zlepšit přidáním komentáře, pak spíše než přidáním tohoto komentáře, extrahujte kód do své vlastní metody. Bez ohledu na to, jak malý byl kód.

Pokud například váš kód bude vypadat takto:

if x == 1 { ... } // is pixel on?

místo toho to vypadat takto:

if pixelOn() { ... }

s

function pixelOn() { return x == 1; }

Nebo jinými slovy, nejde o délku metody, ale o samokumentující kód.

14
Julio

Myslím, že to je přesně to, co chcete dělat. Právě teď by tato funkce mohla být pouze jedna nebo dvě linie, ale postupem času by mohla růst. Také více funkcí volání vám umožní číst volání funkcí a pochopit, co se uvnitř děje. Díky tomu je váš kód velmi DRY (Don't Repeat Yourself) což je mnohem lépe udržovatelné.

7
mpenrow

Souhlasím se všemi ostatními příspěvky, které jsem viděl. To je dobrý styl.

Režie takové malé metody může být nulová, protože optimalizátor může optimalizovat volání pryč a vložit kód. Jednoduchý kód, jako je tento, umožňuje optimalizátoru dělat svou nejlepší práci.

Kód by měl být psán pro přehlednost a jednoduchost. Snažím se omezit metodu na jednu ze dvou rolí: rozhodování; nebo vykonávající práci. To může generovat jednořádkové metody. Čím lépe to dělám, tím lepší je můj kód.

Takový kód má tendenci mít vysokou soudržnost a nízkou vazbu, což je dobrá praxe kódování.

ÚPRAVA: Poznámka k názvům metod. Použijte název metody, který označuje, co metoda neudělá. Zjistil jsem, verb_noun (_modifier) ​​je dobré pojmenování schéma. Toto dává jména jako Find_Customer_ByName místo Select_Customer_Using_NameIdx. Druhý případ je náchylný k nesprávnosti při změně metody. V prvním případě můžete zaměnit celou implementaci zákaznické databáze.

5
BillThor

Refaktoring jednoho řádku kódu do funkce se zdá být nadměrný. Mohou existovat výjimečné případy, jako například ver loooooong/vyhovuje řádkům nebo výplatám, ale nedělal bych to, pokud nebudu vím funkce v budoucnu poroste.

a váš první příklad naznačuje použití globálů (které mohou nebo nemusí mluvit o jiných problémech v kódu), já bych to dále upravil a tyto dvě proměnné vytvořil jako parametry:

function conditionMet(x, condition){
   return x == condition;
}
....
conditionMet(1,(3-2));
conditionMet("abc","abc");

Příklad conditionMetmůže může být užitečný, pokud byl stav dlouhý a opakující se, jako například:

function conditionMet(x, someObject){
   return x == ((someObject.valA + someObject.valB - 15.4) / /*...whole bunch of other stuff...*/);
}

Zvaž toto:

Jednoduchá funkce detekce kolizí:

bool collide(OBJ a, OBJ b)
{
    return(pow(a.x - b.x, 2) + pow(a.y - b.y, 2) <= pow(a.radius + b.radius, 2));
}

Pokud jste ve svém kódu psali tenhle „jednoduchý“ liner po celou dobu, můžete nakonec udělat chybu. Navíc by bylo opravdu mučivé psát to znovu a znovu.

3
Mateen Ulhaq

Řekl bych, že jsou příliš krátké, ale toto je můj subjektivní názor.

Protože:

  • Neexistuje žádný důvod k vytvoření funkce, pokud je použita pouze jednou nebo dvakrát. Skákání na defs sát. Zejména s úžasně rychlým kódem VS a C++.
  • Přehled třídy. Když máte tisíce malých funkcí, tak mě to naštve. Baví mě, když si mohu prohlédnout definice tříd a rychle zjistit, co to dělá, ne jak to SetXToOne, SetYToVector3, MultiplyNumbers, + 100 setters/getters.
  • Ve většině projektů tito pomocníci ztrácejí váhu po jedné nebo dvou refaktoringových fázích a poté provedete „prohledání všech“ -> smazání, abyste se zbavili zastaralého kódu, obvykle ~ 25% +.

Funkce, které jsou dlouhé, jsou špatné, ale funkce, které jsou kratší než 3 řádky a provádějí pouze jednu věc, jsou stejně špatné IMHO.

Řekl bych tedy jen malou funkci, pokud je to:

  • 3+ řádků kódu
  • Chybí věci, které by juniorské devs mohly chybět (neví)
  • Provádí další ověření
  • Používá se, nebo se použije alespoň 3x
  • Zjednodušuje často používané rozhraní
  • Během dalšího refaktoringu se nestane mrtvou váhou
  • Má nějaký zvláštní význam, například specializaci šablony nebo něco
  • Provádí některé odkazy na izolační úlohy - const, ovlivňuje proměnlivé parametry, provádí vyhledávání soukromých členů

Vsadím se, že další vývojář (senior) bude mít lepší věci, než si pamatovat všechny vaše funkce SetXToOne. Takže se brzy brzy změní v mrtvou váhu.

2
Coder

Ne, a to je zřídka problém. Nyní, když někdo necítí žádnou funkci, by měl být delší než jeden řádek kódu (pokud by to mohl být tak jednoduchý), byl by to problém a v některých ohledech líný, protože nemyslí na to, co je vhodné.

2
JeffO

Nemám rád příklad č. 1, protože generického jména.

conditionMet se nezdá být obecný, takže to znamená určitou podmínku? Jako

isAdult () = { 
  age >= 18 
}

To by bylo v pořádku. Je to sémantický rozdíl

isAtLeast18 () { age >= 18; } 

nebylo by to pro mě v pořádku.

Možná je často používán a může být předmětem pozdější změny:

getPreferredIcecream () { return List ("banana", "choclate", "Vanilla", "walnut") }

je v pořádku. Pokud jej používáte vícekrát, stačí změnit jediné místo, pokud musíte - možná zítra bude možná možná šlehačka.

isXYZ (Foo foo) { foo.x > 15 && foo.y < foo.x * 2 }

není atomová a měla by vám dát pěknou testovací příležitost.

Pokud potřebujete projít nějakou funkci, samozřejmě, projít, co se vám líbí, a psát jinak hloupě vypadající funkce.

Ale obecně vidím mnohem více funkcí, které jsou příliš dlouhé, než funkce, které jsou příliš krátké.

Poslední slovo: Některé funkce vypadají pouze vhodně, protože jsou psány příliš podrobně:

function lessThan (a, b) {
  if (a < b) return true else return false; 
}

Pokud vidíte, že je to stejné jako

return (a < b); 

nebudete mít problém

localLessThan = (a < b); 

namísto

localLessThan = lessThan (a, b); 
1
user unknown

Neexistuje žádný kód jako žádný kód!

Nechte to jednoduché a nepřekračujte věci.

Není to líný, dělá svou práci!

0
RDL

Příliš krátký nikdy není problém. Některé důvody pro krátké funkce jsou:

Opakovaná použitelnost

Např. Pokud máte funkci, například metodu množiny, můžete ji uplatnit, abyste se ujistili, že parametry jsou platné. Tuto kontrolu je třeba provést všude, kde je proměnná nastavena.

Údržba

Můžete použít nějaké prohlášení, o kterém si myslíte, že se v budoucnu může změnit. Např. nyní zobrazujete symbol ve sloupci, ale později se to může změnit na něco jiného (nebo dokonce na pípnutí).

niformita

Používáte např. vzorec fasády a jediná věc, kterou funkce dělá, je předat tuto funkci jinému bez změny argumentů.

0
Michel Keijzers

Když dáte oddílu kódu název, je to v podstatě pro to, že mu dáte jméno. Může to být z několika důvodů, ale klíčovým bodem je, pokud mu můžete dát smysluplné jméno, které přidá váš program. Jména jako "addOneToCounter" by nepřidala nic, ale conditionMet() by.

Pokud potřebujete pravidlo, abyste zjistili, zda je úryvek příliš krátký nebo příliš dlouhý, zvažte, jak dlouho trvá nalezení smysluplného názvu úryvku. Pokud nemůžete v přiměřené době, úryvek není vhodné velikosti.

0
user1249

Ano, je v pořádku mít funkci krátkého kódu. V případě metod jako „getters“, „setters“, „accesors“ je velmi běžné, jak již bylo zmíněno v předchozích odpovědích.

Někdy jsou tyto krátké "přístupové" funkce virtuální, protože při přepsání v podtřídách budou mít funkce více kódu.

Pokud chcete, aby funkce nebyla tak krátká, dobře, v mnoha funkcích, ať už globálních nebo metodách, používám místo přímého návratu obvykle proměnnou „result“ (Pascal style), což je velmi užitečné při použití debuggeru.

function int CalculateSomething() {
  int Result = -1;

   // more code, maybe, maybe not

  return Result;
}
0
umlcat

Ne, ale může to být příliš těsné.

Pamatujte: Kód je napsán jednou, ale přečten mnohokrát.

Nepište kód pro kompilátor. Napište to pro budoucí vývojáře, kteří budou muset udržovat váš kód.

0
Jim G.