Przejdź do głównej zawartości

Wzorzec Obserwator - otrzymywanie subskrybowanych informacji.

Po tym jak mogę dodawać obiekty do listy subskrybentów zabieram się za otrzymywanie wiadomości.

Poprzedni post tu.

Napisałem sobie krótki test w Ruby:
def test_receiving_information                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
    @client = Client.new                                                                                                                                                                                                                     
    @media.add_advertising("5 55 555")                                                                                                                                                                                                       
    @media.add_to_subscribers @client                                                                                                                                                                                                        
    #@media.broadcast                                                                                                                                                                                                                        
    #assert_not_empty @client.ads                                                                                                                                                                                                            
                                                                                                                                                                                                                                             
end




Na razie wykomentowałem dalsze akcji i puszczam rake:

coola@sv26 [/home/coola/dsp2017/xp-simulator]# rake                                                                                                                                                                                          
/usr/share/ruby-2.3.1/bin/ruby ./test/all_tests.rb                                                                                                                                                                                           
Loaded suite ./test/all_tests                                                                                                                                                                                                                
Started                                                                                                                                                                                                                                      
......E                                                                                                                                                                                                                                      
=============================================================================================================================================================================================================================================
Error: test_receiving_information(SubscriptionTests): RuntimeError: Argument should have publish method                                                                                                                                      
/home/coola/dsp2017/xp-simulator/src/Media.rb:17:in `add_to_subscribers'                                                                                                                                                                     
/home/coola/dsp2017/xp-simulator/test/subscription_tests.rb:47:in `test_receiving_information'                                                                                                                                               
     44:                                                                                                                                                                                                                                     
     45:     @client = Client.new                                                                                                                                                                                                            
     46:     @media.add_advertising("5 55 555")                                                                                                                                                                                              
  => 47:     @media.add_to_subscribers @client                                                                                                                                                                                               
     48:     #@media.broadcast                                                                                                                                                                                                               
     49:     #assert_not_empty @client.ads                                                                                                                                                                                                   
     50:                                                                                                                                                                                                                                     
=============================================================================================================================================================================================================================================
                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
