Apakah itu bau kode jika Anda sering membuat objek hanya untuk memanggil metode di atasnya

14

Saya mewarisi basis kode di mana ada banyak kode seperti ini:

SomeDataAdapter sda = new SomeDataAdapter();
sda.UpdateData(DataTable updateData);

Dan kemudian sda tidak pernah digunakan lagi.

Apakah itu bau kode yang menunjukkan bahwa metode-metode itu seharusnya benar-benar metode kelas statis?

Shane Wealti
sumber
Apakah kelas-kelas ini mengimplementasikan antarmuka apa pun?
Reactgular
7
Sehari setelah Anda refactor ke metode statis akan menjadi hari Anda ingin menjalankan tes unit dengan versi tiruan adaptor data Anda.
Mike
22
@ Mike: Mengapa Anda perlu mengejek metode statis? Saya sangat lelah dengan argumen keliru ini bahwa metode statis tidak dapat diuji. Jika metode statis Anda memegang keadaan atau membuat efek samping, itu adalah kesalahan Anda , bukan kesalahan metodologi pengujian Anda.
Robert Harvey
9
Menurut pendapat saya, ini adalah aroma bahasa yang menunjukkan kelemahan analisis "semuanya harus kelas".
Ben
7
@RobertHarvey: Anda mungkin perlu mengejek metode statis karena alasan yang sama Anda mengejek metode lain: terlalu mahal untuk memanggil selama pengujian unit.
kevin cline

Jawaban:

1

Saya akan menganggapnya sebagai bau arsitektur dalam UpdateData yang mungkin seharusnya milik kelas 'layanan'.

Di mana datanya adalah Apple. Di mana AppleAdapter adalah kelas layanan / bisnis-intelijen. Di mana AppleService adalah referensi Singleton ke AppleAdapter yang ada di luar metode saat ini.

private static volatile AppleAdapter _appleService = null;
private static object _appleServiceLock = new object();
private AppleAdapter AppleService
{
    get
    {
        if (_appleService == null)
        {
            lock (_appleServiceLock)
            {
                if (_appleService == null)
                    _appleService = new AppleAdapter();
            }
        }
        return _appleService;
    }
}

public SomeAppleRelatedMethod(Apple apple)
{
    AppleService.UpdateData(apple);
}

Saya tidak berpikir apa yang Anda lakukan itu salah, tetapi jika SomeDataAdapter memang mewakili semacam layanan bisnis tanpa kewarganegaraan, maka seorang singleton akan menjadi praktik terbaik untuk itu. Semoga itu bisa membantu! Contoh yang diberikan adalah cara mewah untuk memastikan tidak ada pertentangan dari _appleService jika kebetulan keduanya null dan diakses pada waktu yang sama persis oleh dua utas atau lebih.

Kamu tahu apa? Jika SomeDataAdapter adalah ADO IDbDataAdapter (yang hampir pasti), abaikan seluruh respons ini!

: P

Saya tidak memiliki izin untuk menambahkan komentar ke pertanyaan awal, tetapi jika Anda dapat menentukan di mana kode ini ada.

Jika kode ini mewakili implementasi kustom IDbDataAdapter, dan UpdateData membuat IDbConnection, IDbCommand, dan memasang semuanya di belakang layar, maka tidak, saya tidak akan menganggap kode itu berbau karena sekarang kita berbicara tentang stream dan lainnya hal-hal yang perlu dibuang ketika kita selesai menggunakannya.

Andrew Hoffman
sumber
12
Tolong! Saya tenggelam dalam pola perangkat lunak.
Robert Harvey
4
... atau disuntikkan sebagai ketergantungan. ;)
Rob
12
Bercak dengan lajang dan penguncian ganda untuk mendapatkan sesuatu yang setara dengan fungsi / prosedur sederhana adalah bau kode yang jauh lebih besar bagi saya!
Ben
3

Saya pikir masalah ini bahkan lebih dalam dari itu. Bahkan jika Anda melakukan refactor menjadi metode statis, maka Anda mendapatkan kode tempat Anda memanggil metode statis tunggal di semua tempat. Yang menurut saya adalah kode bau itu sendiri. Ini mungkin menunjukkan Anda kehilangan beberapa abstraksi penting. Mungkin Anda ingin membuat kode yang akan melakukan beberapa pra dan pasca pemrosesan sambil memungkinkan Anda untuk mengubah apa yang terjadi di antaranya. Pra dan pasca pemrosesan akan berisi panggilan umum sementara di antara keduanya akan tergantung pada implementasi konkret.

Euforia
sumber
Saya setuju ada masalah yang lebih dalam. Saya mencoba meningkatkannya secara bertahap tanpa mendesain ulang arsitektur penuh tetapi sepertinya apa yang saya pikirkan bukanlah cara yang baik untuk melakukannya.
Shane Wealti
1

