لوگوی سایت دانیجت
سبد خرید0

سبد خرید

0

هیچ محصولی در سبد خرید نیست.

Design pattern هایی که هر برنامه نویس اندروید باید بداند

زمان مورد نیاز برای مطالعه : 8 دقیقه

در این مقاله شش Design pattern یا الگوی طراحی به شما معرفی میشود که هر برنامه نویس اندرویدی باید بداند زیرا که تاثیر بسیار مهمی بر روی تمیزی و کارایی کد شما دارد.

Design Pattern چیست ؟

یک design pattern یک راه حل تکرارپذیر برای یک مشکل مهندسی نرم افزار است. بر خلاف اکثر راه حل های خاص برنامه، design pattern ها  در بسیاری از برنامه ها استفاده می شود. design pattern ها به عنوان محصولات نهایی در نظر گرفته نمی شوند. در عوض، آنها الگوهایی هستند که می توانند در موقعیت های مختلف اعمال شوند و می توانند در طول زمان بهبود یابند و یک ابزار مهندسی نرم افزار بسیار قوی را ایجاد کنند. از آنجا که سرعت توسعه هنگام استفاده از یک نمونه اولیه اثبات شده افزایش می یابد، توسعه دهندگان با استفاده از design pattern ها می توانند کارایی کدنویسی و خوانایی محصول نهایی را بهبود بخشند.

نکته : هدف این مقاله معرفی Design Pattern های مهم و توضیح مختصری از عملکرد آنها میباشد و توضیح کامل آن ها در این مقاله میسر نیست.بعد از اینکه با این پترن ها آشنا شدید حتما در مورد آنها سرچ و تحقیق کنید تا عمیقا اونها رو درک کنید.

 

Pattern #1  Singleton

Singleton کلاسی است که اجازه می دهد تنها یک نمونه(instance) از خودش ایجاد شود و به آن نمونه ایجاد شده دسترسی پیدا کند. Singleton شامل متغیرهای ثابت است که می تواند نمونه های منحصر به فرد و خصوصی خود را در خود جای دهد. در سناریوهایی استفاده می شود که کاربر بخواهد نمونه سازی(instantiation ) یک کلاس را فقط به یک شی محدود کند. این معمولا زمانی مفید است که یک single object برای هماهنگ کردن اقدامات(coordinate actions) در سراسر یک سیستم مورد نیاز باشد.

قوانین ساخت کلاس Singleton

برای ساختن کلاس Singleton قوانین زیر رعایت می شود:

۱.یک سازنده خصوصی(A private constructor)

۲.مرجع ایستا از کلاس خود(A static reference of its class)

۳.یک متد استاتیک(One static method)

۴.مرجع شی در دسترس گلوبال(Globally accessible object reference)

۵.سازگاری در چندین ترد یا رشته (Consistency across multiple threads)

 

مثال از Singleton

نمونه در کلاس java :

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
        
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

 

نمونه در کلاس Kotlin :

Object Singleton { 
    init {
        println("Hello Singleton")
    }
}

 

Pattern #2  Factory

همانطور که از نام آن پیداست، Factory از تمام منطق ایجاد شی مراقبت می کند. در این الگو، یک کلاس Factory  کنترل می کند که کدام شی باید نمونه سازی شود. الگوی Factory  هنگام برخورد با بسیاری از اشیاء رایج مفید است. شما می توانید از آن در جایی استفاده کنید که ممکن است نخواهید یک کلاس را مشخص کنید.

برای درک بهتر مطلب به کد زیر دقت کنید تا به نحوه کار با پترن Factory آشنا شوید :

interface Currency {
    fun symbol(): String
    fun code(): String
}

enum class Country {
    UnitedState, Spain
}

class USDollar : Currency {
    override fun symbol(): String {
        return "$"
    }

    override fun code(): String {
        return "USD"
    }
}

class Euro : Currency {
    override fun symbol(): String {
        return "€"
    }

    override fun code(): String {
        return "EUR"
    }
}

object CurrencyFactory {

    fun currency(country: Country): Currency {
        return when (country) {
            Country.UnitedState -> {
                USDollar()
            }
            Country.Spain -> {
                Euro()
            }
        }
    }
}

Pattern #3  Builder

هدف الگوی سازنده(Builder) این است که “ساخت یک شی پیچیده را از نمایش آن جدا کند تا فرآیند construction یکسان بتواند بازنمایی های متفاوتی ایجاد کند.” برای ساختن یک شی پیچیده گام به گام استفاده می شود و مرحله نهایی آن شی را برمی گرداند.

 نمونه اون رو هنگام ساخت Alert Dialog دیدید که قدم به قدم از شما اطلاعات شی رو دریافت میکنه و در انتها شی مورد نظر رو برای شما میسازه.

