💻 آخرین فرصت یادگیری برنامه‌نویسی با آفر ویژه قبل از افزایش قیمت در ۵ آذر ماه (🎁 به همراه یک هدیه ارزشمند )
۰ ثانیه
۰ دقیقه
۰ ساعت
۳ محسن موحد
سبک‌های متفاوت کدنویسی برای پیاده سازی interface
جامعه جاوا (اندروید) ایجاد شده در ۱۸ فروردین ۱۳۹۹

سلام.

براساس ویدیوی این جلسه و مباحثی که تا الان یاد گرفتیم، میخوام چند روش برای پیاده سازی interface رو در کنار هم بیارم.

کلیت کلاس TaskDialog رو به شکل زیر در نظر میگیریم و روی همین کلاس کار میکنیم:

public class TaskDialog extends DialogFragment {
    // some fields come here
    private AddNewTaskCallback listener;
    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        // some codes come here
        // ...      
        builder.setView(view);
        return builder.create();
    }
    interface AddNewTaskCallback {
        void onNewTask();
    }
}

 

روش اول(پیاده سازی اینترفیس):

داخل کلاس TaskDialog یک constructor میسازیم و listener رو داخلش ست میکنیم.

// TaskDialog.java
public TaskDialog(AddNewTaskCallback listener) {
    this.listener = listener;
}

 

اینترفیس AddNewTaskCallback رو داخل کلاس MainActivity پیاده سازی میکنیم:

// MainActivity.java
public class MainActivity extends AppCompatActivity implements TaskDialog.AddNewTaskCallback {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TaskDialog dialog = new TaskDialog(this); // MainActivity.this
        dialog.show(getSupportFragmentManager(), null);
    }
    @Override
    public void onNewTask() {
        // ...
    }
}

اگر dialog در متد onClick ایجاد میشه، بجای this باید از MainActivity.this استفاده بشه.(چون this به listener کلیک اشاره میکنه.)

 

روش دوم:

مثل روش قبل همون constructor قبلی اومده:

// TaskDialog.java
public TaskDialog(AddNewTaskCallback listener) {
    this.listener = listener;
}

 

شیءای از AddNewTaskCallback رو بعنوان پارامتر constructor پیاده میکنیم:

// MainActivity.java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TaskDialog dialog = new TaskDialog(new TaskDialog.AddNewTaskCallback() {
                    @Override
                    public void onNewTask() {
                        // ...
                    }
                });
        dialog.show(getSupportFragmentManager(), null);
    }
}

 

روش سوم:

استفاده از setter برای پیاده سازی اینترفیس و مقدار دهی در کلاس TaskDialog:

// TaskDialog.java
public TaskDiaog setListener(AddNewTaskCallback listener) {
    this.listener = listener;
    return this;
}

TaskDialog بعنوان خروجی setter درنظر گرفتم تا از زنجیره ی متد استفاده کنم. میتونه خروجی void باشه و بصورت جدا setter رو call کنم.

میبینید که داخل setListener مقدار دهی شده:

// MainActivity.java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TaskDialog dialog = new TaskDialog()
                .setListener(new TaskDialog.AddNewTaskCallback() {
                    @Override
                    public void onNewTask() {
                        // ...
                    }
                });
        dialog.show(getSupportFragmentManager(), null);
    }
}

 

روش چهارم:

@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    listener = (AddNewTaskCallback) context;
}

شبیه روش اول، فقط اینجا this رو پاس نمیدیم:

// MainActivity.java
public class MainActivity extends AppCompatActivity implements TaskDialog.AddNewTaskCallback {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TaskDialog dialog = new TaskDialog();
        dialog.show(getSupportFragmentManager(), null);
    }
    @Override
    public void onNewTask() {
        // ...
    }
}

 

 

چند روش هم برای ارسال مقادیر به دیالوگ:

روش اول: روشی که استاد در ویدیوی این جلسه(پیاده سازی ویرایش) تدریس کردن(استفاده از parcelable)

روش دوم: پاس دادن مقادیر از طریق constructor یا ساخت متد setter.

روش سوم: ساخت کلاس اپلیکیشن:

کلاس App در تمام قسمت‌های اپلیکیشن قابل دسترسیست و باید نام کلاس در AndroidManifest و اتریبیوت android:name=".App"  تعریف شود.

فیلد currentTask تعریف شده:

// App.java
public class App extends Application {
    public static Task currentTask;
    @Override
    public void onCreate() {
        super.onCreate();
        // ...
    }
}

 

در کلاس TaskAdapter زمانیکه روی دکمه ی btnEdit کلیک شد، task مورد نظرو داخل فیلد currentTask از کلاس App میریزیم:

