Niedawno podczas koleżeńskiej konserwacji wypłynął nam temat pantoflarstwa, czyli bezwarunkowej podległości osobnika płci męskiej pod swego żeńskiego w życiu partnera. Swoją Panią.
I nieuchronnie już wówczas do głowy napłynęła mi myśl, jak taką sytuację można doskonale zamodelować przy użyciu PostSharp – godnego uwagi darmowego narzędzia do programowania aspektowego w .NET. Przysiadłem na chwilę, ściągnąłem Post#, zaimplementowałem minidemko i je niniejszym prezentuję:
Zaczynamy od naszego MĘŻCZYZNY, który robić może co chce i dumny jest z tego że ŁO-HO-HO:
1: public class Man 2: { 3: public void DrinkBeer() 4: { 5: Console.WriteLine("Drinking beer, yummy!"); 6: } 7: 8: public void BuyFlowers() 9: { 10: Console.WriteLine("Giving flowers for my valentine..."); 11: } 12: 13: public void WatchTv() 14: { 15: Console.WriteLine("Relaxing with tv."); 16: } 17: }
Stwórzmy takiego kola i zobaczmy jak mu życie płynie:
1: static void Main(string[] args) 2: { 3: Man freeMan = new Man(); 4: 5: freeMan.DrinkBeer(); 6: Console.WriteLine("------------------"); 7: freeMan.BuyFlowers(); 8: Console.WriteLine("------------------"); 9: freeMan.WatchTv(); 10: }
Skutek:
Taa…
Dodajmy jednak łyżkę dziegciu do tej beczki miodu, przerysowując nieco rzeczywistość przy pomocy postsharpowego atrybutu:
1: [Serializable, MulticastAttributeUsage(MulticastTargets.Method)] 2: public class PantofelAttribute : OnMethodBoundaryAspect 3: { 4: private readonly Girlfriend _girlfriend = new Girlfriend(); 5: 6: public override void OnEntry(MethodExecutionEventArgs eventArgs) 7: { 8: var actionName = eventArgs.Method.Name; 9: try 10: { 11: _girlfriend.ConsiderPermission(actionName); 12: } 13: catch (Exception exc) 14: { 15: Console.WriteLine( 16: @"Sorry, permission for {0} was not granted. 17: {1} was thrown with the following message from your dearest beloveth: 18: ""{2}""", 19: actionName, exc.GetType().Name, exc.Message); 20: 21: eventArgs.FlowBehavior = FlowBehavior.Return; 22: } 23: } 24: }
Jak to bywa – przed wykonaniem jakiejkolwiek akcji będzie teraz biedak musiał o pozwolenie swojej białogłowy się starać. A że w takiej sytuacji logika zbyt skomplikowana nie jest, i ją można zamodelować bez większego kłopotu:
1: [Serializable] 2: public class Girlfriend 3: { 4: public void ConsiderPermission(string actionName) 5: { 6: // no way! 7: if (actionName.Contains("Beer")) 8: { 9: throw new Foch("You've got to be kidding me!"); 10: } 11: 12: // sure, go ahead 13: if (actionName.Contains("Flowers")) 14: return; 15: 16: // default, rather strict, permission-rejecting rule 17: throw new IDontThinkSoException("Not really sure, but better not."); 18: } 19: }
Można zauważyć, że do sterowania przepływem użyłem w tym przypadku wyjątków, co nie jest praktyką zalecaną. Doświadczeni przyznać jednak mogą rację, że zwykłe zwrócenie true/false mogłoby nie oddać realizmu sytuacji w wystarczającym stopniu :).
No dobra, zmodyfikujmy lekko naszego cwaniaczka:
1: [Pantofel] 2: public class Man 3: {
i zobaczmy jak jego poczynania będą wyglądały teraz:
I cóż, nic dodać, nic ująć…
A jak to jest czytelniku u ciebie? Nałożono ci ów atrybut z bezlitosną konsekwencją, czy też może zmodyfikowałeś go lekko przekazując w konstruktorze enum ObedienceLevel starając się w miarę możliwości ustawiać jakąś akceptowalną wartość?:)
hehe… nice :) Procent może póki co powiedz jak to jest u Ciebie? Przypadkiem nie masz dodatkowego atrybutu EngagementAttribute?
niezle. tylko zeby to nie byl Twoj ostatni wpis lub ostatni bez cenzury…
Taki przyklad z zycia widac :)
Uśmiałem się jak na dobrym kabarecie ;)
Procent: jak Ci się znudzi obecny fach (just joking, don’t throw foch ;), to w rozrywce też zrobisz karierę!
Pozdrawiam i czekam na wiecej.