Finished in 0.002118131 seconds.                                                                                                                                                                                                             
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7 tests, 9 assertions, 0 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications                                                                                                                                                        
85.7143% passed                                                                                                                                                                                                                              
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3304.80 tests/s, 4249.03 assertions/s                                                                                                                                                                                                        
rake aborted!                                                                                                                                                                                                                                
Command failed with status (1): [/usr/share/ruby-2.3.1/bin/ruby ./test/all_...]                                                                                                                                                              
/home/coola/dsp2017/xp-simulator/Rakefile:4:in `block in <top (required)>'                                                                                                                                                                   
/home/coola/.gems/2.3/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'                                                                                                                                                                     
Tasks: TOP => default => test                                                                                                                                                                                                                
(See full trace by running task with --trace)                                   


Okazuje się, że mój klient nie "implementuje" metody publish, potrzebnej dla obiektu Media do publikacji.

Dopisuję dwie linijki:

class Client                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                             
  def publish                                                                                                                                                                                                                                
  end  
                                                                                                                                                                                                                                      
end 

Dla rake to wystarczy:

coola@sv26 [/home/coola/dsp2017/xp-simulator]# rake                                                                                                                                                                                          
/usr/share/ruby-2.3.1/bin/ruby ./test/all_tests.rb                                                                                                                                                                                           
Loaded suite ./test/all_tests                                                                                                                                                                                                                
Started                                                                                                                                                                                                                                      
.......                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                             
Finished in 0.00171854 seconds.                                                                                                                                                                                                              
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7 tests, 9 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications                                                                                                                                                        
100% passed                                                                                                                                                                                                                                  
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4073.22 tests/s, 5237.00 assertions/s               


Odkomentowuję następną linijkę:

def test_receiving_information                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
    @client = Client.new                                                                                                                                                                                                                     
    @media.add_advertising("5 55 555")                                                                                                                                                                                                       
    @media.add_to_subscribers @client                                                                                                                                                                                                        
    @media.broadcast                                                                                                                                                                                                                         
    #assert_not_empty @client.ads                                                                                                                                                                                                            
                                                                                                                                                                                                                                             
end 


Tutaj przede wszystkim nie ma metody broadcast i jej implementacji.

coola@sv26 [/home/coola/dsp2017/xp-simulator]# rake                                                                                                                                                                                          
/usr/share/ruby-2.3.1/bin/ruby ./test/all_tests.rb                                                                                                                                                                                           
Loaded suite ./test/all_tests                                                                                                                                                                                                                
Started                                                                                                                                                                                                                                      
......E                                                                                                                                                                                                                                      
=============================================================================================================================================================================================================================================
Error: test_receiving_information(SubscriptionTests): NoMethodError: undefined method `broadcast' for #<Media:0x007f3f412768c0>                                                                                                              
/home/coola/dsp2017/xp-simulator/test/subscription_tests.rb:48:in `test_receiving_information'                                                                                                                                               
     45:     @client = Client.new                                                                                                                                                                                                            
     46:     @media.add_advertising("5 55 555")                                                                                                                                                                                              
     47:     @media.add_to_subscribers @client                                                                                                                                                                                               
  => 48:     @media.broadcast                                                                                                                                                                                                                
     49:     #assert_not_empty @client.ads                                                                                                                                                                                                   
     50:                                                                                                                                                                                                                                     
     51:   end                                                                                                                                                                                                                               
=============================================================================================================================================================================================================================================
                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
Finished in 0.002872458 seconds.                                                                                                                                                                                                             
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7 tests, 9 assertions, 0 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications                                                                                                                                                        
85.7143% passed                                                                                                                                                                                                                              
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2436.94 tests/s, 3133.21 assertions/s                                                                                                                                                                                                        
rake aborted!                                                                                                                                                                                                                                
Command failed with status (1): [/usr/share/ruby-2.3.1/bin/ruby ./test/all_...]                                                                                                                                                              
/home/coola/dsp2017/xp-simulator/Rakefile:4:in `block in <top (required)>'                                                                                                                                                                   
/home/coola/.gems/2.3/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'                                                                                                                                                                     
Tasks: TOP => default => test                                                                                                                                                                                                                
(See full trace by running task with --trace)          


Dodaję zmiany w klasie Media:

class Media                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                             
  attr_accessor :ads, :subscribers                                                                                                                                                                                                           
                                                                                                                                                                                                                                             
  def initialize                                                                                                                                                                                                                             
    @ads = Array.new                                                                                                                                                                                                                         
    @subscribers = Array.new                                                                                                                                                                                                                 
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
  def add_advertising telephone_number                                                                                                                                                                                                       
    @ads.push telephone_number                                                                                                                                                                                                               
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
  def add_to_subscribers client                                                                                                                                                                                                              
    if !client.respond_to? :publish                                                                                                                                                                                                          
      raise 'Argument should have publish method'                                                                                                                                                                                            
    end                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                             
    @subscribers.push client                                                                                                                                                                                                                 
                                                                                                                                                                                                                                             
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
  def broadcast                                                                                                                                                                                                                              
    @subscribers.each { |subscriber| subscriber.publish @ads }                                                                                                                                                                               
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
end 


