fbpx
devstyle.pl - Blog dla każdego programisty
devstyle.pl - Blog dla każdego programisty
5 minut

DI: punkt wyjścia


29.05.2014

 

W tym odcinku skupiam się na stanie aplikacji przed jakimikolwiek procesami “upiększającymi”. Stan ten można uzyskać wykonując

git checkout demo1

na podlinkowanym w poprzednim poście repo. Albo można podglądać sobie online: https://github.com/maniserowicz/di-talk/tree/demo1.

Aplikacja, którą mamy upiększyć, została do celów demonstracyjnych zbudowana dość nietypowo. Nie jest to web app, nie jest to nawet console app. Jest to jedna zwykła dllka, ale…

Nie chcemy wiązać się tutaj z żadnym konkretnym frameworkiem. Zamiast tego zasymulujemy dowolny typ aplikacji, który “obsługuje żądania”. Czyli tak naprawdę każdą aplikację. Może to być aplikacja webowa: obsługuje żądania z przeglądarki. Może to być serwis: obsługuje żądania z innych aplikacji. Może to być nawet coś desktopowego, gdzie żądaniem jest akcja użytkownika.

Sercem systemu jest “symulator” dowolnej implementacji “infrastruktury” oferowanej przez jakikolwiek framework do tworzenia aplikacji. Nazwałem to “WebServer” i wygląda tak:

public class WebServer
{
    public void RegisterUser(string email)
    {
        var controller = new UsersController();
        controller.RegisterUser(email);
    }
}

