Hem görevi gerçekleştiren hem de bir boole durumunu durum olarak döndüren bir yönteme nasıl ad verilir?


33

Bir yöntem varsa

bool DoStuff() {
    try {
        // doing stuff...
        return true;
    }
    catch (SomeSpecificException ex) {
        return false;
    }
}

daha çok aranmalı IsStuffDone()mı?

Her iki isim de kullanıcı tarafından yanlış yorumlanabilir: Eğer isim buysa, DoStuff()neden bir boole döndürüyor? Adı IsStuffDone()açıksa, yöntemin bir görevi yerine getirip getirmediği veya yalnızca sonucunu kontrol edip etmediği açık değildir.

Bu dava için bir kongre var mı? Veya alternatif bir yaklaşım, bu kusurlu olarak kabul edilir? Örneğin, C # gibi çıktı parametrelerine sahip dillerde, bir boolean durum değişkeni, yönteme bir yöntem olarak iletilebilir ve yöntemin dönüş türü olur void.

EDIT: Özel sorunumda istisna işleme doğrudan arayan kişiye devredilemez, çünkü yöntem bir arayüz uygulamasının bir parçasıdır. Bu nedenle, arayan, farklı uygulamaların tüm istisnalarıyla uğraşmakla suçlanamaz. Bu istisnalara aşina değil. Ancak, arayan kişi, npinti'nin cevabında ve yorumundaStuffHasNotBeenDoneForSomeReasonException önerildiği gibi özel bir istisna ile ilgilenebilir .


2
Bu, işlevin kullanımına ve yapılan işlere bağlıdır. Gerekirse, işlerin doğru şekilde yürütülmesi gerekiyorsa, o zaman bu yaklaşımın hatalı olduğunu düşünürdüm, çünkü işlevin kullanıcısı boolean bayrağını kaçırabilir ve istisna tarafından sağlanan bilgilerden yoksun olabilir.
Benni

7
Çoğu zaman, onu "kırılmış" olarak adlandırırdım boolean, istisnayı sarmak ya da geçmek yerine geri dönmek neredeyse her zaman yanlıştır.
maaartinus

2
Bu tür bir istisna işleyicisi nadiren iyi bir fikirdir. Sadece beklediğiniz özel istisnaları yakalayın, hepsini değil. Ve mümkünse ilk etapta atmaktan kaçının, yakalama ihtiyacını ortadan kaldırın.
CodesInChaos

2
Şey ... BadlyDesignedMethodInSeriousNeedOfRefactoring? İstisnalar hakkındaki sorunuzu yanıtlamak için - Arayan kişinin onları ele almasına izin verdim veya onları yakalayıp "bu yöntem işini yapma" anlamına gelen özel bir istisna atayım. Paylaş ve Keyfini çıkar.
Bob Jarvis - Monica

5
Söyleyen herkes için: sadece bir istisna atma (veya geçmesine izin verme), bu kodun nasıl kullanıldığı konusunda temelsiz varsayımlarda bulunuyorsunuz. Olası senaryolardan biri, problemin daha büyük alt sınıflarını her zaman artan maliyetle çözen çeşitli sezgisel çözüm yöntemleriyle çözülmesi gereken bir problemin olmasıdır; gibi bir şey yazmak mantıklı olur if (FirstMethodSucceeds(problem) or SecondMethodSucceeds(problem) or ...) Hurray(); else UniversalSolve(problem);. Aynısını (özel?) İstisnalar ile yapmak işe yaramaz bir şekilde daha karmaşık olurdu.
Marc van Leeuwen

Yanıtlar:


68

.NET'te, bir tanesinin bir istisna ( DoStuff) atabileceği sıklıkla yöntem çiftleriniz vardır , diğerinde bir Boole durumu ve başarılı bir yürütme sırasında, bir out parametresi ( TryDoStuff) üzerinden gerçek sonuç döndürülür .

(Microsoft buna "Try-Parse Pattern" adını verir , çünkü belki de en belirgin örneği TryParseçeşitli ilkel türlerin yöntemleridir.)

Eğer Tryönek kendi dilinizde nadir olduğunu, buna genelde kullanmamalısınız.


3
+1 Bu şekilde başka bir yerde yapılan böyle bir şey gördüm. if (TryDoStuff()) print("Did stuff"); else print("Could not do stuff");bence oldukça standart ve sezgisel bir deyimdir.
Karl Nicoll

12
TryDoStuffYöntemlerin temiz bir şekilde başarısız olduğu ve yanlış döndüklerinde hiçbir yan etkisinin olmadığı varsayıldığı belirtilmelidir .
Trillian

Bilginize, Removeörneğin .NET çerçevesinde bir öğeyi veri yapısından (örn. Dictionary) Kaldıracak ve a döndürecek yöntemler de vardır bool. API'nin tüketicisi, onu tüketmeye veya görmezden gelmeye karar verebilir. Ancak, hatalar istisnalar olarak rapor edilir.
Ömer İkbal

18

Arama koduna istisnayı basitçe attıysanız ne olur?

