Alıcıları ve ayarlayıcıları birleştirme


16

JQuery gibi JavaScript kitaplıkları, programlama arayüzünde 'getters' ve 'setters' öğelerini birleştirir:

 $('element').css({'color','blue'});

rengi ayarlayacak veya

 $('element').css();

bir öğe için css alır.

Böyle bir model için bir isim var mı ve uygulamalarda kullanmak iyi bir uygulama mı?

Yanıtlar:


12

Martin Fowler kısa süre önce bu makalede Aşırı yüklenmiş alıcı ve ayarlayıcı olarak adlandırdı :

Geçenlerde Javascript'te alay ettim ve bana çarpan bir şey, bir alıcı ve bir ayarlayıcı için aynı işlev adını kullanma alışkanlığı. Bu yüzden jQuery'de bannerınızın $("#banner").height()yüksekliğini öğrenmek isterseniz, kullanacağınız yüksekliği değiştirmek isterseniz $("#banner").height(100).

Smalltalk tarafından kullanıldığı için bu sözleşme bana tanıdık geliyor. İle bir değer alabilir banner heightve ile değiştirebilirsiniz banner height: 100. Bunun küçük bir kongre olduğunu bilmek, benden hoşlanmamı beklemek için yeterli, çünkü o dil için uzak ama uyanık bir aşkım var. Ama en iyi şeylerin bile kusurları var ve bu kodlama stili için sevmediğimi gizleyemiyorum ...

Bu tercihe rağmen, uğraştığınız dilin kurallarına uymanız gerekir. Eğer Smalltalk'ı tekrar yazsaydım, yine height:100de dilin kurallarına uyumu korumak için kullanırdım . Ancak Javascript, güçlü kurallara sahip olduğu için not edilmedi, bu yüzden burada jQuery tarafından kullanılsa bile, bu kuraldan kaçınmayı tercih ederim ...


1
Ben genellikle Fowler'in söylediklerinin çoğuna katılırken, bunun hoşlanmamasına katılmıyorum. Onun akıl yürütmesi, JavaScript'in Smalltalk gibi güçlü kurallara sahip olmamasıdır, bu da orada kullanılabilir olmasını sağlar. Ancak, jQuery güçlü kurallara sahiptir ve JavaScript jQuery değildir. jQuery bir çerçevedir.
CaffGeek

@Chad, bunu okumanıza katılmıyorum. Onun iddiası, açıklık ve tutarlılıktan yoksun olmasıdır. Smalltalk'ta kullandığını söylüyor çünkü diğerleriyle tutarlılık endişelerini ortadan kaldırıyor. Smalltalk'in sözleşmelerinin bir şekilde sorunu hafiflettiğini veya ortadan kaldırdığını iddia etmiyor.
Winston Ewert

2

OO dillerinde "yöntem aşırı yüklenmesi" veya OO olmayan dillerde "işlev aşırı yüklenmesi" olarak adlandırılır.

İyi bir uygulama olup olmadığı, kamu üyeleri ve alıcılar / belirleyiciler kadar tartışmalı bir konudur. Profesyonel ve aleyhte olanlar muhtemelen dişlerini bu özelliğe sahip olan ya da olmayan ve kendi yollarına yerleştirilmiş diller üzerinde kesiyorlardı. Bunu birkaç nedenden dolayı kullanıyorum ve uygulamayı seviyorum:

  • İçinde oldukça iyi kullanıldığı bağlam, birini diğerinden ayırır.
  • Yöntem adının başına getveya sonuna setekleme ayrıntı düzeyi ekler.
  • Birden fazla alıcı varsa (örneğin, biri için intve biri için double), bir ödevin LHS'sindeki ( int x = foo.bar()vs. double x = foo.bar()) türün değiştirilmesi , sınıf her ikisini de sağlıyorsa sağ tarafta bir kod değişikliği ( barAsInteger()vs. barAsDouble()) gerektirmez . Bunun aşağı tarafı, bazen sadece koda bakarak hangi yöntemin çağrıldığını bilmek zor olabilir.

