بافنده جوانب

بافندهٔ جوانب  ابزاری برای زبان‌های جنبه گرا هست که وظیفه دارد جنبه‌ های برنامه را در ورودی بگیرد و کد نهایی را با استفاده از آنها تولید کند. بافنده با تلفیق جنبه‌ها و کلاس‌ها، ساختاری جدید به نام کلاس‌های بافته شده تولید می‌کند. استفاده این ابزار در مرحله پیش از کامپایل می‌باشد.

دستورهای داده شده به بافنده‌ها صوابدید نام دارند. این صوابدیدها با استفاده از ترکیبی از نقاط پیوست تعریف می‌شوند که تعیین می‌کنند کدام توابع باید توسط کد جنبه‌ها تکمیل شود. شیوهٔ دقیق تکمیل این توابع به خود جوانب برمیگردد. با این کار بافنده‌ها ابزاری ارزشمند برای ارتقای پودمانی هستند.

انگیزه 
زبان‌های متعدد جنبه گرا وجود دارد که شناخته شده باشند اما انگیزه کافی برای طراحی و ساخت زبان‌های جنبه گرای جدید به علل اقتصادی وجود ندارد.  استفاده از تکنولوژی کاملاً متفاوت نیاز به این دارد که شرکت‌ها برنامه نویسان جدید استخدام کنند، زنجیره ابزار های متفاوتی برای توسعه تهیه کنند و همچنین کدهای قبلی خود را رها کنند که همگی خرج‌های زیادی دربردارد.

برای حل این معضلات در کنار داشتن برنامه‌نویسی جنبه گرا بافنده‌ها به ما این اجازه را می‌دهند که با اندکی تعمیم مانند AspectJ از زبان پرکاربردی مانند جاوا استفاده کنیم. بجای طراحی یک زبان کاملاً جدید، بافنده پسوندهای تعریف شده توسط AspectJ را تفسیر می‌کند و کد جاوا را «می بافد» تا بتواند توسط هر جاوا کامپایلری استفاده شود. این تضمین می‌کند که هر کد شی گرا موجود، یک کد معتبر جنبه گرا نیز باشد و توسعه مانند روال عادی توسعه شیء گرا انجام شود. مثالی دیگر از اینگونه تعمیمات زبان ++AspectC است که تعمیمی جنبه گرا برای زبان ++C می‌باشد.

پیاده‌سازی 
همانطور که گفته شد، کار بافنده این است که با گرفتن دستورالعمل‌هایی از جنبه برنامه (همان صوابدید)، به صورت خودکار این دستورالعمل‌ها را در بین کلاس‌های موجود اعمال کند. در نتیجه کلاس‌هایی خواهیم داشت همنام کلاس‌های اصلی برنامه، اما با کدی متفاوت برای توابع. محل اضافه شدن این دستورالعمل‌ها توسط صوابدید تعیین می‌شود.

در طی این عملیات بافنده‌ها اجازه اضافه‌شدن کدهایی را به برنامه می‌دهند که در غیر اینصورت به صورت اضافی در برنامه قرار می‌گرفتند. در نتیجه دیگر نیازی به دخالت برنامه‌نویس در پخش این کدها نیست.

مثال 
در کد AspectJ زیر، نقاط پیوست و کد کلاس شده جنبه، در قالبی شبیه کلاس جاوا پیاده شده‌اند. وظیفه بافنده این است که تنها یک کلاس در انتها تولید کند که جنبه تعریف شده را در خود اعمال کرده باشد.

مثال زده شده، قصد لاگ اندازی ورود به توابع را دارد. بدون وجود بافنده، برنامه‌نویس باید به صورت دستی تمام این لاگ‌ها را در توابع مورد نیاز قرار می‌داد، که مشخصا در یک برنامه‌ی واقعی امری به مراتب زمانگیر و کلافه‌کننده است. در هر تابع، با توجه به صوابدید کدی مختص آن تابع تولید می‌شود.

برای افزایش کارایی کد، می‌توان آن را مستقیماً تبدیل به bytecode کرد، در واقع بافنده در نقش کامپایلر نیز عمل می‌کند. اما کار بافنده در این حالت پیچیده‌تر و زمانگیرتر می‌شود طبق انتظار.aspect Logging {
    pointcut method() : execution(* *(..));
    before() : method() {
        System.out.println("Entering " + 
            thisJoinPoint.getSignature().toString());
    }
}
public class C {
    public void first() {
        System.out.println("Executing C.first()");
    }
    public void second() {
        System.out.println("Executing C.second()");
    }
}کد AspectJ بالا تبدیل به کد جاوای پایین می‌شود:public class C {
    public void first() {
        System.out.println("Entering C.first()");
        System.out.println("Executing C.first()");
    }
    public void second() {
        System.out.println("Entering C.second()");
        System.out.println("Executing C.second()");
    }
}

کارایی 
عملکرد زمان کامپایل با استفاده بافنده‌ها به دلیل کار اضافی لازم برای پیدا کردن توابع مطابق با نقاط پیوست، به طور کلی از کامپایلر های سنتی معادل آنها بدتر است. یک مطالعه نشان داد که کامپایلر ajc که برای زبان AspectJ هست، حدود ۳۴٪ کندتر از کامپایلر Java 1.3 و حدود ۶۲٪ کندتر از کامپایلر جاوا ۱.۴ است.

منابع 

 
 
 
 
 
 
 
 
 
 
 
 
 
 

برنامه‌نویسی جنبه‌گرا
پیاده‌سازی زبان برنامه‌نویسی
توسعه نرم‌افزار جنبه‌گرا
کامپایلرسازی