Agak. Biasanya itu berarti Anda ingin melewati suatu fungsi dan bahasa pilihan Anda tidak akan membiarkan Anda. Agak canggung dan tidak sopan, tetapi jika Anda terjebak dalam bahasa tanpa fungsi kelas satu, tidak banyak yang bisa Anda lakukan.

Jika tidak ada objek yang diteruskan sebagai argumen ke fungsi lain, Anda bisa mengubahnya menjadi metode statis dan tidak ada yang akan berubah.

Doval
sumber
Ini juga bisa berarti bahwa Anda ingin metode statis untuk mengembalikan versi yang dimodifikasi (atau salinan yang dimodifikasi) dari objek yang Anda lewati.
Robert Harvey
2
"jika Anda terjebak dalam bahasa tanpa fungsi kelas" ": Tidak ada perbedaan antara objek dengan hanya satu metode dan fungsi kelas (atau penutupan kelas satu): Mereka hanya dua tampilan berbeda dari yang sama benda.
Giorgio
4
@Iorgio Secara teoritis, tidak. Dalam praktiknya, jika bahasa Anda setidaknya tidak memiliki gula sintaksis untuk itu, itu adalah perbedaan antara fn x => x + 1dan new Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }};atau membatasi diri Anda pada beberapa fungsi yang sulit dikodekan dan berguna secara sempit.
Doval
Mengapa tidak bisa fn x => x + 1menjadi gula sintaksis new Function<Integer, Integer>() { public Integer eval(Integer x) { return x + 1; }}? Oke, mungkin maksud Anda jika seseorang terjebak dalam bahasa tanpa jenis gula sintaksis ini.
Giorgio
@Iorgio Anda harus bertanya kepada Oracle. (Memang, itu akhirnya berubah dengan Java 8). Perhatikan bahwa Anda memerlukan lebih banyak sintaksis gula dari pada itu hanya agar benar-benar bermanfaat - Anda juga ingin dapat melewati metode yang telah dinyatakan sebelumnya dengan nama. Kari juga akan berguna. Pada titik tertentu Anda harus bertanya-tanya apakah layak memiliki semua peretasan itu alih-alih memperlakukan fungsi sebagai warga negara pertama. Tapi sekarang saya keluar topik.
Doval
0

Jika holding state membuat kelas yang diberikan lebih utilitarian, fungsional ... dapat digunakan kembali maka tidak. Untuk beberapa alasan, pola desain perintah muncul di pikiran; alasan itu tentu saja bukan keinginan untuk membuat Robert Harvey tenggelam.

radarbob
sumber
0

Tentukan "sering." Seberapa sering Anda membuat instance objek? Banyak - mungkin tidak?

Kemungkinan ada masalah yang lebih besar untuk dikhawatirkan di sistem Anda. Menjadi statis akan berkomunikasi lebih jelas kepada programmer bahwa keadaan internal objek tidak berubah - hebat.

Jika keadaan sedang kacau, dan Anda harus mulai membuat hal-hal lain statis untuk menjadikan hal pertama statis, maka Anda harus bertanya bagian mana yang harus statis dan bagian mana yang tidak.

Ya itu bau kode, hanya yang kecil.

pengguna1775944
sumber
0

Jadikan metode ini statis dan teruskan. Tidak ada yang salah dengan metode statis. Setelah pola penggunaan muncul, Anda bisa khawatir tentang abstrak pola.

davidk01
sumber
0

Bau di sini adalah bahwa ini adalah kode prosedural yang dibungkus (minimal) pada objek.

Pasti ada alasan mengapa Anda ingin melakukan operasi itu pada tabel data, tetapi alih-alih memodelkan operasi itu dengan operasi terkait lainnya yang berbagi beberapa semantik (yaitu memiliki makna yang sama), penulis hanya memutar prosedur baru di dalam yang baru kelas & menyebutnya.

Dalam bahasa fungsional, itulah cara Anda melakukan sesuatu;) tetapi dalam paradigma OO, Anda ingin memodelkan beberapa abstraksi yang menyertakan operasi itu. Kemudian Anda akan menggunakan teknik OO untuk menyempurnakan model itu dan menyediakan serangkaian operasi terkait yang mempertahankan beberapa semantik.

Jadi bau utama di sini adalah bahwa penulis menggunakan kelas, mungkin karena kompiler memerlukannya, tanpa mengatur operasi menjadi model konseptual.

BTW hati-hati kapan saja Anda melihat program dimodelkan dan bukannya ruang masalah . Ini pertanda bahwa desain bisa mendapat manfaat dari lebih banyak pemikiran. Dengan kata lain, hati-hati untuk semua kelas yang menjadi "xAdaptor" dan "xHandler" dan "xUtility", dan biasanya terkait dengan model domain anemia . Ini berarti seseorang hanya membundel kode untuk kenyamanan, bukan memodelkan konsep yang sebenarnya ingin mereka terapkan.

rampok
sumber