Komentarze do Robert Pająk - Blog http://rpajak.com Inżynieria oprogramowania, .NET i bazy danych Fri, 28 Nov 2014 17:02:01 +0000 hourly 1 http://wordpress.org/?v=4.0.1 Skomentuj Jakość oprogramowania i Extreme Programming, którego autorem jest dotnetomaniak.pl http://rpajak.com/jakosc-oprogramowania-i-extreme-programming/#comment-185 Fri, 28 Nov 2014 17:02:01 +0000 http://rpajak.com/?p=262#comment-185 Jakość oprogramowania i Extreme Programming | Robert Pająk – Blog

Dziękujemy za dodanie artykułu – Trackback z dotnetomaniak.pl

]]>
Skomentuj IFactory = abstrakcja na Func<Owned<T>>, którego autorem jest Pellared http://rpajak.com/ifactory-abstrakcja-na-func/#comment-136 Wed, 29 Oct 2014 19:51:14 +0000 http://rpajak.com/?p=253#comment-136 Bardzo dobry komentarz!

Myślę, że też takie podejście jest (przynajmniej dla mnie) bardziej intuicyjne i zrozumiałe. Na pewno też łatwiej wtedy napisać testy jednostkowe do takiej klasy!

Podam jedyną zaletę jaką osobiście widzę w IFactory. Łatwo da się skonfigurować Autofac’a, żeby radził sobie z prostymi zależnościami w stylu Func>. Jednak problemy zaczynają się jak fabryka potrzebuje argumentu podczas tworzenia np. Func> – niestety nie potrafiłem zmusić Autofac’a, żeby mi automatycznie rejestrował takie zależności… Mimo, że z Func sobie radzi bez najmniejszych problemów! Obejściem problemu jest wstrzyknięcie dwóch fabryk Func oraz Func> i ręczne poskładania obu funkcji – to już zadziała… Alternatywnie można jawnie wstrzyknąć lambdę podczas bootstrapowania…

Mimo takich problemów z delegatami nie twierdzę w żaden sposób, że podejście z IFactory jest lepsze niż wsytrzykiwanie Func. Niektórzy po prostu wolą interfejsy niż Func<>. Dla niektórych Func<> jest zbyt abstrakcyjny.

]]>
Skomentuj IFactory = abstrakcja na Func<Owned<T>>, którego autorem jest Arek Bal http://rpajak.com/ifactory-abstrakcja-na-func/#comment-134 Wed, 29 Oct 2014 18:39:00 +0000 http://rpajak.com/?p=253#comment-134 Ja tam wolę na odwrót.
Func czy delegat Factory jako podstawa fabryki Wygodne, ładne i krótsze niż całe CosTam.Create()
Lista tworząca te obiekty w bootstrappowaniu to
takie coś:
HeyFactory = () => new Dong();
OjejkuFactory = () => new DOdo();
JajjaFactory = foo => new Jajjo(OjejkuFactory);

Nie wspominając o rekordowej wydajności. Normalnie połączenie 3 światów:
-CleanCode(mniej kodu, czytelniejszy kod)
-Wydajności(Nie potrzeba inicjalizować instancji fabryk, lambdy kosztuje, ale zawsze mniej)
-Architektury(obiektowość i zarządzanie zależnościami)

A te klasy faktoryzujące(jak nam się fabryka jakimś cudem rozrośnie np. o inicjalizację z różnych źródeł w zależności od ustawień configa) zwyczajnie mogą mieć extensiona adaptującego do delegata Func ToDelegate(this IFactory that)

]]>
Skomentuj IFactory = abstrakcja na Func<Owned<T>>, którego autorem jest dotnetomaniak.pl http://rpajak.com/ifactory-abstrakcja-na-func/#comment-132 Mon, 27 Oct 2014 22:03:04 +0000 http://rpajak.com/?p=253#comment-132 IFactory = abstrakcja na Func | Robert Pająk – Blog