// TaskAdapter
findViewById(R.id.btnEdit).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        App.currentTask = task;
        // ...
    }
});

 

چون روی btnEdit کلیک شده، بنابراین براساس کدی که مینویسیم، EditTaskDialog ساخته میشه و میتونیم به currentTask جدید دسترسی داشته باشیم:

// EditTaskDialog.java
private Task task;
@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);
    task = App.currentTask;
}

 

محسن عزیز ممنونم بابت وقتی که گذاشتی چون این انگیزت قابل ستایشه 

 ایا میدونی بهترین روش کدوم هست؟

ایا این روش‌ها باعث پرفرومنس بهتر میشن یا صرفا برای خوانایی کد هست؟

پوریا شفیعی ۱۸ فروردین ۱۳۹۹، ۱۲:۰۹

سلام پوریا جان. مخلصم.

من فک میکنم همونطور که داخل عنوان نوشتم اینها سبک‌های متفاوتی از کدنویسی هست.

دو روشش که شبیه هم هستن و روش دوم، راهی واسه پیاده سازی سریع اینترفیس هست و روش setter رو میشه زمانیکه از زنجیره ی متدها استفاده کردیم بیاریم.(اگر بصورت زنجیره هم نبود فرقی نمیکنه)

من نظرم اینه در زمان کدنویسی با توجه به موقعیتی که وجود داره بهتر میتونیم تصمیم بگیریم از چه فرمی استفاده کنیم.

مثلا در روش دوم برای دسترسی به مقادیر بیرون از متد پیاده سازی شده، باید اون مقادیر Final بشن، شاید در اون موقعیت کد، اینکارو نشه کرد، بنابراین از روش دیگه استفاده میکنید.

 

در مورد ارسال مقادیر، فک میکنم روش استاد شاهینی(روش اول) مناسبتر باشه. توو کدهای مختلفیم که دیدم، از روش parcelable استفاده شده.

 

فک میکنم روش‌های مختلف برای پیاده سازیه یک مسئله، هضم اون مسئله رو راحتتر کنه.

محسن موحد ۱۸ فروردین ۱۳۹۹، ۱۲:۳۲

متن طولانی شد، بصورت پست قرارش میدم.(اولش قرار بود توو یه خط بنویسمش  :دی)

ازونجایی که زبان هایی که دارم کار میکنم، بهم ارتباط دارن، یادگیریشون کار زیاد سختی نیست. مثلا اگر ببینید، متخصص وب در کنار زبان سروری مثل PHP، زبان‌ها و تکنولوژی‌های متفاوتی رو هم یاد میگیره و مشکلی هم واسش ایجاد نمیشه.(مثل JS و HTML و CSS و چنتا دیتابیس و فریمورک‌های متفاوت و کار با سرور و وب سرور و کلی چیزه دیگه) یعنی اگه ذهن بتونه یادگیریه یک زبانو قبول کنه پس قطعا چند زبان دیگه رو هم میتونه یادبگیره.(هر زبان میره تو یه خونه از حافظه ی مغز :دی) فقط چون نیاز به تمرین هست و مغز برای هضم بعضی از مطالب جدید مقاومت میکنه، نیاز به زمان هست. برای مثال شاید اولین باری که توو آموزش‌ها با recycler view اشنا شدیم، این مسئله واسمون گنگ بود ولی توو همون قالب انقدر کد نوشتیم(حتی کپی پیست و جای گذاری کدها) که به مرور زمان دیدیم مطلب گنگی وجود نداره و به درک کامل این مسئله رسیدیم.(گذر زمان هم توو یادگیری تاثیر داره)

بنابراین سخته همزمان به چند زبان تسلط کامل پیدا کرد. بنظرم بهتره یک زبان رو base قرار داد و روی اون زمان بیشتری گذاشت و بقیه ی زبان‌ها و تکنولوژی‌های مختلفی که در ارتباط هستنو بصورت قالب کلی، حتی برای راه اندازی کار یادگرفت و پروژه پروژه و روبرو شدن با چالش‌های جدید به اون موارد هم تسلط پیدا کرد یا حتی در زمان‌های خالی میشه به اون مسائل هم پرداخت. مثلا متخصص اندروید میتونه این فریمورک رو base قرار بده و زبان PHP رو بصورت یک قالب کلی و جمو جور برای راه اندازی کارهای ارتباط با سرور یاد بگیره و در زمان مناسبتر یا چالش جدید به آموزه‌های PHP ایش شاخو برگ بده و ...

 

یک شیوه هم واسه تمرین از روی آموزش‌ها بگم.

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

محسن موحد ۱۹ فروردین ۱۳۹۹، ۱۴:۰۲