Bu şekilde, kodunuzu kimlerin kullandığı konusunda istisna işlemeyi size bırakıyorsunuz. Peki, gelecekte aşağıdakileri yapmak istiyorsanız:

  • İstisnalar atılmazsa, A eylemine geçin
  • (Örneğin) a FileNotFoundExceptionatılırsa, B eylemini yapın
  • Başka bir istisna atılırsa, C işlemine geçin

İstisnalarınızı geri atarsanız, yukarıdaki değişiklik basit bir şekilde ekstra bir catchblok eklemek anlamına gelir. Bunu olduğu gibi bırakırsanız, projenin karmaşıklığına bağlı olarak birden fazla konumda olabilen yöntemi ve yöntemin çağrıldığı yeri değiştirmeniz gerekecektir.


1
İstisna, temsil edilemeyen ve şirket içinde ele alınması gereken türden bir şeyse ne olur?
Limbo Sürgün

2
@LimboExile: Bununla hala içten başa çıkabileceğini düşünüyorum ve sonra belki başka bir istisna, belki de kendine ait. Bu, gerçekleşmemesi gereken bir şeyin gerçekleştiğini gösterecektir, ama aynı zamanda, kaputun altında gerçekten neler olup bittiğini ortaya çıkarmadınız, sanırım neden istisna ile içtenlikle ilgilenmek istiyorsunuz.
npinti

6
Belki bir istisna atma bir için olmalı akılda değer taşıyan bulunuyor istisnai durumda . DoStuffBaşarısızlığın yaygın veya normal olması halinde, başarısızlık durumu için bir istisna atmak, kötü olan istisnalar dışında program akışını kontrol etmeye benzer. İstisnalar ayrıca doğal bir performans maliyetine sahiptir. Bir DoStuffhata nedeniyle başarısızlık nadir bir durum ise, istisnalar kesinlikle @npinti'nin önerdiği gibi gitme yoludur.
Karl Nicoll

1
@KarlNicoll Bir şeyin "istisnai" olup olmadığı tamamen özneldir. Temel ölçüt, hiç kimse hata hakkında bir şey yapmazsa, programın çökmesini isteyip istemediğiniz ve işlevin türünde hata olasılığının bulunup bulunmadığı olmalıdır. Ek olarak, istisnaların pahalı olduğu bir gerçek değil; dile ve nasıl fırlattığınıza bağlı. İstisnalar Python'da ucuzdur ve yığın izleme bilgisini çıkarırsanız Java'da da ucuz olabilirler. Bir performans maliyeti olsa bile, profilinize kadar endişelenmek için erken bir optimizasyon yapılması gerekir.
Doval

1
@Doval - Sübjektif olduğuna katılıyorum, bu nedenle OP, npinti'nin cevabını en iyi şekilde yapabileceği için tam anlamıyla indirim yapmamalı. Demek istediğim, istisnalar atmanın her zaman atılacak en iyi yol olmadığıydı. Bir hatanın bir istisna atmanın ve bir başvurunun potansiyel olarak çökmesini haklı çıkarmadığı birçok durum vardır. Örneğin, OP'nin DoStuff()yöntemi iç kod bir istisna attıktan sonra temizlenirse ve yöntemin Son Koşulları hala doğruysa, bir hata kodu işlendiği için bir dönüş kodu daha iyi bir seçenek olabilir.
Karl Nicoll

7

DoStuff() bu yeterlidir ve işlevin döndüren değeri belgelenmelidir ve mevcut birçok API'yi arayarak, işlev adından bahsetmenize gerek yoktur:

PHP

// this method update and return the number affected rows 
// called update instead of updateAndGetAffectedCount
$affected = $query->update(/* values */);

Cı-Sharp

// Remove item from the List
// returns true if item is successfully removed; otherwise, false.
public bool Remove( T item )

6

Java'da, Koleksiyon API'si bir boole döndüren bir ekleme yöntemi tanımlar . Temel olarak, toplama işleminin değişip değişmediğini döndürür. Öyleyse, bir Listöğe için eklendiğinden beri, genellikle doğru dönecektir, bir öğe için Set, eğer zaten orada olsaydı, Sether benzersiz öğeye en fazla bir kez izin verildiğinden yanlış dönebilir .

Bununla birlikte, koleksiyon tarafından izin verilmeyen bir öğeyi, örneğin null değerini eklerseniz, ekleme, NullPointerExceptionfalse döndürmek yerine atmaya başlar .

Davanıza aynı mantığı uyguladığınızda, neden bir boole döndürmeniz gerekiyor? Bir istisna saklamaksa, yapma. Sadece istisna at. Bu şekilde neyin yanlış gittiğini görebilirsiniz. Bir boole gereksiniminiz varsa, yapılmadığı için, bir istisna dışında bir nedenden ötürü DoStuff(), bu davranışı temsil ettiği için yöntemi adlandırın . Bir şeyler yapar.


1

Olabilir, farklı nedenlerle başarısız olabilir, İstisna, normal koşullar, bu yüzden şunu kullanır:

