
الگوی طراحـــــــــی Fly Weight
الگوی طراحی Adapter یکی از الگوهای ساختاری (Structural Patterns) است که هدف آن اتصال دو رابط (interface) یا کلاس با ساختار متفاوت به یکدیگر است. این الگو به ما امکان میدهد یک کلاس یا رابط موجود را به یک کلاس یا رابط دیگر تبدیل کنیم بدون اینکه نیاز به تغییر کد منبع یا رابطها باشد. این کاربرد الگوی Adapter به ما اجازه میدهد تا با یک انتقال نرمال و قابل استفاده کار کنیم و کد تکراری را کاهش دهیم.
برای درک بهتر این الگو، با یک مثال ملموس و کاربردی در دنیای واقعی آشنا میشویم:
فرض کنید ما یک برنامهی ویدیوپلیر داریم که از یک رابط به نام `IMediaPlayer` برای پخش فایلهای ویدیویی استفاده میکند. حالا ما میخواهیم این برنامه قابلیت پخش فایلهای صوتی (مثلاً فرمت MP3) را هم داشته باشد، اما `IMediaPlayer` فقط مخصوص پخش ویدیو است و قابلیت پخش فایلهای صوتی را ندارد.
برای حل این مشکل و استفاده از کد موجود در برنامه، میتوانیم از الگوی Adapter استفاده کنیم. برای این منظور، یک Adapter به نام `AudioPlayerAdapter` ایجاد میکنیم که از `IMediaPlayer` ارثبری میکند و قابلیت پخش فایلهای صوتی را به آن اضافه میکنیم. این Adapter وظیفه تبدیل درخواستهای مرتبط با پخش فایلهای صوتی به فرمتهای قابل قبول توسط `IMediaPlayer` را دارد.
حالا بیایید کد مربوط به این مثال را در زبان سی شارپ بنویسیم:
1. Target (هدف): اینجا `IMediaPlayer` رابط است که برنامه ویدیوپلیر از آن استفاده میکند.
1public interface IMediaPlayer
2{
3 void PlayVideo(string fileName);
4}
2. Adaptee (درونیاب): اینجا کلاس `VideoPlayer` موجود است که `IMediaPlayer` را پیادهسازی میکند و مخصوص پخش فایلهای ویدیویی است.
1public class VideoPlayer : IMediaPlayer
2{
3 public void PlayVideo(string fileName)
4 {
5 Console.WriteLine("Playing video: " + fileName);
6 }
7}
3. Adapter (آداپتر): اینجا کلاس `AudioPlayerAdapter` ایجاد میکنیم که از `IMediaPlayer` ارثبری میکند و قابلیت پخش فایلهای صوتی را به آن اضافه میکند
1public class AudioPlayerAdapter : IMediaPlayer
2{
3 private AudioPlayer audioPlayer;
4
5 public AudioPlayerAdapter()
6 {
7 audioPlayer = new AudioPlayer();
8 }
9
10 public void PlayVideo(string fileName)
11 {
12 // اینجا از AudioPlayer استفاده میکنیم تا فایل صوتی را پخش کنیم
13 audioPlayer.PlayAudio(fileName);
14 }
15}
4. Client (کلاینت): اینجا برنامهی ویدیوپلیر را با توجه به الگوی Adapter ایجاد میکنیم و قابلیت پخش فایلهای صوتی را هم دارا میشود.
1public class VideoPlayerApp
2{
3 private IMediaPlayer player;
4
5 public VideoPlayerApp(IMediaPlayer player)
6 {
7 this.player = player;
8 }
9
10 public void PlayMedia(string fileName)
11 {
12 player.PlayVideo(fileName);
13 }
14}
15
16public class Program
17{
18 public static void Main()
19 {
20 IMediaPlayer videoPlayer = new VideoPlayer();
21 VideoPlayerApp videoApp = new VideoPlayerApp(videoPlayer);
22 videoApp.PlayMedia("movie.mp4");
23
24 IMediaPlayer audioPlayer = new AudioPlayerAdapter();
25 VideoPlayerApp audioApp = new VideoPlayerApp(audioPlayer);
26 audioApp.PlayMedia("song.mp3");
27 }
28}
خروجی برنامه به صورت زیر خواهد بود:
Playing video: movie.mp4
Playing audio: song.mp3
در این مثال، با استفاده از الگوی Adapter، توانستیم کلاس VideoPlayer که فقط برای پخش ویدیو طراحی شده بود، را به یک Adapter تبدیل کنیم که اکنون قابلیت پخش فایلهای صوتی را هم دارد. با این کار، تغییراتی در کد موجود نداشتهایم و تنها با ایجاد Adapter جدید، قابلیت پخش فایلهای صوتی را به برنامه اضافه کردیم. این الگو به ما امکان استفاده از کلاسها و رابطهای موجود را در ساختارهای دیگر بدون نیاز به تغییر آنها میدهد.