Używam metody publish z atrybutem i rzeczywiście rake mówi, że w klasie Client nie ma atrybutu metody publish:

                                                                                                                                                                                         
Loaded suite ./test/all_tests                                                                                                                                                                                                                
Started                                                                                                                                                                                                                                      
......E                                                                                                                                                                                                                                      
=============================================================================================================================================================================================================================================
Error: test_receiving_information(SubscriptionTests): ArgumentError: wrong number of arguments (given 1, expected 0)                                                                                                                         
/home/coola/dsp2017/xp-simulator/src/Client.rb:3:in `publish'                                                                                                                                                                                
/home/coola/dsp2017/xp-simulator/src/Media.rb:25:in `block in broadcast'                                                                                                                                                                     
/home/coola/dsp2017/xp-simulator/src/Media.rb:25:in `each'                                                                                                                                                                                   
/home/coola/dsp2017/xp-simulator/src/Media.rb:25:in `broadcast'                                                                                                                                                                              
/home/coola/dsp2017/xp-simulator/test/subscription_tests.rb:48:in `test_receiving_information'                                                                                                                                               
     45:     @client = Client.new                                                                                                                                                                                                            
     46:     @media.add_advertising("5 55 555")                                                                                                                                                                                              
     47:     @media.add_to_subscribers @client                                                                                                                                                                                               
  => 48:     @media.broadcast                                                                                                                                                                                                                
     49:     #assert_not_empty @client.ads                                                                                                                                                                                                   
     50:                                                                                                                                                                                                                                     
     51:   end                                                                                                                                                                                                                               
=============================================================================================================================================================================================================================================
                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
Finished in 0.002341671 seconds.                                                                                                                                                                                                             
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7 tests, 9 assertions, 0 failures, 1 errors, 0 pendings, 0 omissions, 0 notifications                                                                                                                                                        
85.7143% passed                                                                                                                                                                                                                              
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2989.32 tests/s, 3843.41 assertions/s                                                                                                                                                                                                        
rake aborted!                                                                                                                                                                                                                                
Command failed with status (1): [/usr/share/ruby-2.3.1/bin/ruby ./test/all_...]                                                                                                                                                              
/home/coola/dsp2017/xp-simulator/Rakefile:4:in `block in <top (required)>'                                                                                                                                                                   
/home/coola/.gems/2.3/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'                                                                                                                                                                     
Tasks: TOP => default => test                                                                                                                                                                                                                
(See full trace by running task with --trace)           

Dopisuję argument ads do klasy Client i jest OK.

Teraz odkomentowuję ostatnią linijkę testu:

def test_receiving_information                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
    @client = Client.new                                                                                                                                                                                                                     
    @media.add_advertising("5 55 555")                                                                                                                                                                                                       
    @media.add_to_subscribers @client                                                                                                                                                                                                        
    @media.broadcast                                                                                                                                                                                                                         
    assert_not_empty @client.ads                                                                                                                                                                                                             
                                                                                                                                                                                                                                             
  end  

Rake krzyczy, że nie ma zmiennej klasowej ads i jest ona pusta:

Started                                                                                                                                                                                                                                      
......E                                                                                                                                                                                                                                      
=============================================================================================================================================================================================================================================
Error: test_receiving_information(SubscriptionTests): NoMethodError: undefined method `ads' for #<Client:0x007f1a96ef2420>                                                                                                                   
/home/coola/dsp2017/xp-simulator/test/subscription_tests.rb:49:in `test_receiving_information'                                                                                                                                               
     46:     @media.add_advertising("5 55 555")                                                                                                                                                                                              
     47:     @media.add_to_subscribers @client                                                                                                                                                                                               
     48:     @media.broadcast                                                                                                                                                                                                                
  => 49:     assert_not_empty @client.ads                                                                                                                                                                                                    
     50:                                                                                                                                                                                                                                     
     51:   end                                                                                                                                                                                                                               
     52:                                                                                                                                                                                                                                     
=============================================================================================================================================================================================================================================
                         

Dodaję zmiany:

class Client                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                             
  def publish ads                                                                                                                                                                                                                            
                                                                                                                                                                                                                                             
    @ads = ads                                                                                                                                                                                                                               
                                                                                                                                                                                                                                             
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
  def ads                                                                                                                                                                                                                                    
    @ads                                                                                                                                                                                                                                     
  end                                                                                                                                                                                                                                        
                                                                                                                                                                                                                                             
end

I teraz projekt przechodzi wszystkie testy :)


coola@sv26 [/home/coola/dsp2017/xp-simulator]# rake                                                                                                                                                                                          
/usr/share/ruby-2.3.1/bin/ruby ./test/all_tests.rb                                                                                                                                                                                           
Loaded suite ./test/all_tests                                                                                                                                                                                                                
Started                                                                                                                                                                                                                                      
.......                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                             
Finished in 0.001713314 seconds.                                                                                                                                                                                                             
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7 tests, 10 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications                                                                                                                                                       
100% passed                                                                                                                                                                                                                                  
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4085.65 tests/s, 5836.64 assertions/s 