قوانین ساخت Builder :

۱.کانستراکتور خصوصی (A private constructor)

۲.یک کلاس داخلی که معمولاً Builder نامیده می شود.

۳.تابع برای هر Field به منظور تنظیم مقدار بازگشتی Field

۴.نمونه بازگشتی ساخت تابع از کلاس main

با خواندن مثال زیر کاملا متوجه طریقه استفاده Builder  آشنا میشید :

class Hamburger private constructor(
    val cheese: Boolean,
    val beef: Boolean,
    val onions: Boolean
) {
    class Builder {
        private var cheese: Boolean = true
        private var beef: Boolean = true
        private var onions: Boolean = true

        fun cheese(value: Boolean) = apply { cheese = value }
        fun beef(value: Boolean) = apply { beef = value }
        fun onions(value: Boolean) = apply { onions = value }

        fun build() = Hamburger(cheese, beef, onions)
    }
}

Pattern #4  Facade

الگوی Facade یک رابط(interface) سطح بالاتری را ارائه می دهد که استفاده از مجموعه ای از رابط های دیگر را آسان تر می کند. کد زیر زیر این ایده را بیشتر نشان می دهد.

interface BooksApi {
  @GET("books")
  fun listBooks(): Call<List<Book>>
}

 

Square’s Retrofit یک کتابخانه اندروید منبع باز(open source) است که به شما کمک می کند الگوی facade را پیاده سازی کنید. شما یک اینترفیس ایجاد می کنید تا داده های API را به کلاینت ارائه دهید.

Pattern #5  Dependency Injection

تزریق وابستگی مانند نقل مکان به یک آپارتمان مبله است. هر چیزی که نیاز دارید از قبل وجود دارد. لازم نیست منتظر تحویل مبلمان باشید یا صفحات دستورالعمل های سایت دکوراسیون IKEA را دنبال کنید تا آن را جمع و خرید کنید.

در اصطلاح نرم افزاری، تزریق وابستگی به شما امکان می دهد هر object مورد نیاز را برای نمونه سازی یک object جدید ارائه دهید. این object جدید نیازی به ساخت یا سفارشی سازی خود object ها ندارد.

در Android، ممکن است متوجه شوید که باید از نقاط مختلف برنامه خود به همان object های پیچیده دسترسی داشته باشید، مانند network client، image loader یا SharedPreferences برای ذخیره سازی محلی. شما می توانید این object ها را به اکتیویتی ها و فرگمنت های خود تزریق کنید و بلافاصله به آنها دسترسی داشته باشید.

در اینجا یک مثالی آورده ایم. بدون تزریق وابستگی

 نمایش خودرویی که وابستگی موتور خود را در کد ایجاد می‌کند به این صورت است:

class Car {

    private val engine = Engine()

    fun start() {
        engine.start()
    }
}

fun main(args: Array) {
    val car = Car()
    car.start()
}

 

این نمونه ای از تزریق وابستگی نیست چون که کلاس Car در حال ساخت موتور خود است. این کار می تواند مشکل ساز باشد.

کد با تزریق وابستگی چگونه به نظر می رسد؟ به جای اینکه هر نمونه از Car شی Engine خود را در مقدار دهی اولیه بسازد، یک شی Engine را به عنوان پارامتر در سازنده خود دریافت می کند:

به کد زیر دقت کنید :

class Car(private val engine: Engine) {
    fun start() {
        engine.start()
    }
}

fun main(args: Array) {
    val engine = Engine()
    val car = Car(engine)
    car.start()
}

Pattern #6  Adapter

الگوی adapter به عنوان پلی بین دو interface ناسازگار عمل می کند.

این الگو شامل یک کلاس واحد(single class) است که مسئول پیوستن به عملکردهای(functionalities ) اینترفیس های  مستقل یا ناسازگار است. یک مثال واقعی می تواند یک رم ریدر(card reader) باشد که به عنوان آداپتور بین کارت حافظه و لپ تاپ عمل می کند. کارت حافظه را به رم ریدر و سپس رم ریدر را به لپ تاپ وصل می کنید تا کارت حافظه از طریق لپ تاپ قابل خواندن باشد.

توضیح کامل این Pattern رو میتوانید در اینجا مطالعه کنید.

جمع بندی

شاید مطالب بالا کمی نا مفهوم باشه اما اصلا نگران نباشید.با تحقیق و دیدن کلیپ های آموزشی و همچنین در یوتیوب شما کامل میتونید عملکرد هر Design Pattern رو درک کنید.

موفق و پیروز باشید

 

منبع : Medium.com

دیدگاه

2 نظر تاکنون ارسال شده است
  1. سایت خوب با مقالاتی بسیار بی نظیری دارین