Yöntem vs İşlev vs yordam


107

Basit bir soru, ama sık sık, bu tür vahşet ile tanımlanan, ancak yıllar boyunca farklı şeyler ifade ettiğim bilinen bu üç terimi duyuyorum.

"Prosedürler", "Yöntemler", "İşlev", "Altprogramlar" vb. "Doğru" tanımları nelerdir?


4
rutin "
mefisto

1
@ teresko: "Alt program" ın daha yaygın olduğunu düşünüyorum.
mk12

Yanıtlar:


108

Burada farklı bir cevaba gidiyorum: pratik olarak konuşursak, gerçekten hiçbir fark yoktur , "metod" un genellikle OO dillerinde bir nesneyle ilişkili bir alt rutini ifade etmesiyle ilgili küçük bir istisna dışında .

"Prosedür, fonksiyon, alt program, alt program ve yöntem" terimlerinin tümü aynı anlama gelir: daha büyük bir programdaki çağrılabilir bir alt program. Ancak, bu terimlerin tüm değişken kullanımlarını yakalayan bir tanım bulmak zor, çünkü bunlar programlama dilleri veya paradigmalarda tutarlı bir şekilde kullanılmazlar.

Bir fonksiyonun bir değer döndürdüğünü söyleyebilirsiniz. Peki, aşağıdaki C işlevi bir değer döndürmez:

void f() { return; }

... ama buna prosedür diyecek birini bulacağınızdan şüpheliyim.

Elbette, Pascal'da prosedürler değerleri döndürmez ve fonksiyonlar değerleri döndürür, ancak bu sadece Pascal'ın nasıl tasarlandığının bir yansımasıdır. Fortran'da bir fonksiyon bir değer döndürür ve bir alt yordam birden çok değer döndürür. Ancak bunların hiçbiri gerçekten bu terimler için "evrensel" bir tanım bulmamıza izin vermiyor.

Aslında, "prosedürel programlama" terimi, C, Fortran ve Pascal da dahil olmak üzere bütün dilleri ifade eder; bunlardan sadece biri aslında "prosedür" terimini bir şey ifade etmek için kullanır.

