Kami memiliki fungsi API yang memecah jumlah total menjadi jumlah bulanan berdasarkan tanggal mulai dan berakhir yang diberikan.
// JavaScript
function convertToMonths(timePeriod) {
// ... returns the given time period converted to months
}
function getPaymentBreakdown(total, startDate, endDate) {
const numMonths = convertToMonths(endDate - startDate);
return {
numMonths,
monthlyPayment: total / numMonths,
};
}
Baru-baru ini, konsumen untuk API ini ingin menentukan rentang tanggal dengan cara lain: 1) dengan memberikan jumlah bulan alih-alih tanggal akhir, atau 2) dengan memberikan pembayaran bulanan dan menghitung tanggal akhir. Menanggapi hal ini, tim API mengubah fungsi menjadi sebagai berikut:
// JavaScript
function addMonths(date, numMonths) {
// ... returns a new date numMonths after date
}
function getPaymentBreakdown(
total,
startDate,
endDate /* optional */,
numMonths /* optional */,
monthlyPayment /* optional */,
) {
let innerNumMonths;
if (monthlyPayment) {
innerNumMonths = total / monthlyPayment;
} else if (numMonths) {
innerNumMonths = numMonths;
} else {
innerNumMonths = convertToMonths(endDate - startDate);
}
return {
numMonths: innerNumMonths,
monthlyPayment: total / innerNumMonths,
endDate: addMonths(startDate, innerNumMonths),
};
}
Saya merasa perubahan ini menyulitkan API. Sekarang penelepon perlu khawatir tentang heuristik yang tersembunyi dengan pelaksanaan fungsi dalam menentukan parameter mengambil preferensi dalam yang digunakan untuk menghitung rentang tanggal (yaitu dengan urutan prioritas monthlyPayment
, numMonths
, endDate
). Jika seorang penelepon tidak memperhatikan tanda tangan fungsi, mereka mungkin mengirim beberapa parameter opsional dan bingung mengapa endDate
diabaikan. Kami menentukan perilaku ini dalam dokumentasi fungsi.
Selain itu saya merasa itu menetapkan preseden buruk dan menambahkan tanggung jawab ke API yang seharusnya tidak menjadi perhatiannya (yaitu melanggar SRP). Misalkan konsumen menginginkan fungsi untuk mendukung lebih banyak kasus penggunaan, seperti menghitung total
dari numMonths
dan monthlyPayment
parameter. Fungsi ini akan menjadi semakin rumit dari waktu ke waktu.
Preferensi saya adalah untuk menjaga fungsinya seperti semula dan sebaliknya meminta penelepon untuk menghitung endDate
sendiri. Namun, saya mungkin salah dan bertanya-tanya apakah perubahan yang mereka lakukan merupakan cara yang dapat diterima untuk merancang fungsi API.
Atau, apakah ada pola umum untuk menangani skenario seperti ini? Kami dapat menyediakan fungsi tingkat tinggi tambahan di API kami yang membungkus fungsi asli, tetapi ini membengkak API. Mungkin kita bisa menambahkan parameter flag tambahan yang menentukan pendekatan mana yang akan digunakan di dalam fungsi.
Date
- Anda dapat menyediakan string dan dapat diurai untuk menentukan tanggal. Namun, cara ini oh menangani parameter juga bisa sangat rewel dan mungkin menghasilkan hasil yang tidak dapat diandalkan. Lihat Date
lagi. Ini tidak mungkin dilakukan dengan benar - Momen menanganinya dengan lebih baik tetapi sangat menjengkelkan untuk digunakan.
monthlyPayment
diberikan tetapi total
bukan kelipatan bilangan bulat dari itu. Dan juga bagaimana menghadapi kemungkinan kesalahan roundoff floating point jika nilainya tidak dijamin bilangan bulat (mis. Coba dengan total = 0.3
dan monthlyPayment = 0.1
).