بایگانی ماهیانه: مرداد ۱۳۹۳

از کلاسهای concrete (پایین دست) برای پاس دادن پارامتر استفاده نکنید!

یکی از بدیهات برنامه نویسی شی گرا پاس دادن یک نوع کلاس بین کلاس ها میباشد که معمولاً دیده میشه برنامه نویسان بدون آینده نگری کلاسی که نیاز دارند رو دقیقاً همون رو پاس میدهند برای روشنتر شدن قضیه به شبه کد زیر توجه کنید :

class TestActivity extends Activity { ……..}

class Test {

public Test(TestActivity ta){}

}

در اینجا کلاس Test بعنوان مصرف کننده کلاس TestActivity فقط و فقط میتواند کلاس TestActivity را بعنوان ورودی بگیرد، حال میتوان حالتی را در نظر گرفت که کلاس Test میخواهد کارآیی خود را افرایش داده و همه نوع کلاسهایی که از جنس Activity هستند را در بر بگیرد در این حالت باید دست به جراحی عمده در کلاس Test بزنیم و هرکجا از TestActivity استفاده برده ایم آنرا تغییر به کلاس بالاتر خود یعنی Activity دهیم.

این کار شاید در برخی مواقعی بعنوان technical debt قابل قبول باشد اما بصورت کلی این نوع کار کرد به هیچ عنوان حتی بصورت چابک (در این حالت بخوانید عجله ایی) هم توصیه نمیشود و حتماً باید از کلاس بالاتر و یا interface مخصوص به کلاس استفاده برد.

مثال دنیای واقعی :

 

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import android.widget.TextView;

import com.github.praytimes.Clock;
import com.github.praytimes.Coordinate;
import com.github.praytimes.PrayTime;
import com.github.praytimes.PrayTimesCalculator;

import cal.Main_Calendar;

/**
* Pray time helper. It is like an aspect for activity class somehow
*
* @author ebraminio
*/
public class PrayTimeActivityHelper {
private final Utils utils;

private final Main_Calendar calendarActivity;
private Date date = new Date();
private final TextView prayTimeTextView;

public PrayTimeActivityHelper(Main_Calendar calendarActivity) {
this.calendarActivity = calendarActivity;
this.utils = calendarActivity.utils;
prayTimeTextView = (TextView) calendarActivity
.findViewById(R.id.today_praytimes);
}

public void setDate(int year, int month, int dayOfMonth) {
Calendar c = Calendar.getInstance();
c.set(year, month, dayOfMonth);
date = c.getTime();
}

public static Map<PrayTime,Clock> prayTimeClockMap = new HashMap<PrayTime, Clock>();
public String getPrayTime(PrayTime pt)
{
Coordinate coord = utils.getCoordinate(calendarActivity);
PrayTimesCalculator ptc = new PrayTimesCalculator(
utils.getCalculationMethod(calendarActivity));
Map<PrayTime, Clock> prayTimes = ptc.calculate(date, coord);
prayTimeClockMap = prayTimes;
char[] digits = utils.preferredDigits(calendarActivity);
switch (pt)
{
case Imsak:
return utils.clockToString(prayTimes.get(PrayTime.Imsak), digits);
case Sunrise:
return utils.clockToString(prayTimes.get(PrayTime.Sunrise), digits);
case Dhuhr:
return utils.clockToString(prayTimes.get(PrayTime.Dhuhr), digits);
case Sunset:
return utils.clockToString(prayTimes.get(PrayTime.Sunset), digits);
case Maghrib:
return utils.clockToString(prayTimes.get(PrayTime.Maghrib), digits);
case Midnight:
return utils.clockToString(prayTimes.get(PrayTime.Midnight), digits);
default:
return “”;
}
}

منبع  سورس بالا :

https://github.com/ebraminio/DroidPersianCalendar/blob/master/PersianCalendar/src/main/java/com/byagowi/persiancalendar/PrayTimeActivityHelper.java

(خدایا چقدر باید refactor کرد حتی کدهای خوب رو!!!)