Commit do tego tu.

To jest ostatni projektowy wpis w konkursie Daj się Poznać 2017. Dzięki Maćku i Społeczności :)

Komentarze

Popularne posty z tego bloga

Kursy IT na Pluralsight. Dlaczego warto?

Bardzo sobie cenię kursy na Pluralsight. Mam wrażenie, że każdy kurs, który przeszedłem na tej platformie, w dużym stopniu podniósł moje zdolności. Wiem, dostęp do tej platformy nie jest tani, ale w mojej ocenie warty swojej ceny. To nie jest reklama, ale forma entuzjazmu jaki mam do tej formy samodoskonalenia. O to kilka punktów pokazujących ofertę tego serwisu i dlaczego warto skorzystać: Pluralsight to kursy z Javascript, C#, Java, Angular, Python, MySQL i wielu innych technologii i umiejętności. Kursy na Pluralsight w większości mają wyższą jakość niż te, które możemy znaleźć na przykład na YouTube. Są wyselekcjonowane, mają wysoką jakość dźwięku i obrazu. Często wgryzają się głęboko w dany problem daleko poza standardowe „Hello World” danej technologii. Twórcy Pluralsight to często osoby znane ze świata IT i konferencji branżowych, jak: Scott Hanselman, Microsoft John Somnez, SimpleProgrammer.com John Skeet, Google Pluralsight udostępnia funkcjonalność ścieżek – paths....

Bicie piany

Czy słyszałeś o tym gościu, który powiedział, że Object Oriented to przeżytek? No nie. Następny. Co powiedział? Opisał wszystkie obietnice OO, i jak żadna z nich tak naprawdę nigdy nie została spełniona i o tych wszystkich możliwościach OO, które kosztują więcej, niż są warte i że funkcjonalne programowanie jest lepsze i ... Phi. Tak słyszałem już to wcześniej. No, więc OO jest martwe, leży i kwiczy i możemy przejść dalej. Przejść dalej do czego? Co? No do NASTĘPNEJ WIELKIEJ RZECZY oczywiście. Aaaa, do tego. Czy wiesz już co to jest? Nie bałdzo, ale jestem podekscytowany na myśl o mikroserwisach; jaram się Elixirem; i słyszałem, że React jest fantastyczny; i ... Tak, tak. Bicie piany. Dałeś się nabrać na bicie piany. Co? Co masz na myśli. Przecież mamy takie wspaniałe czasy. Tak naprawdę postrzegam te czasy jako depresyjne. Ale dlaczego? Przecież co kilka dni wyskakują nowe wspaniałe technologie! Wspinamy się na coraz wyższe szczyty. Phi. To, co tak napraw...

Podstawy Programowania Funkcyjnego Epizod 1

O czym jest programowanie funkcyjne? Zakładam, że słyszałeś już kiedyś o programowaniu funkcyjnym. No cóż, któż nie słyszał? Wszyscy o tym gadają. Wychodzi dużo nowych języków funkcyjnych takich, jak Scala, F# i Clojure. Ludzie rozmawiają też o starszych językach jak Erlang, Haskell, ML i innych. A więc, o co w tym wszystkim chodzi? Dlaczego programowanie funkcyjne jest Następną Wielką Rzeczą™? I co jest w tym takiego pociągającego? Poniższy tekst jest luźnym tłumaczeniem wpisu bloga Roberta Cecila "Wujka Boba" Martina z dnia 22 grudnia 2012 ze strony: https://blog.cleancoder.com/uncle-bob/2012/12/22/FPBE1-Whats-it-all-about.html Proszę o komentarze, jeżeli ta luźność jest zbyt daleko posunięta. Po pierwsze, prawie na pewno programowanie funkcyjne jest następną wielką rzeczą. Są ku temu dobre, solidne powody i poznamy je w tym artykule. Ale najpierw, aby zrozumieć te powody, musimy poznać, czym programowanie funkcyjne jest....