Daha iyi Show () + Hide () veya SetVisible (bool görünür)?


59

Hangisi daha iyi ve neden? (Arayüz tasarımı açısından):

a) İkisine Show()ve Hide()fonksiyonuna sahip olmak

b) Bir SetVisible(bool visible)işleve sahip olmak

EDIT: Örneğin, bazı nesnelerin görünürlük durumu vardır ve bu fonksiyonlar onu değiştirmek için kullanılır.

c) her üç sahip olmak Show(), Hide(), SetVisible(bool visible)işlevlerini


4
Hangi bağlamda? Genellikle önemli değil
Aviv Cohn


6
Neden hepsine halka açık değil? Her zaman gösterileceğini veya gizleneceğini bildiğiniz durumlar vardır ve şartlı olarak göstermek veya gizlemek isteyebileceğiniz durumlar vardır.
14'te

@ pllee: Bu muhtemelen çok iyi bir nokta.
user3123061

4
Java'da, büyük harf olmadan görünür, gizlenir ve gösterilir.
Pierre Arlaud

Yanıtlar:


81

Tercih ediyorum SetVisible(bool visible), çünkü müşteri kodunu şöyle yazmamı sağlıyor:

SetVisible(DetermineIfItShouldBeVisible());

yazmak zorunda kalmak yerine

if (DetermineIfItShouldBeVisible()) {
    Show();
} else {
    Hide();
}

SetVisibleYaklaşım aynı zamanda daha kolay uygulanması için izin verebilir. Örneğin, belirli bir somut sınıf basitçe metodu kompozit sınıflarına devrederse, SetVisibleuygulanacak daha az bir yöntem demektir.

void ButtonWithALabel::SetVisible(bool visible) {
    myButton.SetVisible(visible);
    myLabel.SetVisible(visible);
}

25
Aynı şekilde, Dil'inizin desteklediğini varsayarak Visible'ı bir özellik yapabilirsiniz. MyObject.Visible = false;daha sezgisel olarak beni vururMyObject.SetVisible(false);
Brian

9
@Bri Benim için daha az okunabilir ve hata ayıklanabilir, çünkü program davranışını gözlerime saklıyor - temel yöntem çağrısı - ama bu başka bir hikaye. Java bu sözdizimini desteklemiyor, yine de tercih ve göz eğitimi meselesi.
ignis

10
SetVisible()(bana) aslında hiçbir şey göstermediğini göstermez. Bir nesnenin görünürlük özelliğini ayarladığınız gibi , nesnenin görüntülenip görüntülenmeyeceğini veya gizlenip gizlenmeyeceğini belirlemek için muhtemelen bu özelliğin değerini kontrol etmek için karşılık gelen Refresh()veya Redisplay()yönteme bırakan bir okur .
TMN

1
Ne yazık ki Java, C # yaptığı gibi özellikleri desteklememektedir, yalnızca yukarıda gördüğünüz alıcıları ve ayarlayıcıları desteklemektedir.
GreenCabbage

1
@TMN: Görünürlüğü önleyen başka faktörlerin yokluğunda (Z düzeni, ebeveyn görünürlüğü, konum vb.) setVisible(true), Sistemin önceden boşta olmasa da, sistemin bir sonraki boşta iken çekileceği bir işlemi harekete geçirmesini beklerdim . Bunun refresh, nesnenin görüntüsünü hızlandırmak için faydalı olabileceğini, ancak nesnenin nihayetinde ne olursa olsun çizileceğini beklerdim (örneğin, görünürlüğü falsegerçekleşmeden önce ayarlanmadığı sürece ).
supercat

35

Aynı işi yapmak için birden fazla işlevi öneren tüm posterlere katılmıyorum. Bir yerine üç fonksiyonları çok kabartmak gibi görünmeyebilir iken, sınıf birçok tür fonksiyonları (örn ile bitirmek muhtemel olduğunu unutmayın setEnabled, enable, disablebir ile sona erecek) ve böylece bu yaklaşımın çok daha büyük sınıf arayüzüne. Dahası, sınıfınızdaki her ne olursa olsun, benzer iskan fonksiyonlarından / özelliklerinden bir demet ile sonlanmanız ve fonksiyonların çarpılması hangisinin neyle gittiğini daha da gizleyecektir.