Dziękujemy za dodanie artykułu – Trackback z dotnetomaniak.pl

]]>
Skomentuj Wzorce prezentacji MVC MVP MVVM – różnice, którego autorem jest sebek http://rpajak.com/wzorce-prezentacji-mvc-mvp-mvvm-roznice/#comment-131 Mon, 27 Oct 2014 14:27:30 +0000 http://rpajak.com/blog/?p=61#comment-131 Zrób schemty z blokami (M, V, C, P, VM) i strzałeczkami łączącymi. Będą mocno pomagać podczas czytania artykułu…

]]>
Skomentuj IOwned = IDisposable + Dependency Injection, którego autorem jest Pellared http://rpajak.com/iowned-aby-nasze-abstrakcja-byly-mozliwie-czysta/#comment-128 Sun, 26 Oct 2014 20:37:46 +0000 http://rpajak.com/?p=243#comment-128 Z Twoimi komentarzami się zgadzam i najlepiej gdyby wszystko było takie jak to opisałeś :)

Samo współdzielenie zasobów w programowaniu współbieżnym jest bardzo nieefektywne i niebezpieczne i niewygodne itp itd ale niestety czasami inaczej się nie da, nie mówiąc już o rozproszonym zwalnianiu zasobów (sic!)… Niestety czasami nie mamy innego wyboru , bo może nas zmuszać do tego np. architektura jakiegoś istniejącego już oprogramowania. Zgadzam się, że wtedy najlepszym wyjściem jest posiadanie opisywanego przez Ciebie „parenta”, który zarządza zwalnianiem i zwalnia wtedy kiedy wszystkie „childy” już wykorzystają dany obiekt. Mam już na to przygotowaną implementację, którą podzielę się za 2 posty… Jednak nikomu nie życzę, żeby kiedykolwiek z tego korzystał…

W pracy mamy do czynienia z dużą ilością „Disposable” – programujemy dość niskopoziomowo jak na .NET :)

Nie chcemy mieć finalizatorów (destruktory są w C++ :) ) w kodzie produkcyjnym, bo pogorszyłoby nam to wydajność (takie obiekty z automaty lecą do drugiej kolekcji). Generalnie nie mam nic przeciwko finalizatorom – w 99% przypadkach ich narzut nie stanowi problemu. Notabene właśnie do tego mechanizmu śledzenia zamian wykorzystuję destruktor – jakbyś nie zauważył :)

Bardzo dziękuję za komentarz!

]]>
Skomentuj IOwned = IDisposable + Dependency Injection, którego autorem jest Mad http://rpajak.com/iowned-aby-nasze-abstrakcja-byly-mozliwie-czysta/#comment-126 Sun, 26 Oct 2014 11:30:14 +0000 http://rpajak.com/?p=243#comment-126 Poniżej moje kolejne uwagi do punktu nr 1 :)

Możliwość wywołania zwalniania obiektów przez kilka wątków na raz, jest już złym pomysłem. Jeżeli istnieje taka sytuacja, to równie dobrze jeden z wątków może używać obiektu, gdy inny wątek już go zwolnił. W .NET BCL też można znaleźć implementacje Dispose, które nie są bezpieczne wielowątkowo. To nie Dispose jest odpowiedzialny za bezpieczeństwo wielowątkowe, ale „coś” wyżej. Może być to osoby wątek, który czeka aż inne wątki przestaną używać obiekt i wtedy on go zwolni. Równie dobrze może być to parent, który tworzy obiekty lub uruchamia wątki. To daje nam pewność, że obiekt zostanie zwolniony w jednym miejscu, w bezpiecznym momencie.

Wracając do Autofac’a, nie znam wew. implementacji tego konteneru. Być może implementacja Dispose wpasowuje się w ich architekturę. Może akurat takie rozwiązanie jest dobre, bo wprowadzili pewne założenia w innych miejscach, gdzie tworzone są obiekty. Mogę tylko zgadywać :) Akurat argument, że framework A zrobił to tak, to w naszym frameworku B takie rowiązanie też będzie słuszne, nie przemawia do mnie.

Jeśli chodzi o podstawową implementację IDisposable według MS, to jest tam mechanizm śledzenia zasobów, które zapomnieliśmy zwolnić (czyli po prostu zapomnieliśmy wywołać Dispose). Służy do tego destruktor, który czyści tylko zasoby niezarządzane. Zarządzane obiekty (pola w danej klasie) i tak zostaną wychwycone przez GC.

