24 Temmuz 2019 Çarşamba

MutableClassToInstanceMap Sınıfı

Giriş
A.class sınıfından kalıtan nesneleri saklamak içindir. Map<A.class,MyOtherType> tarzı A ile kalıtım ilgisi olmayan value tiplerde kullanımı uygun değil.


get metodu
Şöyle yaparız.
<T extends RestClientInterface> T getInstance(Class<T> type) {
  return map.getInstance(type);
}
of metodu
Şöyle yaparız.
ClassToInstanceMap<RestClientInterface> map = MutableClassToInstanceMap.create();

17 Temmuz 2019 Çarşamba

FutureCallback Arayüzü

Giriş
ListenableFuture bitince tetiklenir. Bu metodlar işi tetikleyen yani threadpool'a execute çağrısı yapan thread içinde çalışır. Açıklaması şöyle
This is still better than the guava default of MoreExecutors.directExecutor() where its done in the thread that invokes execute..
onFailure metodu
Şöyle yaparız.
ListenableFuture<?> future = executor.submit(runnable);

FutureCallback<?> callback = new FutureCallback() {

   @Override
   public void onSuccess(Object result) {}

   @Override
   public void onFailure(Throwable t) {}

};

Futures.addCallback(future, callback, executor);
onSuccess metodu
Şöyle yaparız.
return new FutureCallback<List<Grandparents>>() {
  @Override
  public void onSuccess(List<Grandparents> grandparents) {
   
    for(grandparent g : grandparents) {
      ...
    }
  }
}

12 Temmuz 2019 Cuma

UnsignedLongs Sınıfı

parseUnsignedLong metodu
Belirtilen string'i long olarak verir.

toString metodu
Şöyle yaparız.
String formatted = UnsignedLongs.toString(myLongValue);

10 Temmuz 2019 Çarşamba

EventBus Sınıfı

Giriş
Şu satırı dahil ederiz.
import com.google.common.eventbus.EventBus;
Açıklaması şöyle. Aynı JVM içinde haberleşmek içindir. Eğer asenkron olarak çalışmak istersek AsyncEventBus kullanılabilir
It is not a general-purpose publish-subscribe system, nor is it intended for interprocess communication
Açıklaması şöyle.

Why can't I do <magic thing> with EventBus?

EventBus is designed to deal with a large class of use cases really, really well. We prefer hitting the nail on the head for most use cases to doing decently on all use cases.
Additionally, making EventBus extensible -- and making it useful and productive to extend, while still allowing ourselves to make additions to the core EventBus API that don't conflict with any of your extensions -- is an extremely difficult problem.
If you really, really need magic thing X, that EventBus can't currently provide, you should file an issue, and then design your own alternative.
EventBus ve Unit Test
EventBus exception'ları yuttuğu için Assertions.assertFalse() gibi bir çağrı eventbus içinde yapılsa daha test başarısız olarak işaretlenmez. Buna dikkat etmek lazım.

Kullanım
1. Bir adet EventBus nesnesi yarat
2. EventBus nesnesinin register() metodunu kullanarak Listener tak. Listener'ların @Susbcribe ile işaretli metodları EventBus tarafından tanınır.
3. EventBus.post() ile event gönder

constructor
Şöyle yaparız.
EventBus bus = new EventBus();
post metodu
post metodu hemen döner ve event kuyruğa atılır. Bir event için tüm dinleyiciler çağrıldıktan sonra kuyruktaki yeni event işletilir.

Örnek
Şöyle yaparız.
bus.post ( new String("event!"));
Dinleyen metodu şöyle yaparız.
@Subscribe
public void consume(String event) {
   System.out.println("Got event: " + event);
}
Örnek
post metodu içinde başka event fırlatmak istersek şöyle yaparız. Elimizde şöyle bir kod olsun.
interface InternalEventCallback {
  void run();
}

class InternalEventCallbackHandler {

  @Subscribe
  public void internalEventHandler(InternalEventCallback r){
    r.run();
  }
}
Bu handler'ı register ederiz. Şöyle yaparız.
eventBus.register(new InternalEventCallbackHandler());
İlk handler içinde önce NestedEvent  gönderilir. Bunun sonucuna bakmadan InternalEventCallback da gönderilir. InternalEventCallback çalışınca NestedEvent işlenmiş olur. Onun sonucuna bakarak InternalEventCallback devam eder veya durur.
@Subscribe
public void parentEventHandler(ParentEvent parentEvent) {
  NestedEvent nestedEvent = createNestedEvent();
  eventBus.post(nestedEvent);
  eventBus.post(new InternalEventCallback() {
    @Override
    public void run() {
      if(nestedEvent.isCancelled()) {
        return;
      }

      Object anotherNestedEvent = createOtherNestedEvent();
      eventBus.post(anotherNestedEvent);
    }
  });
}
register metodu
Açıklaması şöyleEventBus'a register olan dinleyici sınıfların metodlarının Java'daki kalıtım hiyerarşisine göre de çağırılabileceği anlatılıyor. Örneğin dinleyici sınıf parametresi Object olan bir metod tanımlarsa EventBus ile gönderilen tüm mesajları dinleyebilir.
To listen for a common event supertype (such as EventObject or Object)...
...in traditional Java events: not easy.
...with EventBus: events are automatically dispatched to listeners of any supertype, allowing listeners for interface types or "wildcard listeners" for Object.
Otto isimli Guava tabanlı bir EventBus, Guava'daki bu çalışma şeklini değiştirmiş. Yeni bir dinleyici EventBus'a kayıt olunca sınıf hiyerarşisini dolaşmayarak sadece verilen metodu kaydetme yöntemini seçmiş.

Örnek
Şöyle yaparız.
bus.register(foo);
Örnek
Elimizde şöyle bir kod olsun.
public class ComponentRepainter {

  @Subscribe
  public void doSomething(EventObject e) {
    ((Component) e.getSource()).repaint();
  }
}
Elimizde şöyle bir kod olsun.
EventBus eventBus = ... ;
eventBus.register(new ComponentRepainter());
Her türlü event nesnesini ComponentRepainter nesnesinin de duyması için şöyle yaparız
MouseEvent e = ... ;
eventBus.post(e);
Örnek
Elimizde şöyle bir kod olsun.
class MyEvent[T] protected () { /* Your methods here */ }
class MyEventInt extends MyEvent[Int] {}
class MyEventString extends MyEvent[String] {}
Her bir event tipi için @Subscribe metodu yazarsak generic event'ler de gönderebiliriz.

unregister metodu
Bu sınıf WeakReference kullanmıyor dolayısıyla dinleyici sınıfın kod kullanılarak bus'tan çıkarılması gerekiyor.