SlideShare uma empresa Scribd logo
1 de 70
Baixar para ler offline
MVC, MVP ve Mediator ile TDD
       Tecrübeleri

          Kenan SEVİNDİK
Mimarisel Bir Örüntü: MVC


                       Controller


                                       Kullanıcı girdileri
Veri değişiklikleri                    ve UI olayları



                      Bildirimler

          Model                         View

                        Veri erişimi
MVC'nin Amacı




Trygve Reenskaug'un Hedefi
         Neydi...?
Trygve Reenskaug'un Hedefi


              Kullanıcının zihnindeki
                “mental model” ile
              bilgisayar sistemindeki
                  “sayısal model”
                arasındaki boşluğu
                    doldurmaktır!
Trygve Reenskaug'un Hedefi
45
                             40
40
                             35
35
                             30
30
                             25
25                       1   20
                         2                                Row 1
20                       3   15

15                           10

10                            5

                              0
 5
                                  1   1.5   2   2.5   3
 0
     1   2   3




                 Model
Günümüzdeki Kullanım Amacı:




      “Seperation      of Concern”
Reenskaug'un makalelerinde asıl amaç değildir,
               bir sonuçtur!
Günümüzdeki MVC Yorumlaması


            Controller




                         Model



              View
MVP Sahneye...
MVC ve Veri Yönetimi

                                                      Elimdeki veriyi
Verinin oluşturulması,                                nasıl yönetmeliyim?
Güncellenmesi veya                                    Sorusuna cevap bulmaya
Silinmesi gibi konularla             Controller       çalışılır
Ilgilenen kısımdır


                                                     Kullanıcı girdileri
              Veri değişiklikleri                    ve UI olayları



                                    Bildirimler

                        Model                         View

                                      Veri erişimi
Elimdeki Veriyi Nasıl
                Yönetmeliyim?
   Elimdeki veri neden oluşur? Nedir?
       Encapsule edilmiş veri alanları, property'ler
   Uygulama içerisinden veri nasıl seçilir?
       Metinsel seçimler
       Satır ve sütun seçimleri
       Bir grup elemanın veya bir bloğun seçilmesi
   Veri nasıl güncellenmeli?
       CRUD işlemleri, taşıma, kopyalama, silme,
        yapıştırma...
MVC ve Kullanıcı Arayüzü
                    Etkileşimi
Kullanıcı ile veri arasındaki
etkileşime odaklanan                                      Kullanıcı veri ile nasıl
kısımdır                                                  etkileşime girer? sorusuna
                                                          cevap arar
                                        Controller


                                                        Kullanıcı girdileri
                 Veri değişiklikleri                    ve UI olayları



                                       Bildirimler

                           Model                         View

                                         Veri erişimi
Kullanıcı Veri İle Nasıl Etkileşime
            Girmeli?
   Veri ekranda nasıl gösterilmeli?
       GUI oluşturma ve gösterme işlemi
   Kullanıcı girdileri ve UI olaylarından veri
    güncelleme işlemlerine nasıl geçiş olmalı?
       Kullanıcı işlemleri, fare ve klayve girdileri
Model View Presenter

    UI event'leri uygulamaya özel event'lere
    dönüştürülür


                                    Presenter



    UI üzerindeki değişiklikler
    Presenter tarafından
    yansıtılır
                                                Model üzerindeki
                  Presenter                     Değişiklikler
                  Model üzerinde                Event'ler
                  Değişiklik                    Ile Presenter'a
                  Yapabilir                     iletilir
                  Model verisine      Model
                  erişebilir
MVP Türevleri...
Passive View
Etkileşimin yönü

Bildirimler
                         Model




    Presenter




                         View
Supervising Controller


  Presenter




                  Model




    View
Nereden Başlamalı?

 Nasıl Kodlamalı?
Modelden?
Ekranlardan?
Önce Presenter

             Çünkü...
     kullanıcı senaryoları ve
gereksinimler bire bir Presenter
 içindeki fonksiyonlara karşılık
           gelmektedir
Çünkü...
          Geliştiriciler Presenter kısımlarını
          kodlamaya odaklanabilirler

          Kendi içlerinde de fonksiyonel
          gereksinimlere göre gruplara ayrılarak
          paralel çalışabilirler
                                                        Presenter Kodları



 Fonksiyonel                     View
Gereksinimler                  Arayüzleri




                                                              View
                                                        Implementasyonları
UI geliştiriciler ise tamamen GUI geliştirmeye
odaklanabilirler. View içerisinde sadece UI
widget'ların oluşturulması, sayfalara yerleştirilmesi
söz konusudur.
Çünkü...

  Geliştirme sürecinde TDD
yaklaşımına uygun çalışmaya
    olanak sağlamaktadır


View, Model ve ihtiyaç duyulan
servis bileşenleri mock'lanarak
       Presenter'a verilir
Presenter ve TDD

İkincil
Nesne
                                   İkincil
                                   Nesne



                  Asıl Nesne
               (Birim teste tabi
               tutulan nesnedir)




              İkincil
              Nesne
İkincil Nesneler ve Mock
                  İşlemi
   Gerçek implementasyonları hazır olmayabilir
   Hazır olsa bile test ortamında yaratılması
    çalıştırılması zor olabilir
   Ya da çok yavaş çalışabilir, network veya dosya
    sistemi ile ilişkisi olabilir
   GUI bağlantısı söz konusu olabilir
   Bu ve benzeri nedenlerle ikincil nesnelerin
    asılları yerine sahteleri kullanılır
   Bunlara “mock” nesneler adı verilir
Durum / Etkileşim Tabanlı
    Test Yaklaşımları
Etkileşim Tabanlı             Durum Tabanlı
          Yaklaşım                    Yaklaşım
   Mock nesneler               Birincil ve ikincil
    üzerinde, test edilen        nesnelerin ilgili
    davranışla ilgili            davranış sonrasında
    metotların uygun             doğru state
    sayıda ve şekilde asıl       değerlerini yansıtıp
    nesne tarafından             yansıtmadıklarını
    çağırıldığını kontrol        kontrol eden birim
    eden birim test              test yaklaşımıdır
    yaklaşımıdır                İkincil nesneler
                                 olarak asılları
                                 kullanılır
Örnek 1

   Örneğin kullanıcımızın, text alana girilen bir
    metin içindeki Türkçe karakterleri anında
    İngilizce'ye dönüştüren bir program talep ettiğini
    farz edelim.
UI Mockup




Kullanıcı ile diyalogların sonucunda kullanıcı arayüzü taslak olarak ortaya
çıkar. Kullanıcının ihtiyaç duyduğu, olmasını istediği fonksiyonaliteler,
bu fonksiyonları UI üzerinden nasıl tetikleyeceği gibi konular kullanım durumu
senaryolarının oluşturulması esnasında tespit edilir.
Sınıf ve Arayüzler
                             2     Metin içindeki karakterlerin dönüşümü
                                   Presenter tarafından yönetilir



                                                       3
                                                  TextArea.setContent(...)
                                                  metodu ile sağ taraftaki
         1                                        textarea'nın içeriği
                                                  güncellenir
ContentChangedEvent
ile sol taraftaki textarea
daki metin değişikliği
Presenter'a bildirilir
Birim Testleri
@Mock
private TextArea left;

@Mock
private TextArea right;

@Mock
private ContentChangedEvent event;
                    Action kısmı            Event kısmı

