جداسازی در جاوا – انجمن DEV

جداسازی در برنامه نویسی به معنای کاهش وابستگی متقابل بین اجزا یا ماژول های مختلف یک سیستم نرم افزاری است. همه چیز در مورد ایجاد مؤلفه هایی است که مستقل هستند و می توانند در جای دیگری با حداقل تغییرات مورد استفاده قرار گیرند و به طور مستقل قابل آزمایش و نگهداری باشند.
با کاهش وابستگی متقابل، جداسازی به توسعهدهندگان اجازه میدهد تا سیستمهای نرمافزاری ایجاد کنند که انعطافپذیرتر، مقیاسپذیرتر و نگهداری آسانتر باشد.
در عمل این بدان معناست که اجزاء را میتوان بدون تأثیرگذاری بر سایر قسمتهای سیستم، بهروزرسانی، جایگزین یا حذف کرد، و حفظ کل سیستم را آسانتر میکند.
تکنیک ها و الگوهای طراحی برای دستیابی به جداسازی در جاوا در سطح کد
-
تزریق وابستگی (DI): تزریق وابستگی تکنیکی است که در آن وابستگی های یک کلاس از طریق یک رابط یا سازنده تزریق می شود. به این ترتیب، یک کلاس از اجرای واقعی وابستگی های خود بی اطلاع است.
-
الگوی مشاهده گر: الگوی Observer یک الگوی طراحی است که در آن یک شی موضوع، ناظران خود را از تغییراتی که متحمل می شود مطلع می کند.
-
الگوی آداپتور: الگوی Adapter یک الگوی طراحی است که امکان تبدیل رابط یک کلاس به رابط دیگر مناسب برای کلاینت را فراهم می کند.
-
الگوی نما: الگوی طراحی نما الگویی است که یک رابط عمومی ساده و منفرد را ارائه می دهد که می تواند با پنهان کردن پیچیدگی آن برای دسترسی به یک سیستم پیچیده از کلاس ها استفاده شود.
-
الگوی مکان یاب خدمات: الگوی Service Locator الگویی است که یک رجیستری متمرکز به نام سرویس یاب ارائه می دهد که به مشتریان اجازه می دهد خدمات مورد نیاز خود را با درخواست از طریق یاب سرویس بازیابی کنند.
-
الگوی فرمان: الگوی فرمان یک الگوی طراحی است که در آن یک شی برای نشان دادن و کپسوله کردن تمام اطلاعات مورد نیاز برای فراخوانی یک متد در زمان بعدی استفاده می شود.
-
الگوی کارخانه: الگوی Factory الگویی است که رابطی را برای ایجاد اشیاء در یک سوپرکلاس فراهم می کند، اما به کلاس های فرعی اجازه می دهد تا نوع اشیاء ایجاد شده را تغییر دهند.
در این پست قصد داریم نمونه هایی از جداسازی با استفاده از Dependency Injection و سپس الگوی نما را مشاهده کنیم.
مثال در جاوا با استفاده از تزریق وابستگی (DI) برای دستیابی به جداسازی
من جداسازی را با استفاده از تکنیک نشان می دهم تزریق وابستگی. ما قصد داریم یک کلاس را با جدا کردن استفاده از یک شی از ایجاد آن، مستقل از وابستگی های آن کنیم.
فرض کنید ماشینی داریم که به موتور وابستگی دارد. به جای ایجاد نمونه ای از کلاس موتور در کلاس خودرو، کلاس Engine را به عنوان یک وابستگی با استفاده از سازنده تزریق می کنیم.
public interface Engine {
void start();
void stop();
}
public class Car {
private Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
public void start() {
engine.start();
}
public void stop() {
engine.stop();
}
}
این باعث می شود ماشین کلاس مستقل از اجرای خاصی از موتور.
ما می توانیم پیاده سازی های مختلفی از رابط موتور ایجاد کنیم، مانند موتور بنزینی یا موتور الکتریکی
public class Main {
public static void main(String[] args) {
Engine engine = new GasolineEngine(); // create an instance of GasolineEngine
Car car = new Car(engine); // inject the GasolineEngine into the Car
car.start(); // start the car
car.stop(); // stop the car
}
}
این نشان می دهد که چگونه جداسازی می تواند به ما کمک کند تا اجزای قابل تعویضی بسازیم که می توانند بدون تأثیر بر بقیه کد مورد استفاده قرار گیرند.
مثال در جاوا با استفاده از Facade Pattern برای دستیابی به جداسازی
بیایید ببینیم چگونه الگوی نما می توان از آن برای جداسازی کد استفاده کرد.
ما یک برنامه کاربردی داریم که از کتابخانه های شخص ثالث استفاده می کند، و آنها در همه جا هستند، بنابراین برنامه با این کتابخانه ها همراه است. مثلا داریم
public int f(int x) {
Y y = new Y(x);
return y.someCalculations();
}
جایی که Y یک کلاس از شخص 3 است.
راه حل
ما از الگوی نما استفاده میکنیم تا کلاس کتابخانه شخص ثالث را در رابط/کلاسی که میخواهم در معرض برنامه قرار دهم، قرار دهیم.
بنابراین وقتی کتابخانه تغییر می کند، ما فقط باید کتاب خود را بازنویسی کنیم MyFacadeClass
public class MyFacadeClass {
private Y y = new Y();
public int someCalculations(int myParam){
y.someCalculations(myParam);
}
}
توجه: نما و آداپتور الگوهای طراحی بسیار مشابهی هستند، تفاوت اصلی این است که نما مدل دامنه زیرسیستم دیگر را تغییر نمی دهد، در حالی که آداپتور این کار را می کند. به همین دلیل است که من از Facade در اینجا استفاده می کنم.
این نشان میدهد که چگونه جداسازی میتواند به ما کمک کند از کتابخانههای شخص ثالث استفاده کنیم، بدون اینکه آنها را به کد خود متصل کنیم.
تصویر بزرگتر
اگر رابط کاربری و پایگاه داده به طور محکم با یکدیگر همراه باشند، تغییر در یکی احتمالاً نیازمند تغییرات در دیگری است. با این حال، با جدا کردن رابط کاربری و پایگاه داده، می توان هر یک را مستقل از دیگری تغییر داد، بنابراین می توانیم تغییر رابط کاربری را بدون تأثیر بر پایگاه داده یا تعویض پایگاه داده بدون تغییر رابط کاربری امکان پذیر کنیم.
اگر درخواست تغییر شامل تغییراتی در UI و DB باشد چه؟
هنگامی که تغییری مورد نیاز است، مانند افزودن یک فیلد جدید، لایه API باید به روز شود تا بتواند آن را مدیریت کند، همچنین لایه UI باید آن را نمایش دهد. لایه پایگاه داده را که باید داده ها را در آن ذخیره کنیم فراموش نکنید.
در این سناریو، جداسازی همچنان میتواند سودمند باشد، حتی اگر نیاز به تغییرات را به طور کامل از بین نبرد، زیرا تغییرات میتوانند به طور مستقل در لایههای مربوطه ایجاد شوند و این باعث انعطافپذیری بیشتر سیستم میشود.
در آینده میتوانیم موقعیت یا ظاهر فیلد اضافهشده را در UI بدون تأثیرگذاری بر سایر بخشهای سیستم (پایگاه داده یا API) تغییر دهیم.
ما می بینیم که جداسازی کامل ممکن است همیشه امکان پذیر یا عملی نباشد، اما همچنان مزایایی را از نظر انعطاف پذیرتر کردن و نگهداری سیستم فراهم می کند. علاوه بر این، جداسازی میتواند به آزمایش کمک کند، زیرا هر جزء را میتوان مستقل از بقیه آزمایش کرد.
نتیجه گیری
جداسازی سیستم های نرم افزاری را با کاهش وابستگی بین اجزای مختلف انعطاف پذیرتر و نگهداری آسان تر می کند.