Yani bunların hiçbiri gerçekten tutarlı değil. Bunun tek istisnası, muhtemelen, neredeyse tamamen OO dilleriyle kullanılmış gibi görünen, bir nesneyle ilişkili bir işleve işaret eden "yöntem" dir. Buna rağmen, bu bile her zaman tutarlı değildir. Örneğin, C ++, genellikle yöntem yerine "üye işlevi" terimini kullanır ("yöntem" terimi, programcılar arasında yerel C ++ 'a çarptıysa bile).

Mesele şu ki, bunların hiçbiri gerçekten tutarlı değil. Bu, o dönemde hangi dilde olursa olsun kullanılan terimleri yansıtıyor.


Tam olarak cevabın böyle olduğunu düşündüm. (Gezinti sırasında başka bir değişken olarak "alt rutin" eklemeliydim.) Sorabilir miyim: Neden bu C işlevini "Prosedür" olarak tanımlayan birini bulmuyorsunuz? Teknik olarak yanlış olduğu için veya "prosedür" terimi şu anda modası geçmiş değil mi?
Django Reinhardt

7
C programcıları "işlev" terimini kullanırlar çünkü C'nin tasarımcıları bu terimi kullanır.
Charles Salvia,

15
Bebeği banyo suyuyla atmayalım. Sadece terminoloji tam bir tutarlılıkla kullanılmadığından, farklı terimlerin farklı anlamları olmadığı anlamına gelmez. @ Bruce ve @ Frank'in tanımları kendine has değil, yaygın olarak tanınır. Anlamların evrensel olmadığı gerçeği önemlidir, ancak “pratik olarak konuşursak, gerçekten hiçbir fark yoktur” atılımını haklı çıkarmaz. (@Django)
33'de

9
Türleri "üye işlevlerini", Java ve C # çağrı işlevlerini "statik yöntemleri" olarak adlandırır.
Jörg W Mittag

2
Bruce'un cevabı kesinlikle programlamada yeni iseniz, kesinlikle gitmeniz gereken cevap. Tanımları kesinlikle% 99 da doğru olacak. Ancak daha fazla teknik / teorik cevap bekliyordum. Bazen yeni programcılar sadece kendi alan adlarını bilirler ve hepsinin var olduğu konusunda ısrar ederler. Gerçekte, bugün hala eski dilleri kullanan ve farklı tanımları kullanmak için “yanlış” olmayan programcılar var. En çok ilgilendiğim şey buydu.
Django Reinhardt

67

Bir işlev bir değer döndürür, ancak işlem yapmaz

Bir yöntem, bir işlevine benzer, ama bir sınıfın bir parçası. Terimi, bir yöntem , nesne yönelimli programlama hemen hemen sadece kullanılmaktadır.


8
Tam olarak iç değil. Bir yöntem, bir sınıfın parçası olan herhangi bir işlev veya prosedürdür.
Scott Whitlock

8
Yani SQL'de "Saklı Prosedür" herhangi bir değer döndürmüyor mu? Pascal gibi bir şey bir "Prosedür" ne olacak? Tanımlarınız mevcut eğilimlere mi dayanıyor yoksa evrensel tanım olarak mı kabul edilmeli? Teşekkürler!
Django Reinhardt

3
@Django: Pascal'da bir prosedürün bir dönüş değeri olamaz ve bir fonksiyonun bir dönüş değeri olmalıdır . Diğer bazı dillerde, terminoloji daha gevşek bir şekilde kullanılabilir.
Bruce Alderman

1
FWIW, FORTRAN, SUBROUTINE'lara ve FUNCTION'lara sahipti, ilk günlerden beri, bir SUBROUTINE'ın bir değer getirmediği fark edildi. Pascal'ın soyundan geldiği ALGOL'u hatırlamıyorum.
David Thornley

2
@ 3p1c_d3m0n JS'deki functionher iki rolü de yerine getiren kesinlikle doğrudur , ancak JS işlevleri tüm dönüşü gerçekleştirir. Bir return ifadesinin değeri yoktur, değer örtüktür undefined. Bir return ifadesi olmadığında, yorumlayıcı örtük bir return ifadesi ekler. Ezoterik, belki, ama burada verilen tanımla tutarlıdır. Bu yüzden var x = function() {}();JS'de yasaldır; Örtük getiriler için değilse, bunun Pascal'da olduğu gibi bir hata olması gerekir.
Noktalı virgül

52

Bir fonksiyon girdilerin bir demet alır ve bir veya daha fazla değer döndüren bir şeydir. Döndürülen değerler tamamen girdiler tarafından belirlenirse ve işlevin herhangi bir yan etkisi yoksa (günlüğe kaydetme, belki de kendi dışında durum değişikliklerine neden olma), o zaman saf işlev olarak adlandırılır.

Bir prosedür, bir değer dönmez bir fonksiyonudur. Özellikle bu, bir prosedürün yalnızca yan etkilere neden olabileceği anlamına gelir. (Bu, bir giriş parametresinin mutasyona uğramasını içerebilir!)

Bir yöntem , bir dizi değişken üzerinde kapanan, yani bir kapanma fonksiyonudur . Sıfır veya daha fazla giriş parametresi alır, bu değişken grubuna erişebilir ve sıfır veya daha fazla değer döndürür. OO dillerinde bu yöntemler nesnelere veya sınıflara eklenir.

Çoğu ana akım OO dilinde, bu kapalı değişkenler bir nesnenin üye alanları veya örnek değişkenleri olarak adlandırılır. Bir yöntem saf bir işlev, saf bir işlev veya bir işlem olabilir.

İkinci tanım nesne = struct + kapanış yazışmalarına yol açar .


5
Dolayısıyla bir nesne değişkenler topluluğu ve bu ortak değişkenler üzerindeki kapanışlar topluluğudur. Temel olarak, nesne yönelimli dillerin her zaman kapanışı oldu ve kimse bilmiyordu? İlginç manzara! +1
Giorgio

1
Çoğu yöntemin hiçbir şeye yakın olduğuna inanmıyorum. foo.doSomething()parametresiz değil. fooBazı sözdizimsel şeker ile verilen bir parametreye (nesne ) sahiptir. Bir kapatma, böyle bir parametreye ihtiyaç duymadan nesnesine başvurabilir. Bu, yöntemlerin kapanış olamayacağı anlamına gelmez , sadece çoğunun yapılmayacağını ve OO olmanın bir dili kapatmaları desteklemek için yeterli olmadığını söylemez .
8bittree

3
foo.doSomething()foodeğişkeni kapatır . İçindeki herhangi bir ifade , diline bağlı olarak veya içinden doSomethingerişebilir . Bu "yakından" nin tanımıdır. Sınıflar, üye değişkenleri üzerine yaklaşırlar, bu nedenle ("OO nedir" dikkate alınmazsa), OO yeterlidir. Bu literatürde oldukça iyi bilinmektedir ...foothisself
Frank Shearar

1
Er, hayır. O küçük Bkz foo.önünde foo.doSomething()? Bu doSomething()bir parametreyi geçiyorsun. Sadece parantez arasında olmadığı için parametre olmadığı anlamına gelmez. thisYa da selfyöntem içinde bu parametre referans için sadece sözdizimsel şeker.
8bittree

1
@ FrankShearar, hesaplamada sadece iki tane oldukça açık bir ayrım olduğunu söyleyebilirim - veri ve talimatlar. Bu bile (sıradışı) kendi kendini değiştiren kod durumunda pencereden dışarı çıkıyor. OO'da, genellikle "yöntem" (veya "üye işlev") olarak adlandırılan şeyin tanımınızla bir yöntem veya işlev olması gerekmez - genel kullanımdaki tüm bu kelimeler genel ve değiştirilebilir bir anlamla etkin olarak eş anlamlıdır. Varlığını kabul ettiğiniz "saf olmayan işlev", aynı genel "talimatlar" kavramı için bir başka (ve ayrıca en uzun soluklu ve jargonistik) eşanlamlıdır.
Steve,

14

Bruce'un iyi bir cevabı var . Anlamsal olarak ekleyeceğim:

  • Bir prosedür, argümanlara "bir şeyler yapmalı" veya başka bir yan etkiye neden olmalıdır (örn. printf).
  • Bir işlev (a) bağımsız değişkenlerle ilgili bir soruyu yanıtlamalı veya (b) bağımsız değişkenlere dayalı yeni bir değer hesaplamalıdır.
  • Bir işlev yöntemi, nesnenin durumu hakkındaki bir soruyu yanıtlamalıdır
  • Bir prosedür yöntemi nesnenin durumunu değiştirmeli

Mükemmel cevap! Sadece bir küçük ekleme: A procedure should "do something" to the arguments- veya başka bir yan etkiye neden olabilir (örn. printf).
Allon Guralnek

1
@Allon printfBir değer döndüren not - yazdırılan karakter sayısı - bu yüzden teknik olarak bir fonksiyondur.
Sjoerd

@Sjoerd Bunun printfbir değer olduğu konusunda hemfikir değilim . Çalıştırma kapsamı dışında belirli bir yan etkiye sahipti: standart çıktının ne olması gerektiğine göre I / O. Buna rağmen, Scott bu ayrımdan açık değildi, ancak işlevsel programlama işlevlerinde yan etkilerin olmadığı ve döndüğü veriye sahipmiş gibi soruları yanıtlayabilmesi gerekiyordu.
Alan,

4

yukarıdaki iyi ayrıntılı cevaplar; Kısa hikaye şu ki, tüm alt programların lezzetleri olacak; Her bir terimin kastedilen, programlama dili bağlamına göre değişecektir.

genel olarak, işlevler bir değer döndürür, ancak buna gerek yoktur

yöntemler şu anda genel bir OOP terimleridir .

SQL'de, saklı yordamların çıktıları vardır, ancak genellikle yalnızca bir hata kodu döndürür, kullanıcı tanımlı işlevler bir değer döndürmelidir (sonuç olarak belirlenmiş olabilir)

Yine, bu terimler arasındaki kesin fark, kiminle konuştuğunuza bağlıdır!


2

Yeterliliğin% 80'i doğrudan isimlendirme konusundaki aşinalık ile ilgilidir,

Verimliliğin% 95'i, tarif etmek için kullanılan terimlere rağmen, şu anda neyin yararlı olduğunu belirleme yeteneğidir.

Sproc'lara sahip olduğumuz MSSQL kullandığım zamanlar haricinde tüm yöntemleri c # olarak adlandırmayı tercih ediyorum ama elbette şimdi Postgres kullanıyoruz ve bunlara fonksiyon deniyor.


13
Tüm istatistiklerin% 83,5'i yerinde oluşturulmuştur;
Django Reinhardt

1
İtiraf etmeliyim ki, OO olmayan bir dilde çalışırken birinin "yöntem" terimini attığını duyduğumda sinirleniyorum. Deyimsel olmayan bir kodun içine girme ile yakından ilişkili gibi görünüyor.
Racheet

C Koduna başvururken 'Yöntem'i kullanıyorum çünkü uğraştığım birçok OO programcısı terim prosedürünü veya işlevini duymakta zihinsel bir bozulmaya sahip. Eğlence için, eğer onlarla gerçekten uğraşmak istersem, terimleri rastgele değiştirebilirim. İyi değil, bir poltergeist'i evinize davet etmek gibi bir şey ... :)
mattnz
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.