@Test
public void contentShouldBeConvertedWhenTextChanged() {
   Mockito.when(event.getText()).thenReturn("çÇöÖşŞıİğĞüÜ");

    TR2ENConverterPresenter presenter = new
             TR2ENConverterPresenter(left, right);

    presenter.contentChanged(event);

    Mockito.verify(right).setContent("cCoOsSiIgGuU");
}
Presenter Implementasyonu
private TextArea left, right;

public TR2ENConverterPresenter(TextArea left, TextArea right) {
   this.left = left;
   this.right = right;

    left.addContentChangeListener(this);
}

@Override
public void contentChanged(ContentChangedEvent event) {
   String content = event.getText();

    content = content.replace('ç', 'c').replace('Ç',
          'C').replace('ı', 'i')
          .replace('İ', 'I').replace('ö', 'o').replace('Ö', 'O')
          .replace('ş', 's').replace('Ş', 'S').replace('ğ', 'g')
          .replace('Ğ', 'G').replace('ü', 'u').replace('Ü', 'U');

    right.setContent(content);
}
View Implementasyonu
public void addContentChangeListener(ContentChangeListener
listener) {
                                    Presenter event listener olarak kendini
   listeners.add(listener);         register etmek için bu metodu kullanır
}

public String getContent() {                          UI state'e erişime
   return (String) textArea.getValue();               ve değiştirmeye imkan
}                                                     sağlayan metotlar

public void setContent(String content) {
   textArea.setValue(content);
                                                           UI event'in uygulama
}                                                          event'ine dönüşümü

public void textChange(TextChangeEvent event) {
   ContentChangedEvent contentChangedEvent = new
                  ContentChangedEvent(event.getText());
   for(ContentChangeListener listener:listeners) {
      listener.contentChanged(contentChangedEvent);
   }
}
Örnek 2

   Bu örnekte de kullanıcımız sıcaklık değerini
    birer birer artırıp düşürdüğü bir gösterge istiyor.
    Sıcaklığa göre göstergedeki değerin arka planı
    dinamik olarak renk değiştirmeli.
UI Mockup




Kullanıcı + ve – butonlarına tıklayarak sıcaklık değerini birer birer artırıp
düşürebilecek. Sıcaklık değeri 0'ın altında iken arka plan mavi, sıfırın üstünde
yeşil, 20 derece'nin üstünde sarı, 40 derecenin üstünde de kırmızı olmalı.
Sınıf ve Arayüzler
Birim Testleri
@Mock
private TempButton incButton;

@Mock
private TempButton decButton;

@Mock
private TempText tempText;

@Mock
private TemperatureChangeEvent event;

private Temperature temperature;

private TemperatureTrackerPresenter presenter;
Birim Testleri
@Test
public void textShouldBeUpdatedWhenTemperatureChanges() {
   Mockito.when(event.getChange()).thenReturn(1);

    Mockito.when(event.getType()).thenReturn(Change.INCREASE);

    Assert.assertEquals(0, temperature.getValue());

    presenter.temperatureChanged(event);


    Assert.assertEquals(1, temperature.getValue());

    Mockito.verify(tempText).refresh();
}
Birim Testleri
@Test
public void colorShoulBeRedWhenTemperatureAboveForty() {
   Mockito.when(event.getChange()).thenReturn(41);

    Mockito.when(event.getType()).thenReturn(Change.INCREASE);

    Assert.assertEquals(0, temperature.getValue());

    presenter.temperatureChanged(event);

    Assert.assertEquals(41, temperature.getValue());

    Mockito.verify(tempText).red();

    Mockito.verify(tempText).refresh();
}
Presenter Impl.
public void temperatureChanged(TemperatureChangeEvent event) {
    int value = event.getChange();

    if(event.getType() == Change.INCREASE) {
        temperature.increase(value);
    } else {
        temperature.decrease(value);
    }

    value = temperature.getValue();

    if(value < 0) {
        tempText.blue();
    } else if (value > 0 && value < 24) {
        tempText.green();
    } else if (value > 24 && value < 40) {
        tempText.yellow();
    } else if (value > 40) {
        tempText.red();
    }

    tempText.refresh();
}
IncButton View Impl.
public void addTemperatureChangeEventListener(
   TemperatureChangeListener changeListener) {
   listeners.add(changeListener);
}

public IncButton() {
   Button btn = new Button("+");
   btn.addListener(this);
   setCompositionRoot(btn);
}

@Override
public void buttonClick(ClickEvent event) {
   TemperatureChangeEvent temperatureChangeEvent = new
                 TemperatureChangeEvent(1, Change.INCREASE);

    for(TemperatureChangeListener listener:listeners) {
       listener.temperatureChanged(temperatureChangeEvent);
    }
}
TempText View Impl.
private Label label;

public TempTextImpl(Temperature temperature) {
   HorizontalLayout ho = new HorizontalLayout();

   ho.setSpacing(true);
   ho.addComponentAsFirst(new Label("Temperature :"));
   label = new Label(new MethodProperty(temperature,
"value"));
   ho.addComponent(label);

    setCompositionRoot(ho);
}

@Override
public void blue() {
   label.setStyleName("bluelabel");
}
Örnek 3

   Üçüncü örneğimizde kullanıcımız kişisel
    bağlantı bilgilerini yönettiği bir uygulama
    istemektedir. Uygulama ekranında sahip olduğu
    bağlantılar listelenecek, listelenen kayıtlardan
    herhangi biri seçildiğinde detay ekranında
    görüntülenip güncellenebilecektir.
UI Mockup


                                                                                         Contact
                                                                                         DetailPanel

ContactList
Panel




         GUI, ContactListPanel ve ContactDetailPanel kısımlarından oluşmaktadır.
         ListPanel'de mevcut contact nesneleri listelenmektedir. Listeden seçilen herhangi bir
         Contact'a ait bilgiler sağ taraftaki DetailPanel'de görüntülenir. Bilgiler değiştirildikten
         sonra Update butonuna basıldığında değişiklikler kaydedilir ve aynı zamanda
         ListPanel'e de yansıtılır
Sınıf ve Arayüzler
Sınıf ve Arayüzler
Contact List Birim Testleri
private ContactListPresenter presenter;

@Mock
private ContactListPanel listPanel;

@Mock
private ContactDetailPanel detailPanel;

@Mock
private ContactService service;

private Collection<Contact> contacts;

@Mock
private ContactUpdatedEvent event;

@Mock
private Contact contact;
Contact List Birim Testleri
@Test
public void contactsShouldBeShownWhenPageIsLoaded() {
   Mockito.verify(service).getContacts();

    Mockito.verify(listPanel).loadContacts(contacts);
}

@Test
public void contactShouldBeReloadedWhenUpdated() {
   Mockito.verify(detailPanel)
         .addContactUpdateListener(presenter);

    presenter.contactUpdated(event);

    Mockito.verify(event).getContact();

    Mockito.verify(listPanel).reloadContact(contact);
}
Contact List Presenter Impl.
public ContactListPresenter(ContactListPanel listPanel,
      ContactDetailPanel detailPanel, ContactService service)
{
   this.listPanel = listPanel;
   this.service = service;

    Collection<Contact> contacts = service.getContacts();

    listPanel.loadContacts(contacts);

    detailPanel.addContactUpdateListener(this);
}