Özellikleri destekleyen dillerde, bunlar tercih edilmelidir, ancak ne Java ne de C ++ 'ın yapmamasından dolayı, bunun bir tartışma noktası olduğunu düşünüyorum.

setVisible()Bu nedenlerden dolayı tercih edilmesi gerektiğini düşünüyorum :

  1. Ters fonksiyonun ne olduğu hemen bellidir. Sizi geri setVisible(false)aramak setVisible(true)için hide()kolayca zıttı olabilirken arayın reveal().
  2. Hangi durumda kod alması gerektiğine karar verdiğinizde programa göre basittir, yani setVisible(wantToSee)bir ififade kullanmak yerine çağırabilirsiniz .
  3. Birden çok benzer işleve sahip olduğunuzda, setX()biçim genelleşir, böylece bir dizi tutarlı işleve sahip olabilirsiniz, oysa verhed yaklaşımı, aradığınızı bilmiyorsanız, bulunması zor olan bir dizi işlev ortaya çıkarır. API'lardaki tutarlılık, öğrenmelerini ve hatırlamalarını önemli ölçüde kolaylaştırır.

3
C ++ özelliklere sahip değildir, ancak serbest işlevleri vardır, böylece sınıf arabirimini yeni üye işlevleri eklemeden, yani daha düşük bir birleştirme derecesiyle genişletebilirsiniz.
phresnel

Qt genellikle her üçünü de bir kolaylık olarak sağlar, böylece hide () ve show () sinyal / slot sistemi kullanılarak doğrudan diğer olaylara bağlanabilir. Bu aslında slot sisteminin bir kısıtlaması olsa da - boost :: fonksiyonları gibi bir şey kullanıyor olsaydı, doğru / yanlış argüman geri çağırmayı ayarlama noktasında bağlanabilir.

1
"Özellikleri destekleyen dillerde, bunlar tercih edilmelidir, ancak ne Java ne de C ++ 'ın yapmamasından dolayı, bunun bir tartışma noktası olduğunu düşünüyorum." şart değil. Alıcı / belirleyici tercih edildiğinde? Evet. Fakat set_visible aslında bir pasör değildir.
Miles Rout

19

Gösterme ve gizlemenin bağlamda ne anlama geldiğine bağlıdır . İlk önce hangisinin "ana yolunuz" olduğunu bulmak ve bunu geliştirmeye odaklanmak istiyorsunuz:

  • Seçme nedenleri setVisible(bool)
    • Bu sadece basit bir bit çevirmedir veya nesneniz temelde tutuluyor
    • Hedefiniz zamanının çoğunu bir CRUD çerçevesinde geçirecek
    • Gösterme ve gizleme arasında kolayca paylaşılan bir çok kod vardır.
  • Seçme nedenleri show()vehide()
    • Nesnenin tüm konteynırlarını görünürlük durumları için kontrol etmesi gerektiği veya bir geçiş animasyonunu tetiklediği zaman gibi önemli bir yan etki veya çok sayıda mantık çalıştırılıyor .
    • Niyeti ifade etmenin önemli olduğu bir etki alanı modelinin parçası mı?

Tamam, şimdi "altın standart" çekirdeğini kodladınız, nesneyi kullanacak hayatı kolaylaştırmak için diğer stile ince bir kolaylık yöntemi eklemenin değip değmeyeceğini bulmanız gerekiyor.

  • Kolaylık setVisible(bool)
    • Önemsiz koşulları olan ve yalnızca görünürlüğü etkileyen if-ifadelerinden kaçınmanızı sağlar (ör. setVisible(a==b))
    • Gerçekleşmesini beklediğiniz bir şeyse, belirli alıcı / ayarlayıcı çerçevelerine kablolanabilir
  • Kolaylık show()vehide()
    • Birinci sınıf fonksiyonları ve geri aramaları olan bir dilde faydalıdır (ör. onSuccess(widget.show))
    • Programın ne yapmaya çalıştığını hızlı bir şekilde görebildiğiniz için yığın izleri ve performans profili ile okumak çok daha kolay