(https://github.com/maniserowicz/di-talk/blob/demo1/src/app/WebServer.cs)

Jak widać, jest to część odpowiedzialna za przyjęcie żądania “skądś”. Akcja, jaką ktoś może wywołać z zewnątrz, to rejestracja nowego użytkownika, a właściwie jego maila. Nasz WebServer musi wykonać dwie czynności:

  1. powołać do życia kawałek aplikacji potrafiący faktycznie zrealizować żądanie (tutaj: UsersController)
  2. wywołać na nim odpowiednią metodę (tutaj: RegisterUser()), przekazując otrzymane parametry

Punkt trzeci byłby zwróceniem rezultatu, ale w tym przypadku to pomijamy.

Proces rejestracji użytkownika składał się będzie z paru dość standardowych kroków:

  1. sprawdzamy czy podany adres e-mail jest poprawny
  2. sprawdzamy czy podany adres e-mail nie jest już zajęty w systemie
  3. tworzymy obiekt reprezentujący nowego użytkownika z podanym adresem oraz unikatowym “tokenem” pozwalającym na weryfikację, czy inicjator akcji jest faktycznie właścicielem konta e-mail
  4. wrzucamy użytkownika do bazy
  5. generujemy “link aktywacyjny” zawierający podany adres e-mail oraz przypisany wcześniej użytkownikowi token
  6. wysyłamy mail z linkiem aktywacyjnym

Standard, prawda? Wszystkie te czynności są zrealizowane w… a jakże, UsersController!

public class UsersController
{
 const string EMAIL_REGEX = @"[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}";

 public void RegisterUser(string email)
 {
 // check if email is valid
 if (Regex.IsMatch(email, EMAIL_REGEX) == false)
 {
 throw new ArgumentException("Invalid email address");
 }

 // check if email is not taken
 if (UsersDatabase.IsEmailTaken(email))
 {
 throw new InvalidOperationException("Email already taken");
 }

 // create new user
 var newUser = new User
 {
 Email = email,
 RegistrationToken = Guid.NewGuid().ToString(),
 };

 // insert user
 UsersDatabase.InsertUser(newUser);

 // generate activation link
 string registrationLink = string.Format(
 "http://myapp.com/confirm?email={0}&token={1}"
 , newUser.Email, newUser.RegistrationToken
 );

 EmailService.RegistrationEmail(newUser.Email, registrationLink);
 }
}

(https://github.com/maniserowicz/di-talk/blob/demo1/src/app/UsersController.cs)

BTW wykorzystane tutaj klasy nie posiadają implementacji – póki co służą tylko jako “coś do wywołania”.

Przyznajcie się, ile razy w życiu widzieliście taki kod? Ba, może nawet taki pisaliście?

Ja się przyznaję: i widziałem, i pisałem. Buuuuu, żal i płacz jak nic. No ale trudno, nie dość że każdy rodzi się głupi, a potem uczy się całe życie, to większość i tak głupia umiera. Natura.

Taki kod (a należy pamiętać, że jest to dość prosty przypadek klasy z jedną tylko metodą) woła o pomstę do nieba. Źle się to czyta, więc źle się to będzie utrzymywać. Strach czegokolwiek ruszać, bo nie da się do tego napisać testów. Ba, ciężko byłoby to nawet przetestować ręcznie! Jakakolwiek modyfikacja owego potwora prawdopodobnie wiązałaby się ze składaniem ofiar całopalnych i niejedną przelaną łzą.

A co jeśli oprócz maila chciałbym wysyłać też SMSa?

A co jeśli chciałbym sprawdzić czy każda z niezależnych od wszystkiego innego akcji (wygenerowanie linka, walidacja maila, wygenerowanie treści wysyłanej wiadomości…) działa jak powinna bez nieustannego debuggowania i klikania?

A co jeśli chciałbym mieć uczucie zbliżone do pewności, że wszystkie te działania ze sobą współgrają, czyli że e-mail nie zostanie wysłany na niewalidujący się adres albo że user zostanie dodany do bazy tylko jeśli w systemie nie ma już zarejestrowanego takiego adresu?

A co jeśli chciałbym dodać bardziej skomplikowaną walidację adresu e-mail niż tylko poprzez głupi regex?

A co jeśli chciałbym uzyskać transakcyjność na poziomie infrastruktury, coby użytkownik nie został w bazie jeśli nie powiedzie się wysyłka wiadomości, przez co nigdy nie mógłby zweryfikować adresu e-mail, a więc aktywować konta?

A co jeśli… popuszczę wodze fantazji i wymyślę kolejnych kilkanaście potencjalnych scenariuszy? Nic, nudno będzie, więc na tym poprzestanę.

Zróbmy coś z tym…

0 0 votes
Article Rating
12 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Kamil
Kamil
9 years ago

Super się zapowiada;)

trackback
9 years ago

DI: punkt wyjścia | Maciej Aniserowicz o programowaniu…

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

Przemysslaw
Przemysslaw
9 years ago

Temat według mnie bardzo ciekawy, i dla mnie osobiście zaliczający się do kategorii “eye opener” (względnie “mind f*ck”) ;) Chętnie dowiem się czegoś nowego i skonfrontuję z moim aktualnym stanem wiedzy ;)

Piotr Perak
9 years ago

A ja się zastanawiam, czy da się jeszcze coś napisać o IoC i DI czego nie było już na 100 innych blogach? I to kilka lat temu. I wydaje mi się, że nie. Ale oczywiście mogę się mylić.

Piotr Perak
9 years ago

Ok.
Po prostu co mi wpadnie jakiś pomysł na posta na mój skromny na razie blog to wydaje mi się, że temat już na maksa oklepany i z tego rezygnuję.

Tomek
Tomek
9 years ago

Czy będzie kolejny post, który pokarze odpowiedzi na zadane pytania/wątpliwości? Jestem bardzo ciekawy.

Dziękuję i pozdrawiam,
Tomek

Tomasz
Tomasz
9 years ago

Super już nie mogę się doczekać kolejnych części.
Maciej obecnie próbuje się odnaleść w dobrych praktykach programowania jakie blogi miejsca zagraniczne lub też polskie możesz polecić by właśnie tą wiedze poglębić?

Kurs Gita

Zaawansowany frontend

Szkolenie z Testów

Szkolenie z baz danych

Książka

Zobacz również