C ++ 'da "işlev aşırı yüklenmesi" olarak da adlandırılır.
DeadMG

Her iki terim de C ++ için geçerlidir çünkü hem yöntemlere hem de çıplak işlevlere sahiptir.
Blrfl

1

JavaScript gerçek özelliklere sahip olmadığından (bir değer ayarlamanın gerçekte kodu yürütebildiği), pıtırtı özellik deyimini uygulayan değerdir. (Başka bir şey bile olsa)

Yani, gayrimenkulleri uygulayan dillerde, bunun yerine bunu yapardınız:

element.css = ...
x = element.css

JavaScript kalıbını özellikleri işleyen bir dilde kullanacak olsaydınız, anormal bir şey yapardınız. Bu muhtemelen iyi bir fikir olmazdı. Özellikleri dilin bunları ele alma biçiminde kullanın, böylece sizinle çalışan diğer insanları karıştırmazsınız.


msgstr "burada bir değer ayarlanması gerçekten kod yürütebilir" Bu aslında doğru değil. ECMA 5
Demian Brecht'ten

@Demian: Ancak, JQuery ECMA 5'i uygulamayan tarayıcılarda çalışıyor
John Fisher

Tarayıcılar arası uyumluluk hakkında hiçbir şeyden bahsetmedim, sadece alıntı yazıldığı gibi yanlış.
Demian Brecht

@Demian: JavaScript'in en yaygın sürümlerini kullandığını varsayarsanız "JavaScript'in gerçek özellikleri yoktur" metni doğrudur. JQuery uygulaması bağlamında tartıştığımız için ifade doğru olacaktır. Yine de, JavaScript'in yeni sürümlerinin gerçek özelliklere sahip olduğuna dikkat ettiğiniz için teşekkür ederiz.
John Fisher

1

Basit bir nedenden ötürü buna tamamen karşıyım: Bir Sınıf, Yöntem veya İşlev sadece bir şey yapmalı - bence ve getterve setteryöntemini birleştirmek bu kuralı ihlal edecek. Sonuç olarak:

  1. returnFonksiyonun değeri ise göre değişir alıcı veya ayarlayıcı blok yürütülür olsun. Bu sizi sadece bir sürdürülebilirlik kabusu haline getirebilir. Kişisel yöntem her durumda veri / nesne, sadece bir tür dönmelidir - veya iade null, falseya da atmak exceptionhata durumunda.
  2. Birim Testleri Yazmak , işlev tamamen farklı iki işlevsellikten sorumlu olduğu için daha zor olacaktır.
  3. Bu tür bir yöntem veya işlev için belgelerin yazılması açık nedenlerle zordur.
  4. Yanıtta daha önce belirtildiği gibi birden fazla alıcı yöntemine ihtiyaç duyulduğunda tutarlı olmayacaktır Blrfl.

0

Bence sen arıyorsun properties


C # 'da (ve belki de diğer .NET dillerinde?) Sağlanan işlevsellik adı buna benzer, ancak gerçekten aynı şey değildir.
Thomas Owens


Teşekkürler, gerçekten ayarladığınız bir vaka söz sahibi veya uygulamadaki bir kişi maaş alabilirsiniz değil person.salary('10000')ya person.salary()veya benzer.
yannis

1
Nasıl olduğunu göremiyorum. Orijinal özelliklerdeki örnekte doğru olmayan "Özellikler alanlar gibi okunur ve yazılır". Orada, açık yöntem çağrıları yapılır. Çok benzer, ama tam olarak aynı değil.
Thomas Owens

1
@yannis Bu doğru değil. JavaScript'in özellikler için bir sözdizimi vardır ve orijinal soruda açıkladığınız şey bu değildir. JavaScript'te özelliklerin nasıl uygulanacağı ve kullanılacağı hakkında bilgi için bkz. En.wikipedia.org/wiki/Property_(programming)#JavaScript .
Thomas Owens
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.