Duplikacja kodu? Zgadzam się :)

]]>
Skomentuj IOwned = IDisposable + Dependency Injection, którego autorem jest Pellared http://rpajak.com/iowned-aby-nasze-abstrakcja-byly-mozliwie-czysta/#comment-124 Fri, 24 Oct 2014 22:58:17 +0000 http://rpajak.com/?p=243#comment-124 Dziękuję za komentarz.

1. Myślę, że mój post daje wystarczająco dużo powódów, aby używać moijej implementacji. Dodam, że np. programiści Autofac’a też mają swoją implementację Disposable na, której się m.in. wzorowałem; https://github.com/autofac/Autofac/blob/master/Core/Source/Autofac/Util/Disposable.cs. Implementcja IDisposable z MSDN, nie jest bezpieczna wątkowo, nie ma mechanizmu śledzenia zasobów, które zapomnieliśmy zwolnić i jeszcze powoduje duplikację kodu…

2. Tutaj chodzi o przypadek kiedy musimy zwolnić zasoby szybciej niż to zrobi za nas kontener. Np. żeby nie trzymać niepotrzebnie długo otwartego pliku, którego wymaga klasa Foo. A funkcjonalności tej klasy potrzebujemy tylko, żeby zrobić parę rzeczy. Wydaje mi się, że w typowych webowych aplikacjach biznesowych rzadko występuje taka potrzeba. Gorąco zachęcam do zapoznania się z postem http://nblumhardt.com/2010/01/the-relationship-zoo/ z dodatkowym zwróceniem uwagi na komentarze Marka Seemanna.

]]>
Skomentuj IOwned = IDisposable + Dependency Injection, którego autorem jest Mad http://rpajak.com/iowned-aby-nasze-abstrakcja-byly-mozliwie-czysta/#comment-121 Fri, 24 Oct 2014 19:03:26 +0000 http://rpajak.com/?p=243#comment-121 Ja tutaj nie widzę czystej architektury. Proponujesz jakieś dodatkowe, skomplikowane abstrakcje do opakowywania obiektów (ten wpis) lub dziedziczenia po nich (wpis o implementowaniu IDisposable).

Zacznę od implementacji IDisposable – wzorzec jest prosty, można go znaleźć na MSDN, ten sam od wielu lat. Wystarczy snippet (dla leniwych) i dopisać linie odpowiedzialne za zwolnienie pól, które tego wymagają. Po co dodatkowe dziedziczenie lub kompozycja?

Zwalnianie obiektów. Sprawa jest prosta – kto tworzy, ten sprząta. Ja tworze obiekt w kodzie? Ja jestem odpowiedzialny za wywołanie Dispose. Jeśli kontener tworzy obiekt, to on powinien go zwalniać. Ponownie, po co dodatkowe opakowywanie za pomocą Owned? Na przykładzie Ninject i ASP.NET MVC:

public class Foo : IFoo, IDisposable
{
// kod…
}

public interface IFoo
{
// kod…
}

Bind<IFoo>().To<Foo>().InRequestScope();

Kontener tworzy obiekt i sam go zwalnia po skończonym żądaniu (rozpoznaje, że Foo implementuje IDisposable). Mój interfejs jest czysty, bo nie ma IDisposable. Moja klasa jest czysta, bo nie jest opakowana, oraz nie przyjmuje przez konstruktor lub metodę jakiegoś dodatkowego obiektu, który będzie ją czyścić.

]]>
Skomentuj IOwned = IDisposable + Dependency Injection, którego autorem jest dotnetomaniak.pl http://rpajak.com/iowned-aby-nasze-abstrakcja-byly-mozliwie-czysta/#comment-117 Thu, 23 Oct 2014 20:18:04 +0000 http://rpajak.com/?p=243#comment-117 IOwned – aby nasze abstrakcja były możliwie czysta | Robert Pająk – Blog

Dziękujemy za dodanie artykułu – Trackback z dotnetomaniak.pl

]]>