Neden "vs"? "Vs" değildir. En Boy Odaklı programlamayı işlevsel programlamayla birlikte, aynı zamanda Nesne Odaklı programla birlikte kullanabilirsiniz. "Vs" değil, " Nesne Tabanlı Programlama ile Unsur Odaklı Programlama" dır .
Bana göre AOP bir çeşit "meta-programlama". AOP'nin yaptığı her şey, sadece daha fazla kod ekleyerek onsuz da yapılabilir. AOP sadece bu kodu yazmanızı sağlar.
Wikipedia bu meta-programlama için en iyi örneklerden birine sahiptir. Birçok "set ... ()" yöntemine sahip bir grafik sınıfınız olduğunu varsayın. Her ayar yönteminden sonra grafiklerin verileri değişti, böylece grafikler değişti ve grafiklerin ekranda güncellenmesi gerekiyor. Grafikleri yeniden boyadığınızı varsayalım, "Display.update ()" olarak adlandırmalısınız. Klasik yaklaşım bunu daha fazla kod ekleyerek çözmektir . Her set yönteminin sonunda yazıyorsunuz
void set...(...) {
:
:
Display.update();
}
3 set yönteminiz varsa, bu bir sorun değildir. 200 (varsayımsal) varsa, bunu her yere eklemek çok acı verici oluyor. Ayrıca, yeni bir set yöntemi eklediğinizde, bunu sonuna kadar eklemeyi unutmayın, aksi takdirde sadece bir hata oluşturdunuz.
AOP bunu tonlarca kod eklemeden çözer, bunun yerine bir özellik eklersiniz:
after() : set() {
Display.update();
}
Ve bu kadar! Güncelleme kodunu kendiniz yazmak yerine, sisteme bir set () nokta kesimine ulaşıldıktan sonra bu kodu çalıştırması gerektiğini ve bu kodu çalıştıracağını söylersiniz. 200 yöntemi güncellemeye gerek yok, bu kodu yeni bir set yöntemine eklemeyi unutmadığınızdan emin olmanıza gerek yok. Ek olarak sadece bir noktaya ihtiyacınız var:
pointcut set() : execution(* set*(*) ) && this(MyGraphicsClass) && within(com.company.*);
Bu ne anlama geliyor? Ne olursa olsun yöntemi döndürür (ilk yıldız) ya da ne alır (üçüncü yıldız) parametreleri ne bir yöntem olarak adlandırılır eğer vasıtası Buna "set *" (herhangi bir ad kümesi sonra arkasından gelebilecek * vasıta) ve bunun MyGraphicsClass bir yöntemdir ve bu class "com.company. *" paketinin bir parçasıdır, o zaman bu bir set () nokta kesimidir. Ve ilk kodumuz " sonra bir dizi pointcut olan herhangi bir yöntemi çalıştıran, aşağıdaki kodu çalıştırın".
AOP'un sorunu burada nasıl zarif bir şekilde çözdüğünü görüyor musunuz? Aslında burada açıklanan her şey derleme zamanında yapılabilir. AOP ön işlemcisi, sınıfın kendisini derlemeden önce kaynağınızı değiştirebilir (örn. Her set-pointcut yönteminin sonuna Display.update () eklenmesi).
Bununla birlikte, bu örnek AOP'nin büyük dezavantajlarından birini de göstermektedir. AOP aslında birçok programcının " Anti-Pattern " ( Desen Karşıtı) olduğunu düşündüğü bir şey yapıyor . Kesin patern " Uzaktan hareket " olarak adlandırılır .
Uzaktan eylem, bir programın bir bölümündeki davranışın, programın başka bir bölümündeki işlemleri tanımlamak zor veya imkansız olarak çılgınca değiştiği bir anti-modeldir (tanınan bir yaygın hata).
Bir projeye yeni başlayan biri olarak, herhangi bir set yönteminin kodunu okuyabilir ve ekranı güncellemiyor gibi göründüğünü kırık olarak düşünebilirim. Ben sadece bir set-yöntemin koduna bakarak görmüyorum , çalıştırıldıktan sonra, bazı diğer kod "sihirli" ekranı güncellemek için yürütülecek. Bunu ciddi bir dezavantaj olarak görüyorum! Bir yöntemde değişiklik yapılarak garip hatalar ortaya çıkabilir. Belirli şeylerin doğru çalıştığı, ancak açık olmadığı (kodun söylediği gibi, sadece sihirli bir şekilde çalışıyorlar ... bir şekilde) olduğu kod akışını daha da anlamak gerçekten zor.
Güncelleme
Sadece açıklığa kavuşturmak için: Bazı insanlar AOP'nin kötü bir şey olduğunu ve kullanılmaması gerektiğini söylediğim izlenimine sahip olabilirler. Söylediğim bu değil! AOP aslında harika bir özellik. Ben sadece "Dikkatle kullan" diyorum. AOP yalnızca normal Unsuru ve AOP'yi aynı Unsur için karıştırırsanız sorunlara neden olur . Yukarıdaki örnekte, grafiksel bir nesnenin değerlerini güncelleme ve güncellenmiş nesneyi boyamak gibi bir amacımız var. Bu aslında tek bir özellik. Bunun yarısını normal kod, diğer yarısını en boy oran olarak kodlamak, sorunu ekleyen şeydir.
AOP'yi tamamen farklı bir yön için (örneğin, günlüğe kaydetme için) kullanırsanız, desen karşıtı sorunuyla karşılaşmazsınız. Bu durumda projeye bir acemi "Tüm bu günlük mesajları nereden geliyor? Kodda herhangi bir günlük çıkışı görmüyorum" merak edebilir, ama bu büyük bir sorun değil. Program mantığında yaptığı değişiklikler kütük tesisini zorlukla bozar ve kütük tesisinde yapılan değişiklikler program mantığını zorlukla bozar - bu yönler tamamen ayrılır. Günlüğe kaydetme için AOP kullanmanın avantajı, program kodunuzun yapması gereken her şeyi yapmaya konsantre olabilmesidir ve kodunuzun her yerde yüzlerce günlük iletisi tarafından dağıtılmasına gerek kalmadan yine de gelişmiş günlük kaydı yapabilirsiniz. Ayrıca yeni kod eklendiğinde, sihirli bir şekilde günlük iletileri doğru zamanda doğru içerikle görünecektir.
Örneğimde AOP'un iyi kullanımı, herhangi bir değer ayarlanmış bir yöntemle güncellenmişse her zaman günlüğe kaydetmek olacaktır. Bu bir anti-desen oluşturmayacak ve neredeyse hiçbir sorunun nedeni olmayacaktır.
Birisi, çok fazla sorun yaratmak için AOP'yi kolayca kötüye kullanabiliyorsanız, hepsini kullanmak kötü bir fikirdir. Ancak hangi teknoloji suistimal edilemez? Veri kapsüllemesini kötüye kullanabilir, mirası kötüye kullanabilirsiniz. Hemen hemen her kullanışlı programlama teknolojisi kötüye kullanılabilir. Sadece istismar edilemeyen özellikler içerecek şekilde sınırlı bir programlama dili düşünün; özelliklerin yalnızca başlangıçta kullanılması amaçlandığı gibi kullanılabildiği bir dil. Böyle bir dil o kadar sınırlı olurdu ki, gerçek dünya programlama için bile kullanılabilirse tartışılabilir.