TLDR: Hangisinin en önemli olduğunu bulun, uygulayın ve sonra kendinize diğer stili ince uygunluk yöntemleri olarak eklemeye değip değmediğini sorun.


11

Ben "üçü" derdim.

Show()ve Hide()daha grok kolay olma eğilimindedir SetVisible(true)ve SetVisible(false). Ancak, görünürlüğü mantıklı bir şekilde ayarlamak istediğinizde, bunun etrafında boolbir inşa etmekten ziyade bir yönteme sahip olmak daha iyidir .ifbool

Üçünü de mantığı ve en az boyler plakasını çoğaltmadan destekleyebilirsiniz:

void Show() {
    foo.Show();
    bar.Show();
}

void Hide() {
    foo.Hide();
    bar.Hide();
}

void SetVisible(bool visible) {
    if (visible) {
        Show();
    } else {
        Hide();
    }
}

Alternatif olarak, sarmakta olduğunuz şeyler daha SetVisible-ish bir API’ye sahipse:

void Show() {
    SetVisible(true);
}

void Hide() {
    SetVisible(false);
}

void SetVisible(bool visible) {
    foo.SetVisible(visible);
    bar.SetVisible(visible);
}

40
Microsoft bu yaklaşımı başlatmak ve durdurmak için kullanır System.Windows.Forms.Timer. Şahsen, bunu kafa karıştırıcı buluyorum. Her iki gördüğüm zaman Showve SetVisiblebenim ilk eğim iki fonksiyon arasında bazı önemli bir fark olup olmadığını merak etmektir.
Brian,

1
Bu karışıklığı gidermek için kolayca belgeleyebilirsiniz. Bunun basit bir örnek olduğu gibi değildim.
Garry Shutler

20
Şimdi, X'i derste rahat hissetmeden önce belgeleri okumak için fazladan harcayacağım mı? Ya da, alternatif olarak, X'in kafamı karıştırmak için fazladan zaman harcamam mı gerekiyor (ya da böcekleri ortaya koyuyor)? Tabii, X böyle bir şey için oldukça küçük, ama kesinlikle sıfır değil. 3 seçeneğin tümünü sunmak, gerektiği kadar üç kez işlev sunmak anlamına gelir, bu da daha fazla iş dokümanı harcayacağınız anlamına gelir ve dersin nasıl kullanılacağını öğrenmek için daha fazla iş harcıyorum. Ayrıca, farklı geliştiricilerin sınıfınızı kullanırken tutarsız kalmaları için bir yol daha sunar.
Brian

5
Bu, SOLID ilkelerinden biri olan Arabirim Ayrıştırma ilkesinin açık bir ihlalidir. Yaklaşımınıza karşı bir başka görüş ise, pratik pratik tasarımında bir API içinde bir şeyi yapmanın sadece bir yolunu sağlamada ısrar eden, netblog tasarımcısı jaroslav tulach'a ait.
AlfredoCasado

@AlfredoCasado Katılıyorum. Peki ya SetVisible korunuyorsa ? Buna bir alt sınıftan erişebilirsiniz, ancak bu arayüzle (API gibi) verilen bir varlığa yapılan çağrı Gizle / Göster şeklinde olur.
Pierre Arlaud

5

Show () ve hide () 'ı tercih ediyorum, aslında, bir boolean alan her yöntem, API'nin amacını daha iyi ifade eden iki yöntem için değiştirilebilir. Örneğin, temiz koddaki Robert Martin, bir argüman olan yöntemler yerine sıfır argümanlarla tercih edilen yöntemleri önerir.

Benim için bir başka önemli argüman da okunabilirlik, bence iyi kod, nesir gibi okunabilir, "garip bir şey" main_window set "yerine" main_window setVisible false "gibi bir şey. Yazılım programlarında dil inşası mükemmel bir şekilde mümkün olduğunda daha doğal bir dil kullanın.