@Override
public void contactUpdated(ContactUpdatedEvent event) {
   Contact contact = event.getContact();

    listPanel.reloadContact(contact);
}
Contact List View Impl.
public void loadContacts(Collection<Contact> contacts) {
   BeanItemContainer<Contact> dataSource = new
         BeanItemContainer<Contact>(Contact.class, contacts);

   table.setContainerDataSource(dataSource);
   table.setVisibleColumns(new Object[]
               {"name","surname","email","phone"});
   table.setColumnHeaders(new String[]{"Name","Surname","E-
Mail","Phone"});
}

public void valueChange(ValueChangeEvent event) {
   Contact contact = (Contact) table.getValue();

    ContactSelectedEvent selectedEvent = new
          ContactSelectedEvent(contact);

    for(ContactSelectionListener listener:listeners) {
       listener.contactSelected(selectedEvent);
    }
}
Contact List View Impl.
@Override
public void reloadContact(Contact contact) {

    BeanItemContainer container = (BeanItemContainer)

    table.getContainerDataSource();

    container.removeItem(contact);

    container.addBean(contact);

    table.requestRepaintAll();
}
Contact Detail Birim Testleri
@Mock
private ContactDetailPanel detailPanel;

@Mock
private ContactListPanel listPanel;

private ContactDetailPresenter presenter;

@Mock
private Contact contact;

@Mock
private ContactSelectedEvent event;

@Test
public void contactShouldBeDisplayedInDetailPanelWhenSelected() {
presenter.contactSelected(event);

Mockito.verify(detailPanel).displayContact(contact);
Mockito.verify(event).getSelectedContact();

Mockito.verify(listPanel).addContactSelectionListener(presenter);
}
Contact Detail Presenter Impl.
private ContactDetailPanel detailPanel;

public ContactDetailPresenter(ContactDetailPanel detailPanel,
      ContactListPanel listPanel) {

    this.detailPanel = detailPanel;

    listPanel.addContactSelectionListener(this);
}

@Override
public void contactSelected(ContactSelectedEvent event) {

    Contact contact = event.getSelectedContact();

    detailPanel.displayContact(contact);
}
Contact Detail View Impl.
@Override
public void displayContact(Contact contact) {

    BeanItem item = new BeanItem(contact);
    form.setItemDataSource(item);
    form.setVisibleItemProperties(new Object[]
          {"name","surname","email","phone","address"});
}

@Override
public void buttonClick(ClickEvent event) {
   Contact contact = (Contact) ((BeanItem)
   form.getItemDataSource()).getBean();
   ContactUpdatedEvent updateEvent = new
                  ContactUpdatedEvent(contact);

    for(ContactUpdateListener listener:listeners) {
       listener.contactUpdated(updateEvent);
    }
}
ContactListPanel ve ContactDetailPanel ile
 etkileşime girecek bir bileşen daha eklenirse...

Örneğin, update butonunun bulunduğu kısım bir
ToolBarPanel bileşenine dönüştürülür ve update
  butonunun sadece Contact seçildiği zaman
       görünür olması istenirse nasıl bir
           problem ortaya çıkabilir?
Mediator Öncesi

                            Bileşen

  Bileşen




Bileşen                         Bileşen



                  Bileşen
Örnek 4

   Kullanıcımız bağlantılarını yönettiği
    uygulamasına benzer şekilde adres bilgilerini
    yönettiği bir uygulama istemektedir.
   Ancak uygulamanın bileşenlerinin mümkün
    olduğunca birbirlerinden bağımsız ve farklı
    bölümlerde yeniden kullanılabilir olmasına
    dikkat edilmesi istenmektedir.
UI Mockup



                                     Address
                                     Detail
                                     Panel
Address
List
Panel




               AddressToolBarPanel
Sınıf ve Arayüzler
Sınıf ve Arayüzler
Sınıf ve Arayüzler
Sınıf ve Arayüzler
Mediator Impl.
private Collection<MediatorEventListener> listeners = new
         ArrayList<MediatorEventListener>();

public void addListener(MediatorEventListener listener) {
   listeners.add(listener);
}

public void removeListener(MediatorEventListener listener) {
   listeners.remove(listener);
}

public void fire(MediatorEvent event) {

    for(MediatorEventListener listener:listeners) {

        listener.handle(event);

    }

}
Address List Presenter Impl.
private AddressListPanel listPanel;

public AddressListPresenter(AddressListPanel listPanel,
      AddressService addressService) {

    this.listPanel = listPanel;
    listPanel.loadAddresses(addressService.getAddresses());
}

@Override
public void handle(MediatorEvent event) {

   if(event instanceof AddressUpdatedEvent) {
      AddressUpdatedEvent updateEvent =
(AddressUpdatedEvent)event;
      listPanel.reloadAddress(updateEvent.getAddress());
   }

}
Address Detail Presenter Impl.
private AddressDetailPanel detailPanel;

public AddressDetailPresenter(AddressDetailPanel detailPanel)
{
   this.detailPanel = detailPanel;
}

@Override
public void handle(MediatorEvent event) {

    if(event instanceof AddressSelectedEvent) {

         AddressSelectedEvent selectedEvent =
                        (AddressSelectedEvent)event;

         detailPanel.displayAddress(
               selectedEvent.getSelectedAddress());

    }
}
Address ToolBar Presenter Impl.
private AddressToolBarPanel addressToolBarPanel;

public AddressToolBarPresenter(AddressToolBarPanel
addressToolBarPanel) {
   this.addressToolBarPanel = addressToolBarPanel;
   addressToolBarPanel.swithToSelectionMode();
}

@Override
public void handle(MediatorEvent event) {
   if(event instanceof AddressSelectedEvent) {
      addressToolBarPanel.swithToUpdateMode();

       addressToolBarPanel.setAddress(
          ((AddressSelectedEvent)event).getSelectedAddress());
    } else if(event instanceof AddressUpdatedEvent) {

        addressToolBarPanel.swithToSelectionMode();
    }
}
Address List View Impl.
public AddressListPanelImpl(Mediator mediator) {
   this.mediator = mediator;

...
}

@Override
public void loadAddresses(Collection<Address> addresses) {
...
}

@Override
public void valueChange(ValueChangeEvent event) {
   Address address = (Address) table.getValue();

    AddressSelectedEvent selectedEvent = new
                      AddressSelectedEvent(address);
    mediator.fire(selectedEvent);
}
Address ToolBar View Impl.
public AddressToolBarPanelImpl(Mediator mediator) {
   this.mediator = mediator;
...
}

@Override
public void setAddress(Address address) {
   this.address = address;
}

@Override
public void buttonClick(ClickEvent event) {

    if(event.getButton() == updateButton) {
       mediator.fire(new AddressUpdatedEvent(address));
    }

}
Mediator Sonrası

                            Bileşen
 Bileşen




                 Mediator




Bileşen                         Bileşen



                  Bileşen
Soru & Cevap
İletişim

   Harezmi Bilişim Çözümleri Ltd.
   Kurumsal Java Eğitimleri
   http://www.harezmi.com.tr
   http://www.java-egitimleri.com
   info@java-egitimleri.com

Mais conteúdo relacionado

Destaque

初回(キャリアって何?)4月24日
初回(キャリアって何?)4月24日初回(キャリアって何?)4月24日
初回(キャリアって何?)4月24日Cozy Azuma
 
Spectrum Community Investment Casebook May 2015lo-respages - LB
Spectrum Community Investment Casebook May 2015lo-respages - LBSpectrum Community Investment Casebook May 2015lo-respages - LB
Spectrum Community Investment Casebook May 2015lo-respages - LBSuzie Mundell
 
Prilojenie
PrilojeniePrilojenie
Prilojenieval1616
 
Hari sokan sekolahmu
Hari sokan sekolahmuHari sokan sekolahmu
Hari sokan sekolahmuSyed Adib
 
Gartner EEE - Altyapı Yönetimi - Vakıfbank Sunumu
Gartner EEE - Altyapı Yönetimi - Vakıfbank SunumuGartner EEE - Altyapı Yönetimi - Vakıfbank Sunumu
Gartner EEE - Altyapı Yönetimi - Vakıfbank Sunumuhalilaksu
 
Teaching & Learning With Internet (9B)
Teaching & Learning With Internet (9B)Teaching & Learning With Internet (9B)
Teaching & Learning With Internet (9B)cikguyatie_uum
 
Bab 1-kedudukan
Bab 1-kedudukanBab 1-kedudukan
Bab 1-kedudukanarilmeran
 
SCVAF Marketing Re-Design Project
SCVAF Marketing Re-Design ProjectSCVAF Marketing Re-Design Project
SCVAF Marketing Re-Design Projectrrenefranciss
 
Presentatie Orion Engineering 2012
Presentatie Orion Engineering 2012Presentatie Orion Engineering 2012
Presentatie Orion Engineering 2012maeike
 
Personal Persona Presentation
Personal Persona PresentationPersonal Persona Presentation
Personal Persona PresentationJaclyn Zajac
 
Carlaword
CarlawordCarlaword
Carlawordcasago6
 
Julie kelly resume[1]
Julie kelly resume[1]Julie kelly resume[1]
Julie kelly resume[1]Julie Kelly
 
Beautiful pictures 4 zene - bob marley
Beautiful pictures   4 zene - bob marleyBeautiful pictures   4 zene - bob marley
Beautiful pictures 4 zene - bob marleyfilipj2000
 

Destaque (20)

Нагорнюк
НагорнюкНагорнюк
Нагорнюк
 
初回(キャリアって何?)4月24日
初回(キャリアって何?)4月24日初回(キャリアって何?)4月24日
初回(キャリアって何?)4月24日
 
Spectrum Community Investment Casebook May 2015lo-respages - LB
Spectrum Community Investment Casebook May 2015lo-respages - LBSpectrum Community Investment Casebook May 2015lo-respages - LB
Spectrum Community Investment Casebook May 2015lo-respages - LB
 
Prilojenie
PrilojeniePrilojenie
Prilojenie
 
How to: Set up direct deposit
How to: Set up direct depositHow to: Set up direct deposit
How to: Set up direct deposit
 
La Rochelle workshop 2016
La Rochelle workshop 2016La Rochelle workshop 2016
La Rochelle workshop 2016
 
Hari sokan sekolahmu
Hari sokan sekolahmuHari sokan sekolahmu
Hari sokan sekolahmu
 
Gartner EEE - Altyapı Yönetimi - Vakıfbank Sunumu
Gartner EEE - Altyapı Yönetimi - Vakıfbank SunumuGartner EEE - Altyapı Yönetimi - Vakıfbank Sunumu
Gartner EEE - Altyapı Yönetimi - Vakıfbank Sunumu
 
Teaching & Learning With Internet (9B)
Teaching & Learning With Internet (9B)Teaching & Learning With Internet (9B)
Teaching & Learning With Internet (9B)
 
Portfolio
PortfolioPortfolio
Portfolio
 
Bab 1-kedudukan
Bab 1-kedudukanBab 1-kedudukan
Bab 1-kedudukan
 
Caracteristicas
CaracteristicasCaracteristicas
Caracteristicas
 
SCVAF Marketing Re-Design Project
SCVAF Marketing Re-Design ProjectSCVAF Marketing Re-Design Project
SCVAF Marketing Re-Design Project
 
Presentatie Orion Engineering 2012
Presentatie Orion Engineering 2012Presentatie Orion Engineering 2012
Presentatie Orion Engineering 2012
 
Personal Persona Presentation
Personal Persona PresentationPersonal Persona Presentation
Personal Persona Presentation
 
North kolkata
North kolkataNorth kolkata
North kolkata
 
Carlaword
CarlawordCarlaword
Carlaword
 
Julie kelly resume[1]
Julie kelly resume[1]Julie kelly resume[1]
Julie kelly resume[1]
 
Beautiful pictures 4 zene - bob marley
Beautiful pictures   4 zene - bob marleyBeautiful pictures   4 zene - bob marley
Beautiful pictures 4 zene - bob marley
 
Motors tèrmics
Motors tèrmicsMotors tèrmics
Motors tèrmics
 

Semelhante a 2012 04 mvc_mvp_ve_mediator_ile_tdd_tecrubeleri

Erdem Avni SELÇUK 22 Nisan 2015 Çözümpark & Gediz Üniversitesi İzmir MVC Work...
Erdem Avni SELÇUK 22 Nisan 2015 Çözümpark & Gediz Üniversitesi İzmir MVC Work...Erdem Avni SELÇUK 22 Nisan 2015 Çözümpark & Gediz Üniversitesi İzmir MVC Work...
Erdem Avni SELÇUK 22 Nisan 2015 Çözümpark & Gediz Üniversitesi İzmir MVC Work...Erdem Avni Selçuk
 
Web İçin Teknoloji Geliştirmek
Web İçin Teknoloji GeliştirmekWeb İçin Teknoloji Geliştirmek
Web İçin Teknoloji GeliştirmekVolkan Özçelik
 
Özgür Web Teknolojileri Günleri 2010 - İbrahim Hızlıoğlu // CodeIgniter Sunumu
Özgür Web Teknolojileri Günleri 2010 - İbrahim Hızlıoğlu // CodeIgniter SunumuÖzgür Web Teknolojileri Günleri 2010 - İbrahim Hızlıoğlu // CodeIgniter Sunumu
Özgür Web Teknolojileri Günleri 2010 - İbrahim Hızlıoğlu // CodeIgniter Sunumuibrahimhizlioglu
 
Design Patterns
Design PatternsDesign Patterns
Design Patternskodarge
 
1.Hafta.pptx
1.Hafta.pptx1.Hafta.pptx
1.Hafta.pptxYcelENOL
 
MVVM (Model View ViewModel)
MVVM (Model View ViewModel)MVVM (Model View ViewModel)
MVVM (Model View ViewModel)nedirtv
 
Analist Eğitimi - Tüm Bölümler - [535 Slides]
Analist Eğitimi - Tüm Bölümler -  [535 Slides]Analist Eğitimi - Tüm Bölümler -  [535 Slides]
Analist Eğitimi - Tüm Bölümler - [535 Slides]Erol Bozkurt
 
Implementation.pptx
Implementation.pptxImplementation.pptx
Implementation.pptxglkabakc
 
20160414 voxxed days_ist_dynamic_proxy_based_view_model_tr
20160414 voxxed days_ist_dynamic_proxy_based_view_model_tr20160414 voxxed days_ist_dynamic_proxy_based_view_model_tr
20160414 voxxed days_ist_dynamic_proxy_based_view_model_trHarezmi IT Solutions
 
ASP.NET MVC 2 Mimarisi, ASP.NET Uygulama Yönetimi ve Güvenlik Desteği
ASP.NET MVC 2 Mimarisi, ASP.NET Uygulama Yönetimi ve Güvenlik DesteğiASP.NET MVC 2 Mimarisi, ASP.NET Uygulama Yönetimi ve Güvenlik Desteği
ASP.NET MVC 2 Mimarisi, ASP.NET Uygulama Yönetimi ve Güvenlik DesteğiAli İhsan Çalışkan
 
Visual studio 2010 ve tfs 2010 yeni takim gelistirme ozellikleri
Visual studio 2010 ve tfs 2010 yeni takim gelistirme ozellikleriVisual studio 2010 ve tfs 2010 yeni takim gelistirme ozellikleri
Visual studio 2010 ve tfs 2010 yeni takim gelistirme ozellikleriMurat Başeren
 
Angular Framework (Tanıtım Sunumu) - 2024
Angular Framework (Tanıtım Sunumu) - 2024Angular Framework (Tanıtım Sunumu) - 2024
Angular Framework (Tanıtım Sunumu) - 2024eburhan
 
React.js Web Programlama
React.js Web ProgramlamaReact.js Web Programlama
React.js Web ProgramlamaCihan Özhan
 
ASP.Net MVC ile Web Uygulamaları -17(MVCContrib)
ASP.Net MVC ile Web Uygulamaları -17(MVCContrib)ASP.Net MVC ile Web Uygulamaları -17(MVCContrib)
ASP.Net MVC ile Web Uygulamaları -17(MVCContrib)İbrahim ATAY
 
Web KullanılabilirliliğIi
Web KullanılabilirliliğIiWeb KullanılabilirliliğIi
Web KullanılabilirliliğIiAytac Mestci
 
Internet programcılığı 3
Internet programcılığı 3Internet programcılığı 3
Internet programcılığı 3Erol Dizdar
 
Ahmet Kaymaz Ceturk Etkinlik 7 Subat Yazilim Surecleri
Ahmet Kaymaz Ceturk Etkinlik 7 Subat Yazilim SurecleriAhmet Kaymaz Ceturk Etkinlik 7 Subat Yazilim Surecleri
Ahmet Kaymaz Ceturk Etkinlik 7 Subat Yazilim SurecleriAhmet Kaymaz
 
005 Alternatif Yazilim Surecleri [99 Slides]
005 Alternatif Yazilim Surecleri [99 Slides]005 Alternatif Yazilim Surecleri [99 Slides]
005 Alternatif Yazilim Surecleri [99 Slides]Erol Bozkurt
 
Netsis Bilgi Günleri Teknoloji Sunumu
Netsis Bilgi Günleri Teknoloji SunumuNetsis Bilgi Günleri Teknoloji Sunumu
Netsis Bilgi Günleri Teknoloji SunumuNetsis
 

Semelhante a 2012 04 mvc_mvp_ve_mediator_ile_tdd_tecrubeleri (20)

Erdem Avni SELÇUK 22 Nisan 2015 Çözümpark & Gediz Üniversitesi İzmir MVC Work...
Erdem Avni SELÇUK 22 Nisan 2015 Çözümpark & Gediz Üniversitesi İzmir MVC Work...Erdem Avni SELÇUK 22 Nisan 2015 Çözümpark & Gediz Üniversitesi İzmir MVC Work...
Erdem Avni SELÇUK 22 Nisan 2015 Çözümpark & Gediz Üniversitesi İzmir MVC Work...
 
Web İçin Teknoloji Geliştirmek
Web İçin Teknoloji GeliştirmekWeb İçin Teknoloji Geliştirmek
Web İçin Teknoloji Geliştirmek
 
Özgür Web Teknolojileri Günleri 2010 - İbrahim Hızlıoğlu // CodeIgniter Sunumu
Özgür Web Teknolojileri Günleri 2010 - İbrahim Hızlıoğlu // CodeIgniter SunumuÖzgür Web Teknolojileri Günleri 2010 - İbrahim Hızlıoğlu // CodeIgniter Sunumu
Özgür Web Teknolojileri Günleri 2010 - İbrahim Hızlıoğlu // CodeIgniter Sunumu
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
1.Hafta.pptx
1.Hafta.pptx1.Hafta.pptx
1.Hafta.pptx
 
MVVM (Model View ViewModel)
MVVM (Model View ViewModel)MVVM (Model View ViewModel)
MVVM (Model View ViewModel)
 
Analist Eğitimi - Tüm Bölümler - [535 Slides]
Analist Eğitimi - Tüm Bölümler -  [535 Slides]Analist Eğitimi - Tüm Bölümler -  [535 Slides]
Analist Eğitimi - Tüm Bölümler - [535 Slides]
 
Implementation.pptx
Implementation.pptxImplementation.pptx
Implementation.pptx
 
20160414 voxxed days_ist_dynamic_proxy_based_view_model_tr
20160414 voxxed days_ist_dynamic_proxy_based_view_model_tr20160414 voxxed days_ist_dynamic_proxy_based_view_model_tr
20160414 voxxed days_ist_dynamic_proxy_based_view_model_tr
 
ASP.NET MVC 2 Mimarisi, ASP.NET Uygulama Yönetimi ve Güvenlik Desteği
ASP.NET MVC 2 Mimarisi, ASP.NET Uygulama Yönetimi ve Güvenlik DesteğiASP.NET MVC 2 Mimarisi, ASP.NET Uygulama Yönetimi ve Güvenlik Desteği
ASP.NET MVC 2 Mimarisi, ASP.NET Uygulama Yönetimi ve Güvenlik Desteği
 
Visual studio 2010 ve tfs 2010 yeni takim gelistirme ozellikleri
Visual studio 2010 ve tfs 2010 yeni takim gelistirme ozellikleriVisual studio 2010 ve tfs 2010 yeni takim gelistirme ozellikleri
Visual studio 2010 ve tfs 2010 yeni takim gelistirme ozellikleri
 
Angular Framework (Tanıtım Sunumu) - 2024
Angular Framework (Tanıtım Sunumu) - 2024Angular Framework (Tanıtım Sunumu) - 2024
Angular Framework (Tanıtım Sunumu) - 2024
 
React.js Web Programlama
React.js Web ProgramlamaReact.js Web Programlama
React.js Web Programlama
 
ASP.Net MVC ile Web Uygulamaları -17(MVCContrib)
ASP.Net MVC ile Web Uygulamaları -17(MVCContrib)ASP.Net MVC ile Web Uygulamaları -17(MVCContrib)
ASP.Net MVC ile Web Uygulamaları -17(MVCContrib)
 
Web KullanılabilirliliğIi
Web KullanılabilirliliğIiWeb KullanılabilirliliğIi
Web KullanılabilirliliğIi
 
Internet programcılığı 3
Internet programcılığı 3Internet programcılığı 3
Internet programcılığı 3
 
Ahmet Kaymaz Ceturk Etkinlik 7 Subat Yazilim Surecleri
Ahmet Kaymaz Ceturk Etkinlik 7 Subat Yazilim SurecleriAhmet Kaymaz Ceturk Etkinlik 7 Subat Yazilim Surecleri
Ahmet Kaymaz Ceturk Etkinlik 7 Subat Yazilim Surecleri
 
Java Server Faces
Java Server FacesJava Server Faces
Java Server Faces
 
005 Alternatif Yazilim Surecleri [99 Slides]
005 Alternatif Yazilim Surecleri [99 Slides]005 Alternatif Yazilim Surecleri [99 Slides]
005 Alternatif Yazilim Surecleri [99 Slides]
 
Netsis Bilgi Günleri Teknoloji Sunumu
Netsis Bilgi Günleri Teknoloji SunumuNetsis Bilgi Günleri Teknoloji Sunumu
Netsis Bilgi Günleri Teknoloji Sunumu
 

Mais de Kenan Sevindik

20160523 hibernate persistence_framework_and_orm
20160523 hibernate persistence_framework_and_orm20160523 hibernate persistence_framework_and_orm
20160523 hibernate persistence_framework_and_ormKenan Sevindik
 
Developing Reusable Software Components Using MVP, Observer and Mediator Patt...
Developing Reusable Software Components Using MVP, Observer and Mediator Patt...Developing Reusable Software Components Using MVP, Observer and Mediator Patt...
Developing Reusable Software Components Using MVP, Observer and Mediator Patt...Kenan Sevindik
 
Spring application framework
Spring application frameworkSpring application framework
Spring application frameworkKenan Sevindik
 
Cactus in container_unit_test_framework
Cactus in container_unit_test_frameworkCactus in container_unit_test_framework
Cactus in container_unit_test_frameworkKenan Sevindik
 
20150226 ajug kurumsal_bilgi_sistemleri_ve_guvenlik
20150226 ajug kurumsal_bilgi_sistemleri_ve_guvenlik20150226 ajug kurumsal_bilgi_sistemleri_ve_guvenlik
20150226 ajug kurumsal_bilgi_sistemleri_ve_guvenlikKenan Sevindik
 
Java İle Tasarım Prensipleri ve Tasarım Örüntüleri
Java İle Tasarım Prensipleri ve Tasarım ÖrüntüleriJava İle Tasarım Prensipleri ve Tasarım Örüntüleri
Java İle Tasarım Prensipleri ve Tasarım ÖrüntüleriKenan Sevindik
 
Contemporary Software Engineering Practices Together With Enterprise
Contemporary Software Engineering Practices Together With EnterpriseContemporary Software Engineering Practices Together With Enterprise
Contemporary Software Engineering Practices Together With EnterpriseKenan Sevindik
 

Mais de Kenan Sevindik (7)

20160523 hibernate persistence_framework_and_orm
20160523 hibernate persistence_framework_and_orm20160523 hibernate persistence_framework_and_orm
20160523 hibernate persistence_framework_and_orm
 
Developing Reusable Software Components Using MVP, Observer and Mediator Patt...
Developing Reusable Software Components Using MVP, Observer and Mediator Patt...Developing Reusable Software Components Using MVP, Observer and Mediator Patt...
Developing Reusable Software Components Using MVP, Observer and Mediator Patt...
 
Spring application framework
Spring application frameworkSpring application framework
Spring application framework
 
Cactus in container_unit_test_framework
Cactus in container_unit_test_frameworkCactus in container_unit_test_framework
Cactus in container_unit_test_framework
 
20150226 ajug kurumsal_bilgi_sistemleri_ve_guvenlik
20150226 ajug kurumsal_bilgi_sistemleri_ve_guvenlik20150226 ajug kurumsal_bilgi_sistemleri_ve_guvenlik
20150226 ajug kurumsal_bilgi_sistemleri_ve_guvenlik
 
Java İle Tasarım Prensipleri ve Tasarım Örüntüleri
Java İle Tasarım Prensipleri ve Tasarım ÖrüntüleriJava İle Tasarım Prensipleri ve Tasarım Örüntüleri
Java İle Tasarım Prensipleri ve Tasarım Örüntüleri
 
Contemporary Software Engineering Practices Together With Enterprise
Contemporary Software Engineering Practices Together With EnterpriseContemporary Software Engineering Practices Together With Enterprise
Contemporary Software Engineering Practices Together With Enterprise
 

2012 04 mvc_mvp_ve_mediator_ile_tdd_tecrubeleri

  • 1. MVC, MVP ve Mediator ile TDD Tecrübeleri Kenan SEVİNDİK
  • 2. Mimarisel Bir Örüntü: MVC Controller Kullanıcı girdileri Veri değişiklikleri ve UI olayları Bildirimler Model View Veri erişimi
  • 4. Trygve Reenskaug'un Hedefi Kullanıcının zihnindeki “mental model” ile bilgisayar sistemindeki “sayısal model” arasındaki boşluğu doldurmaktır!
  • 5. Trygve Reenskaug'un Hedefi 45 40 40 35 35 30 30 25 25 1 20 2 Row 1 20 3 15 15 10 10 5 0 5 1 1.5 2 2.5 3 0 1 2 3 Model
  • 6. Günümüzdeki Kullanım Amacı: “Seperation of Concern” Reenskaug'un makalelerinde asıl amaç değildir, bir sonuçtur!
  • 7. Günümüzdeki MVC Yorumlaması Controller Model View
  • 9. MVC ve Veri Yönetimi Elimdeki veriyi Verinin oluşturulması, nasıl yönetmeliyim? Güncellenmesi veya Sorusuna cevap bulmaya Silinmesi gibi konularla Controller çalışılır Ilgilenen kısımdır Kullanıcı girdileri Veri değişiklikleri ve UI olayları Bildirimler Model View Veri erişimi
  • 10. Elimdeki Veriyi Nasıl Yönetmeliyim?  Elimdeki veri neden oluşur? Nedir?  Encapsule edilmiş veri alanları, property'ler  Uygulama içerisinden veri nasıl seçilir?  Metinsel seçimler  Satır ve sütun seçimleri  Bir grup elemanın veya bir bloğun seçilmesi  Veri nasıl güncellenmeli?  CRUD işlemleri, taşıma, kopyalama, silme, yapıştırma...
  • 11. MVC ve Kullanıcı Arayüzü Etkileşimi Kullanıcı ile veri arasındaki etkileşime odaklanan Kullanıcı veri ile nasıl kısımdır etkileşime girer? sorusuna cevap arar Controller Kullanıcı girdileri Veri değişiklikleri ve UI olayları Bildirimler Model View Veri erişimi
  • 12. Kullanıcı Veri İle Nasıl Etkileşime Girmeli?  Veri ekranda nasıl gösterilmeli?  GUI oluşturma ve gösterme işlemi  Kullanıcı girdileri ve UI olaylarından veri güncelleme işlemlerine nasıl geçiş olmalı?  Kullanıcı işlemleri, fare ve klayve girdileri
  • 13. Model View Presenter UI event'leri uygulamaya özel event'lere dönüştürülür Presenter UI üzerindeki değişiklikler Presenter tarafından yansıtılır Model üzerindeki Presenter Değişiklikler Model üzerinde Event'ler Değişiklik Ile Presenter'a Yapabilir iletilir Model verisine Model erişebilir
  • 16. Supervising Controller Presenter Model View
  • 20. Önce Presenter Çünkü... kullanıcı senaryoları ve gereksinimler bire bir Presenter içindeki fonksiyonlara karşılık gelmektedir
  • 21. Çünkü... Geliştiriciler Presenter kısımlarını kodlamaya odaklanabilirler Kendi içlerinde de fonksiyonel gereksinimlere göre gruplara ayrılarak paralel çalışabilirler Presenter Kodları Fonksiyonel View Gereksinimler Arayüzleri View Implementasyonları UI geliştiriciler ise tamamen GUI geliştirmeye odaklanabilirler. View içerisinde sadece UI widget'ların oluşturulması, sayfalara yerleştirilmesi söz konusudur.
  • 22. Çünkü... Geliştirme sürecinde TDD yaklaşımına uygun çalışmaya olanak sağlamaktadır View, Model ve ihtiyaç duyulan servis bileşenleri mock'lanarak Presenter'a verilir
  • 23. Presenter ve TDD İkincil Nesne İkincil Nesne Asıl Nesne (Birim teste tabi tutulan nesnedir) İkincil Nesne
  • 24. İkincil Nesneler ve Mock İşlemi  Gerçek implementasyonları hazır olmayabilir  Hazır olsa bile test ortamında yaratılması çalıştırılması zor olabilir  Ya da çok yavaş çalışabilir, network veya dosya sistemi ile ilişkisi olabilir  GUI bağlantısı söz konusu olabilir  Bu ve benzeri nedenlerle ikincil nesnelerin asılları yerine sahteleri kullanılır  Bunlara “mock” nesneler adı verilir
  • 25. Durum / Etkileşim Tabanlı Test Yaklaşımları
  • 26. Etkileşim Tabanlı Durum Tabanlı Yaklaşım Yaklaşım  Mock nesneler  Birincil ve ikincil üzerinde, test edilen nesnelerin ilgili davranışla ilgili davranış sonrasında metotların uygun doğru state sayıda ve şekilde asıl değerlerini yansıtıp nesne tarafından yansıtmadıklarını çağırıldığını kontrol kontrol eden birim eden birim test test yaklaşımıdır yaklaşımıdır  İkincil nesneler olarak asılları kullanılır
  • 27. Örnek 1  Örneğin kullanıcımızın, text alana girilen bir metin içindeki Türkçe karakterleri anında İngilizce'ye dönüştüren bir program talep ettiğini farz edelim.
  • 28. UI Mockup Kullanıcı ile diyalogların sonucunda kullanıcı arayüzü taslak olarak ortaya çıkar. Kullanıcının ihtiyaç duyduğu, olmasını istediği fonksiyonaliteler, bu fonksiyonları UI üzerinden nasıl tetikleyeceği gibi konular kullanım durumu senaryolarının oluşturulması esnasında tespit edilir.
  • 29. Sınıf ve Arayüzler 2 Metin içindeki karakterlerin dönüşümü Presenter tarafından yönetilir 3 TextArea.setContent(...) metodu ile sağ taraftaki 1 textarea'nın içeriği güncellenir ContentChangedEvent ile sol taraftaki textarea daki metin değişikliği Presenter'a bildirilir
  • 30. Birim Testleri @Mock private TextArea left; @Mock private TextArea right; @Mock private ContentChangedEvent event; Action kısmı Event kısmı @Test public void contentShouldBeConvertedWhenTextChanged() { Mockito.when(event.getText()).thenReturn("çÇöÖşŞıİğĞüÜ"); TR2ENConverterPresenter presenter = new TR2ENConverterPresenter(left, right); presenter.contentChanged(event); Mockito.verify(right).setContent("cCoOsSiIgGuU"); }
  • 31. Presenter Implementasyonu private TextArea left, right; public TR2ENConverterPresenter(TextArea left, TextArea right) { this.left = left; this.right = right; left.addContentChangeListener(this); } @Override public void contentChanged(ContentChangedEvent event) { String content = event.getText(); content = content.replace('ç', 'c').replace('Ç', 'C').replace('ı', 'i') .replace('İ', 'I').replace('ö', 'o').replace('Ö', 'O') .replace('ş', 's').replace('Ş', 'S').replace('ğ', 'g') .replace('Ğ', 'G').replace('ü', 'u').replace('Ü', 'U'); right.setContent(content); }
  • 32. View Implementasyonu public void addContentChangeListener(ContentChangeListener listener) { Presenter event listener olarak kendini listeners.add(listener); register etmek için bu metodu kullanır } public String getContent() { UI state'e erişime return (String) textArea.getValue(); ve değiştirmeye imkan } sağlayan metotlar public void setContent(String content) { textArea.setValue(content); UI event'in uygulama } event'ine dönüşümü public void textChange(TextChangeEvent event) { ContentChangedEvent contentChangedEvent = new ContentChangedEvent(event.getText()); for(ContentChangeListener listener:listeners) { listener.contentChanged(contentChangedEvent); } }
  • 33. Örnek 2  Bu örnekte de kullanıcımız sıcaklık değerini birer birer artırıp düşürdüğü bir gösterge istiyor. Sıcaklığa göre göstergedeki değerin arka planı dinamik olarak renk değiştirmeli.
  • 34. UI Mockup Kullanıcı + ve – butonlarına tıklayarak sıcaklık değerini birer birer artırıp düşürebilecek. Sıcaklık değeri 0'ın altında iken arka plan mavi, sıfırın üstünde yeşil, 20 derece'nin üstünde sarı, 40 derecenin üstünde de kırmızı olmalı.
  • 36. Birim Testleri @Mock private TempButton incButton; @Mock private TempButton decButton; @Mock private TempText tempText; @Mock private TemperatureChangeEvent event; private Temperature temperature; private TemperatureTrackerPresenter presenter;
  • 37. Birim Testleri @Test public void textShouldBeUpdatedWhenTemperatureChanges() { Mockito.when(event.getChange()).thenReturn(1); Mockito.when(event.getType()).thenReturn(Change.INCREASE); Assert.assertEquals(0, temperature.getValue()); presenter.temperatureChanged(event); Assert.assertEquals(1, temperature.getValue()); Mockito.verify(tempText).refresh(); }
  • 38. Birim Testleri @Test public void colorShoulBeRedWhenTemperatureAboveForty() { Mockito.when(event.getChange()).thenReturn(41); Mockito.when(event.getType()).thenReturn(Change.INCREASE); Assert.assertEquals(0, temperature.getValue()); presenter.temperatureChanged(event); Assert.assertEquals(41, temperature.getValue()); Mockito.verify(tempText).red(); Mockito.verify(tempText).refresh(); }
  • 39. Presenter Impl. public void temperatureChanged(TemperatureChangeEvent event) { int value = event.getChange(); if(event.getType() == Change.INCREASE) { temperature.increase(value); } else { temperature.decrease(value); } value = temperature.getValue(); if(value < 0) { tempText.blue(); } else if (value > 0 && value < 24) { tempText.green(); } else if (value > 24 && value < 40) { tempText.yellow(); } else if (value > 40) { tempText.red(); } tempText.refresh(); }
  • 40. IncButton View Impl. public void addTemperatureChangeEventListener( TemperatureChangeListener changeListener) { listeners.add(changeListener); } public IncButton() { Button btn = new Button("+"); btn.addListener(this); setCompositionRoot(btn); } @Override public void buttonClick(ClickEvent event) { TemperatureChangeEvent temperatureChangeEvent = new TemperatureChangeEvent(1, Change.INCREASE); for(TemperatureChangeListener listener:listeners) { listener.temperatureChanged(temperatureChangeEvent); } }
  • 41. TempText View Impl. private Label label; public TempTextImpl(Temperature temperature) { HorizontalLayout ho = new HorizontalLayout(); ho.setSpacing(true); ho.addComponentAsFirst(new Label("Temperature :")); label = new Label(new MethodProperty(temperature, "value")); ho.addComponent(label); setCompositionRoot(ho); } @Override public void blue() { label.setStyleName("bluelabel"); }
  • 42. Örnek 3  Üçüncü örneğimizde kullanıcımız kişisel bağlantı bilgilerini yönettiği bir uygulama istemektedir. Uygulama ekranında sahip olduğu bağlantılar listelenecek, listelenen kayıtlardan herhangi biri seçildiğinde detay ekranında görüntülenip güncellenebilecektir.
  • 43. UI Mockup Contact DetailPanel ContactList Panel GUI, ContactListPanel ve ContactDetailPanel kısımlarından oluşmaktadır. ListPanel'de mevcut contact nesneleri listelenmektedir. Listeden seçilen herhangi bir Contact'a ait bilgiler sağ taraftaki DetailPanel'de görüntülenir. Bilgiler değiştirildikten sonra Update butonuna basıldığında değişiklikler kaydedilir ve aynı zamanda ListPanel'e de yansıtılır
  • 46. Contact List Birim Testleri private ContactListPresenter presenter; @Mock private ContactListPanel listPanel; @Mock private ContactDetailPanel detailPanel; @Mock private ContactService service; private Collection<Contact> contacts; @Mock private ContactUpdatedEvent event; @Mock private Contact contact;
  • 47. Contact List Birim Testleri @Test public void contactsShouldBeShownWhenPageIsLoaded() { Mockito.verify(service).getContacts(); Mockito.verify(listPanel).loadContacts(contacts); } @Test public void contactShouldBeReloadedWhenUpdated() { Mockito.verify(detailPanel) .addContactUpdateListener(presenter); presenter.contactUpdated(event); Mockito.verify(event).getContact(); Mockito.verify(listPanel).reloadContact(contact); }
  • 48. Contact List Presenter Impl. public ContactListPresenter(ContactListPanel listPanel, ContactDetailPanel detailPanel, ContactService service) { this.listPanel = listPanel; this.service = service; Collection<Contact> contacts = service.getContacts(); listPanel.loadContacts(contacts); detailPanel.addContactUpdateListener(this); } @Override public void contactUpdated(ContactUpdatedEvent event) { Contact contact = event.getContact(); listPanel.reloadContact(contact); }
  • 49. Contact List View Impl. public void loadContacts(Collection<Contact> contacts) { BeanItemContainer<Contact> dataSource = new BeanItemContainer<Contact>(Contact.class, contacts); table.setContainerDataSource(dataSource); table.setVisibleColumns(new Object[] {"name","surname","email","phone"}); table.setColumnHeaders(new String[]{"Name","Surname","E- Mail","Phone"}); } public void valueChange(ValueChangeEvent event) { Contact contact = (Contact) table.getValue(); ContactSelectedEvent selectedEvent = new ContactSelectedEvent(contact); for(ContactSelectionListener listener:listeners) { listener.contactSelected(selectedEvent); } }
  • 50. Contact List View Impl. @Override public void reloadContact(Contact contact) { BeanItemContainer container = (BeanItemContainer) table.getContainerDataSource(); container.removeItem(contact); container.addBean(contact); table.requestRepaintAll(); }
  • 51. Contact Detail Birim Testleri @Mock private ContactDetailPanel detailPanel; @Mock private ContactListPanel listPanel; private ContactDetailPresenter presenter; @Mock private Contact contact; @Mock private ContactSelectedEvent event; @Test public void contactShouldBeDisplayedInDetailPanelWhenSelected() { presenter.contactSelected(event); Mockito.verify(detailPanel).displayContact(contact); Mockito.verify(event).getSelectedContact(); Mockito.verify(listPanel).addContactSelectionListener(presenter); }
  • 52. Contact Detail Presenter Impl. private ContactDetailPanel detailPanel; public ContactDetailPresenter(ContactDetailPanel detailPanel, ContactListPanel listPanel) { this.detailPanel = detailPanel; listPanel.addContactSelectionListener(this); } @Override public void contactSelected(ContactSelectedEvent event) { Contact contact = event.getSelectedContact(); detailPanel.displayContact(contact); }
  • 53. Contact Detail View Impl. @Override public void displayContact(Contact contact) { BeanItem item = new BeanItem(contact); form.setItemDataSource(item); form.setVisibleItemProperties(new Object[] {"name","surname","email","phone","address"}); } @Override public void buttonClick(ClickEvent event) { Contact contact = (Contact) ((BeanItem) form.getItemDataSource()).getBean(); ContactUpdatedEvent updateEvent = new ContactUpdatedEvent(contact); for(ContactUpdateListener listener:listeners) { listener.contactUpdated(updateEvent); } }
  • 54. ContactListPanel ve ContactDetailPanel ile etkileşime girecek bir bileşen daha eklenirse... Örneğin, update butonunun bulunduğu kısım bir ToolBarPanel bileşenine dönüştürülür ve update butonunun sadece Contact seçildiği zaman görünür olması istenirse nasıl bir problem ortaya çıkabilir?
  • 55. Mediator Öncesi Bileşen Bileşen Bileşen Bileşen Bileşen
  • 56. Örnek 4  Kullanıcımız bağlantılarını yönettiği uygulamasına benzer şekilde adres bilgilerini yönettiği bir uygulama istemektedir.  Ancak uygulamanın bileşenlerinin mümkün olduğunca birbirlerinden bağımsız ve farklı bölümlerde yeniden kullanılabilir olmasına dikkat edilmesi istenmektedir.
  • 57. UI Mockup Address Detail Panel Address List Panel AddressToolBarPanel
  • 62. Mediator Impl. private Collection<MediatorEventListener> listeners = new ArrayList<MediatorEventListener>(); public void addListener(MediatorEventListener listener) { listeners.add(listener); } public void removeListener(MediatorEventListener listener) { listeners.remove(listener); } public void fire(MediatorEvent event) { for(MediatorEventListener listener:listeners) { listener.handle(event); } }
  • 63. Address List Presenter Impl. private AddressListPanel listPanel; public AddressListPresenter(AddressListPanel listPanel, AddressService addressService) { this.listPanel = listPanel; listPanel.loadAddresses(addressService.getAddresses()); } @Override public void handle(MediatorEvent event) { if(event instanceof AddressUpdatedEvent) { AddressUpdatedEvent updateEvent = (AddressUpdatedEvent)event; listPanel.reloadAddress(updateEvent.getAddress()); } }
  • 64. Address Detail Presenter Impl. private AddressDetailPanel detailPanel; public AddressDetailPresenter(AddressDetailPanel detailPanel) { this.detailPanel = detailPanel; } @Override public void handle(MediatorEvent event) { if(event instanceof AddressSelectedEvent) { AddressSelectedEvent selectedEvent = (AddressSelectedEvent)event; detailPanel.displayAddress( selectedEvent.getSelectedAddress()); } }
  • 65. Address ToolBar Presenter Impl. private AddressToolBarPanel addressToolBarPanel; public AddressToolBarPresenter(AddressToolBarPanel addressToolBarPanel) { this.addressToolBarPanel = addressToolBarPanel; addressToolBarPanel.swithToSelectionMode(); } @Override public void handle(MediatorEvent event) { if(event instanceof AddressSelectedEvent) { addressToolBarPanel.swithToUpdateMode(); addressToolBarPanel.setAddress( ((AddressSelectedEvent)event).getSelectedAddress()); } else if(event instanceof AddressUpdatedEvent) { addressToolBarPanel.swithToSelectionMode(); } }
  • 66. Address List View Impl. public AddressListPanelImpl(Mediator mediator) { this.mediator = mediator; ... } @Override public void loadAddresses(Collection<Address> addresses) { ... } @Override public void valueChange(ValueChangeEvent event) { Address address = (Address) table.getValue(); AddressSelectedEvent selectedEvent = new AddressSelectedEvent(address); mediator.fire(selectedEvent); }
  • 67. Address ToolBar View Impl. public AddressToolBarPanelImpl(Mediator mediator) { this.mediator = mediator; ... } @Override public void setAddress(Address address) { this.address = address; } @Override public void buttonClick(ClickEvent event) { if(event.getButton() == updateButton) { mediator.fire(new AddressUpdatedEvent(address)); } }
  • 68. Mediator Sonrası Bileşen Bileşen Mediator Bileşen Bileşen Bileşen
  • 70. İletişim  Harezmi Bilişim Çözümleri Ltd.  Kurumsal Java Eğitimleri  http://www.harezmi.com.tr  http://www.java-egitimleri.com  info@java-egitimleri.com