boolean doStuff() - returns true when successful

Önemli olan, booleanın ne demek olduğunu belgelemek.


1

Genelde yöntemleri bir OperationResult(veya OperationResult<T>) döndürür ve IsSuccessözelliği OperationResultuygun şekilde ayarlarım . Eğer 'usual' metodu geçersizse geri dönün OperationResult, 'usual' metodu bir nesneyi döndürürse geri dönün OperationResult<T>ve Itemözelliği OperationResultuygun şekilde ayarlayın. Ben de üzerinde yöntemleri sahip öneririm OperationResultgibi .Failed(string reason)ve .Succeeded(T item). OperationResultSistemlerinizde hızlı bir şekilde tanıdık bir tür haline gelir ve geliştiriciler nasıl kullanılacağını bilir.


0

Bu gerçekten kullandığınız dile bağlıdır. Bazı dillerde olduğu gibi, pek çok dilde veya hiçbir şekilde bulunmayan sözleşmeler ve protokoller vardır.

Örneğin, Objective-C dilinde ve iOS / Mac OS X SDK yöntemlerinin adları genellikle aşağıdaki satırlar boyunca gider:

- (returndatatype) viewDidLoad {
- (returndatatype) isVisible {
- (returndatatype) appendMessage:datatype variablename with:datatype variablename {

Gördüğünüz gibi, orada viewDidLoad adında bir yöntem var. Ne zaman kendi uygulamalarımı yaparsam bu tür isimleri kullanmayı tercih ederim. Bu, söylediğiniz gibi bir şey olup olmadığını kontrol etmek için kullanılabilir. Yöntemlerine isim verdiğin şey hakkında çok derin düşündüğüne inanıyorum. Çoğu yöntem ne olursa olsun yaptıklarının durumunu döndürür, örnek alın:

PHP'de, bağlantı başarısız olursa mysql_connect () işlevi false döndürür. Yapacağını söylemiyor, ama yapıyor ve belgeler onun programcıya yanlış yorumlanamayacağını söylüyor.


Ah, ama viewDidLoad bir geri arama bildirimidir. Kullanıcılar görünümü yüklemek için onu aramazlar. Aksine, görünüm yüklendikten sonra çağrılır. Aynı şekilde: isVisible görünürlüğü ayarlamaz, yalnızca geçerli değerin değerini döndürür. O değil yapmak bir şey.
lilbyrdie

0

'Dene' öneki kullanılmasını önermek istiyorum. Bu, yöntemin başarılı olabileceği veya olamayacağı durumlar için iyi bilinen bir kalıptır. Bu adlandırma modeli, Microsoft tarafından .NET Framework'te kullanılmıştır (örneğin, TryParseInt).

Ama, belki de bu isimle ilgili değil. Metodunuzun giriş / çıkış parametrelerini nasıl tasarladığınızla ilgilidir.

Benim fikrim, bir yöntemin bir dönüş değeri varsa, o zaman bu yöntemi çağırmanın amacı, bu dönüş değerini elde etmek olmalıdır. Bu nedenle, bir işlemin durumunu belirtmek için dönüş türünü kullanmaktan kaçınmalısınız.

C #, bir out parametresi kullanmayı tercih ederim. Bir çıkış kullanarak parametreyi bir yan parametre olarak işaretliyorum. Özellikle C # 6 satır içi değişken bildirimini destekleyecektir.

DoStuff(out var isStuffDone); // The out parameter name clearly states its purpose.
DoStuff(out var _); // I use _ for naming parameters that I am ignoring.

0

Yöntemin birincil rolünü temel alan bir isim seçerdim. Bu yöntemin boolean değeri döndürmesi, 'Is' ön ekini zorunlu kılmaz. Oldukça genişletilebilir olan 'Is' ön ekini kullanan bazı Java kodları bulalım. Bir bak java.io.File.delete(). Dönüyor boolean, ancak çağrılmadı isFileDeleted(). Bunun nedeni, yöntemin birincil rolünün bir dosyayı silmek olmasıdır. Birisi bu yöntemi bir dosyayı silmek amacıyla çağırır.

Boolean, sadece çalışmanın sonucunu geri göndermek için var. Öte yandan görelim java.util.Map.isEmpty(). Açıkçası, koleksiyonun boş olup olmadığını bulmak için böyle bir yöntem çağırıyorsunuz. Hiçbir şeyin yapılmasını istemiyorsun. Siz sadece mevcut durumun ne olduğunu öğrenmek istiyorsunuz.

Yani şahsen, kesinlikle yapışırdım DoStuff().

Bu benim için biraz önemli bir konu. Çoğu zaman eski kodları koruduğumda, şahsen "yalan söyleme yöntemi" olarak adlandırdığım bir şeyin üzerine rastlarım. Ad, A eylemini öneriyor, ancak vücut B eylemini yapıyor. Veritabanındaki verileri değiştiren bir alıcı yöntemine ilişkin en tuhaf örnek.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.