1
Assembler yeterince nesir değil mi?
Alexander

Dizinin it.setVisible(false); it.setVisible(true);, bir denetimin ebeveyninin görünürlüğünü etkilememesi ve denetimin Z sırasını veya konumunu etkilememesi beklenir. Buna karşılık hide(); show(); Bir kontrolün ebeveynini makul bir şekilde görünür olmaya zorlayabilir, diğer kontrollerin üzerinde hareket ettirebilir ve konumunu görülebilecek bir yerle sınırlayabilir. Bazı durumlarda, bir şey yukarıda belirtilen olduğu gibi (aslında görünür olduğundan emin yapmanın bir anlamı var faydalıdır show(), ancak diğer durumlarda görünürlük bayrağını değiştirmek için yararlıdır olmadan . Başka bir şey değişiyor
Supercat

Nesne Yönelimli bir API'da "bayrak" yoktur, OO mesajlaşma ile ilgilidir, onun başka bir nesneye anlatması, nesnenin durumu olan "bayrakları" değiştirmeyle ilgili bazı görevleri yerine getirmesi hakkındadır. Kontroller, ebeveynler, siparişler ve muhtemelen diğer API'ler ile önceki deneyimlerinize dayanarak beklediğiniz şeyler hakkında birçok varsayımda bulunuyorsunuz, bir alan hakkındaki kişisel duygu ve varsayımlara dayanarak bir API tasarlama çok kötü bir fikir.
AlfredoCasado

5

Yöntemin ne kadar etkileyici, daha okunaklı ve sonuç olarak kodun korunabileceğine inanıyorum. Aşağıdaki iki durumu göz önünde bulundurun:

Dava 1:

void showCustomerData(customerId){
  Customer customer = getCustomer(CustomerId);
  customerPanel.setVisible(customer.isCustomerEnabled());
}

Durum 2:

void showCustomerData(customerId){
  Customer customer = getCustomer(CustomerId);
  //always show customer panel
  customerPanel.setVisible(true);
}

İlk durumda, "setVisible" işlevinin ne yaptığı açıktır, ancak okumak istiyorsanız şunu söyleyiniz:

Müşteri panelini müşteri etkinse görünür olarak veya müşteri devre dışıysa gizlenmiş olarak ayarlayın.

Söylemek daha açıklayıcı olsa da:

  • Müşterinin durumunu kontrol et:
    • müşteri etkinse müşterinin panelini göster
    • Aksi takdirde, gizleyin

"Case 1" işlevini aşağıdaki gibi değiştirecek:

void showCustomerData(customerId){
  Customer customer = getCustomer(CustomerId);
  if(customer.isCustomerEnabled()){
    customerPanel.Show();
  }
  else{
    customerPanel.Hide();
  }
}

daha fazla kod üretir, ancak daha okunaklıdır.

İkinci durumun, paneli göstermek istediğinizi zaten bildiğiniz için açık bir kusuru var, öyleyse neden "Göster" işlevini kullanmıyorsunuz?

"SetVisible" kullanmanın kesinlikle yanlış olduğunu söylemiyorum, ancak zaman içinde sizin tarafınızdan yazılmayan kodu okumaya çalıştığınızda kafa karıştırıcı olur ve "Bir fonksiyon sadece bir işlem yapmalı" kuralına uymaz.


Diyorum ki: show customer panel iff the user/customer is enabled. Örnek olarak okumak kadar kolay olmayan birçok karmaşık koşulun olabileceğine katılıyorum, ancak bu durumlarda bu koşulları farklı çizgilere bölerim.
ComFreek

5

Hide()/ Show()Alternatifin çekici olduğuna inanıyorum, çünkü olanları anlamaktan daha kolay; SetVisible(true)tek bir fonksiyona sahip olmak tercih edilebiliyor, çünkü birçok şartlı durumdan kaçınıyor.

Bu durumda, giriş olarak bir numaralandırma kullanmanızı öneririm SetVisible, bu yüzden ya SetVisible(Visibility.Visible)da elde edersiniz SetVisible(Visibility.Hidden). Tek bir işleve sahipseniz, hangi işlemin yapıldığını anında okuyabilirsiniz.

Java'nın adlandırma kurallarına kullanarak, belki olurdu setVisible(Visibility.VISIBLE)ya setVisible(Visibility.HIDDEN).


3

Darien'in cevabına katılıyorum, ancak C # programcıları bakış açısından bir bakış açısı eklemek istedim.

'SetXXX' yazan bir kod gördüğümde, bir şeyin değerini belirlediğini söylemek için okudum, bu şeyin o değeri ayarlamaktan başka yan etkileri olmasını beklemiyorum ve bunun doğru olmadığını düşünüyorum. (yani aynı değerde ayarlamaya devam edebilirim ve sorun yok). Bir alana erişmek gibi bir şey. Genel olarak bir 'setXXX' ile birlikte bir 'getXXX' yöntemi görmeyi de beklerdim.

Java ve C ++ 'da beklediğinizin bu olup olmadığını bilmiyorum, ama C #' da beklediğim şey bu, C # 'da olsa Özellikler diye kısa bir el var. Ve burada Özellikler'in nasıl kullanılacağına ilişkin bazı güzel rehberler ( http://msdn.microsoft.com/en-us/library/ms182181.aspx ).

Bu görünüm göz önüne alındığında, seçeceğim arayüz, herhangi bir yan etki olup olmadığına bağlıdır (bu alan değerini değiştirmek dışında):

Eylemin yan etkileri varsa, örneğin bir iletişim kutusu gösteriyorsa "Show ()" ve "Hide ()" ile giderim.

Yan etkileri yoksa, "pencere öğesinin" görünürlüğünü belirlediğimi ve başka bir şeyin bu duruma göre ayarlanacağını ve ardından setVisibility veya setIsVisible kullanacağımı söyleyin. (Ben buna SetVisible demiyorum).

C # 'da (Java hakkında emin değilim), bir UI çerçevesinin nesnelerdeki değişiklikleri dinleyeceği ve Görünürlük gibi bir özellik değiştiğinde UI'yi otomatik olarak yeniden oluşturacağı bir gözlemci modeli kabul etmek oldukça yaygındır. Bu, setIsVisible işlevini çağırarak değeri ayarlamanın yan etkileri var gibi göründüğü, ancak tanımımda görünmediği anlamına gelir. Widget'ın sözleşmesi, "IsVisible" ı temsil eden alan değerini ayarlayarak yerine getirilir.

Başka bir deyişle, form gösterilmeden önce bir etiketin formdaki görünürlüğünü değiştirmem benim için sorun değil. Yani label.getIsVisible == true, ancak form gösterilmemiştir.

Form gösterilmezken Hide () 'u aramam uygun değil.


1
Sizin açıklaması getXXX()ve setXXX()yan etkileri olmadan bir alan erişmek için bir yol olarak yöntemler Java ve gibi sesler değil C #. Özelliklere sahip olmadığı için Java'da yapmanız gereken budur . C # 'da böyle bir kod görürsem, C #' daki özellikleri henüz öğrenmemiş olan bir Java geliştiricisi tarafından yazılmış olduğunu tahmin ediyorum.
gilly3

İçin +1 SetVisibility.
akaltar

@ gilly3 - Evet, elbette. Ve, "Özellikler" CLR'de mevcut değildir, C #, IL'de get_XXX ve set_YYY yöntem çağrıları anlamına gelir. Demek istediğim şu: soru bağlamında, eğer setXXX'i gördüyseniz, Java’daki getXXX’in C #’daki özelliklerle aynı anlambilimiyle çalışmasını beklersiniz. Bu doğru, o zaman C # 'daki özellikler için aynı kuralların Java'daki setXXX ve getXXX çiftleri için geçerli olmasının nedeni. Gönderide referans gösterdiğim kurallara katılıyorum ve bu yüzden bu senaryoda kullanmak için aynı yönergeleri Java'da arayüzü tanımlarken savunuyorum.
Daniel James Bryars

1
"Yan etkiler" derken, "gözlemlenebilir" bir şey olmakla ilişkili olanlar dışında "demek istediğinizi açıklığa kavuşturmak yardımcı olabilir. Tercih ettiğim kural, bir getXXçağrının karşılık gelen bir setXXyöntemi varsa, setYYonu etkilememesi gerektiğini, ancak yöntemi getZZolmayan bir çağrıyı etkileyebileceğini söylemektir setZZ.
supercat

2

Biraz değiştirilmiş bir arayüz öneririm:

Show();
Hide();
ToggleVisible();
ToggleVisible(bool visible);

Daha iyi isimler

Bu yöntem adları, geliştiricinin yapılması gerekenlere dayanarak hangi yöntemi kullanacağına karar vermesine yardımcı olur. Oysa SetVisible(bool visible)bu aynı semantik anlam taşır, çünkü bir geliştirici karıştırmayın olabilir Show()ve Hide(), Toggle()harekete belirleyen durumun varlığını ima eder. Böylece, her bir yöntemin ne zaman kullanılacağı geliştirici için sezgisel hale gelir.

Azaltılmış kod yedekleme

Arayüzünüzde çoklu yöntemlere sahip olmanın yararı, arama kodunu basitleştirmesidir. Sadece ortaya çıkarabilir Show()ve Hide(), ama:

  • SetVisible()Sahnelerin arkasındaki asıl işi yapmak için muhtemelen bir tür özel yöntem gerekir (ya da Show()ve için gereksiz kodlar yazarsınız Hide()).
  • Hangi kodun kullanılacağını seçmek için / else engellerse, çağıran kodun fazladan desteği olabilir. Bu benim görüşüme göre kodu şişiriyor.
  • Tüketici olsaydım, kod kısıtlamasını önlemek için SetVisible()(ya da Toggle()gereksiz koddan nefret ederim) zaten ne yaptığını yapan kendi sarmalayıcı fonksiyonumu yazabilirim . Bu nedenle , uygulamada muhtemelen özel bir yöntem olarak var olan bir yöntemi çoğaltmak .

1
Çoğaltma yöntemi mantıklı geliyor, ancak kendim yapmam. Öte yandan, toggleVisible (bool) 'un sezgisel olduğuna katılıyorum. Bana göre, bool'dan geçen boğanın doğru olması durumunda değişmesi gerektiği anlamına geliyor, ki bu garip olurdu, ama ben yabancı gördüm. Bunun gerçekten kılık değiştirmiş bir işlev olduğunu varsaymazdı.
Patrick M

0

Ben SetVisible(bool)sadece görünürlüğü iki kez değiştirmek (göstermek ve yeniden gizlemek veya gizlemek ve yeniden göstermek) herhangi bir şeyi işlem yapılmadan önceki gibi aynı durumda bırakacak olsaydı kullanmanızı öneririm ( eğer göstermek ve yeniden gizlemek iyidir. bir şey veya bunun tersi, "otomatik olarak" olması beklendiği takdirde yeniden çizim ihtiyacı olan nesneleri bırakır). Bir nesneyi gizlemek ve göstermek, bir bitlik durumun değiştirilmesinden başka bir etkiye sahip olmazsa, görünürlük parametresini kabul eden bazı yöntemlere sahip olmak dış kod için mantıklı olur ve bu kodun yazılması kolaylaşır SetVisible.

Bir nesneyi gizleme ve yeniden gösterme, Z sırasını değiştirme gibi yan etkilere sahipse, bu tür eylemlerin büyük olasılıkla ayrı yöntemlerle gerçekleştirilmesi gerekir. Bu gibi durumlarda, "görünürlük" parametresi kabul eden dış yöntemlerin faydası sınırlı olacak ve bu yüzden bunları kolaylaştırmanın çok az avantajı olacaktır. Ayrıca, bir SetVisibleyöntem (yanlış) nesnelerin görünürlüğündeki değişikliklerin yan etkiler olmadan yapılabileceğini önerecektir.

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.