Tutorial Pasukan Lucee MY

Fungsi dan Komponen (CFC) dalam CFML

Belajar menulis fungsi dan membina komponen CFC dalam CFML: createObject, extends, pemetaan, dan amalan penamaan untuk kod yang kemas dan mudah diselenggara.

Fungsi dan Komponen (CFC) dalam CFML
0
Kandungan

Fungsi dan Komponen (CFC) dalam CFML

Penulis: Thalhah · Tarikh: 16 Oktober 2026

Fungsi dan komponen (CFC) ialah cara anda mengasingkan logik dalam CFML supaya kod boleh diguna semula, diuji, dan diselenggara. Artikel ini menunjukkan cara menulis fungsi, membina komponen, memetakannya, dan mewarisinya dengan extends, lengkap dengan amalan penamaan yang munasabah.

Fungsi dalam CFML: UDF berbanding fungsi bawaan

CFML datang dengan ratusan fungsi bawaan seperti len, structKeyExists, dan dateFormat yang sedia digunakan tanpa perlu anda takrifkan. Fungsi takrifan pengguna (UDF, user-defined function) pula ialah fungsi yang anda tulis sendiri untuk merangkum logik khusus projek anda.

Bezanya mudah: fungsi bawaan diurus oleh Lucee dan sentiasa tersedia dalam setiap permintaan, manakala UDF hidup dalam konteks tempat anda menulisnya, sama ada dalam satu halaman, dalam komponen, atau dalam Application.cfc. Apabila logik mula berulang di lebih satu tempat, itu isyarat untuk menulis UDF. Fungsi dalam CFML sentiasa mengembalikan nilai melalui return; jika tiada return dinyatakan, fungsi mengembalikan nilai kosong. Ini beza kecil tetapi penting apabila anda merangka API dalaman.

Dalam sintaks skrip, anda menulis fungsi dengan kata kunci function. Anda boleh menyatakan jenis data untuk parameter dan nilai pulangan, menetapkan nilai lalai, dan menanda parameter wajib dengan required.

numeric function tambah(required numeric a, required numeric b) {
    return a + b;
}

string function sapaan(required string nama, string gelaran = "") {
    return len(gelaran) ? "#gelaran# #nama#" : nama;
}

Fungsi juga boleh ditulis dalam sintaks tag menggunakan cffunction, tetapi sintaks skrip lebih ringkas dan menjadi pilihan kebanyakan pembangun moden. Baca perbandingan tag dan skrip untuk perincian.

CFML juga menyokong closure, iaitu fungsi tanpa nama yang boleh disimpan dalam pemboleh ubah dan dihantar sebagai hujah. Ini berguna untuk panggilan balik dalam fungsi seperti arrayMap dan arrayFilter.

Membina komponen (CFC)

Komponen, atau ColdFusion Component (CFC), ialah bekas yang menggabungkan fungsi (kaedah) dan data (property) dalam satu unit, setara dengan kelas dalam bahasa berorientasikan objek lain. Setiap komponen lazimnya disimpan dalam satu fail .cfc dengan nama fail sama seperti nama komponen.

component accessors="true" {

    property name="nama" type="string";

    public function init(required string nama) {
        variables.nama = arguments.nama;
        return this;
    }

    public string function perkenalkan() {
        return "Hai, saya #variables.nama#";
    }

}

Atribut accessors="true" memberitahu Lucee untuk menjana getter dan setter secara automatik bagi setiap property, jadi anda tidak perlu menulisnya dengan tangan. Komponen juga boleh mengandungi pseudo-constructor: sebarang kod di dalam badan komponen tetapi di luar fungsi akan dijalankan apabila tika dicipta. Gunakannya untuk menetapkan nilai lalai, tetapi elak meletakkan logik berat di situ.

Pengubah akses dan skop

Setiap kaedah komponen boleh ditanda dengan pengubah akses yang mengawal siapa boleh memanggilnya. public membolehkan panggilan dari mana-mana dan merupakan lalai. private mengehadkan panggilan kepada komponen yang sama. package membenarkan komponen dalam pakej yang sama. remote membolehkan kaedah dipanggil terus dari permintaan HTTP, berguna untuk AJAX dan API.

Dua skop penting dalam komponen ialah variables dan this. Pemboleh ubah dalam variables hanya kelihatan kepada kaedah dalam komponen itu sendiri, manakala this mendedahkan nilai kepada dunia luar. Kebanyakan kod dalaman anda patut duduk dalam variables supaya ia tidak bocor keluar.

component {

    variables.cache = {};  // peribadi kepada tika ini

    remote string function apiStatus() {
        return "ok";  // boleh dipanggil melalui HTTP
    }

    private function bersihkanCache() {
        variables.cache.clear();
    }

}

Mengasingkan kod: mengapa komponen

Komponen membantu anda mengasingkan kebimbangan. Logik pangkalan data masuk ke satu komponen, logik perniagaan ke komponen lain, dan logik paparan kekal dalam fail .cfm. Hasilnya kod yang lebih mudah diuji, dicari, dan diubah tanpa memecahkan bahagian lain.

Tanpa pengasingan ini, anda akan mengulang query dan pengiraan yang sama di banyak halaman, dan sebarang perubahan kecil memaksa anda menyunting berpuluh fail. Komponen ialah jawapan kepada masalah itu, dan ia menjadi asas kepada corak yang lebih maju seperti ORM dan REST yang dibincangkan dalam panduan ORM dan panduan REST API. Komponen juga memudahkan ujian unit: anda boleh mencipta tika terpencil dan menyuntik kebergantungan melalui init, tanpa perlu memuatkan seluruh aplikasi.

Mencipta komponen: new dan createObject

Ada dua cara utama untuk mencipta tika komponen: operator new dan fungsi createObject. Kedua-duanya menghasilkan objek yang sama.

// Operator new
var user = new User("Thalhah");

// createObject
var user2 = createObject("component", "User").init("Thalhah");

Perhatikan beza halus: createObject dengan jenis component mencipta tika tanpa memanggil kaedah init, jadi anda perlu memanggil init secara manual. Operator new pula boleh menghantar hujah terus kepada init. createObject amat berguna apabila nama komponen dibina secara dinamik semasa jalanan.

extends: pewarisan dan guna semula

Atribut extends membolehkan satu komponen mewarisi kaedah dan property daripada komponen induk. Ini cara utama mengelak pertindihan kod apabila beberapa komponen berkongsi tingkah laku yang sama.

// BaseService.cfc
component {

    public function log(required string mesej) {
        cflog(text = mesej, type = "information");
    }

}

// UserService.cfc
component extends="BaseService" {

    public function simpan(required string nama) {
        log("Simpan pengguna: #nama#");
        // logik simpan di sini
    }

}

Nama induk ditulis dalam notasi titik tanpa sambungan .cfc, contohnya models.admin.BaseService. Laluan komponen tidak peka huruf besar kecil. Selain extends, komponen juga boleh menggunakan implements untuk melaksanakan antara muka, dan kata kunci super untuk memanggil kaedah induk yang ditindih. Ini memberi anda fleksibiliti penuh corak objek tanpa meninggalkan CFML. Baca panduan skop CFML untuk memahami beza variables dan this dalam komponen.

Pemetaan komponen (component mappings)

Secara lalai Lucee mencari komponen berbanding webroot, tetapi anda boleh mentakrifkan pemetaan supaya komponen dirujuk dengan nama pendek dan lokasi diasingkan daripada struktur URL. Pemetaan ditakrifkan dalam pentadbir atau dalam Application.cfc melalui this.componentPaths.

// Application.cfc
component {
    this.componentPaths = [
        {
            physical: getDirectoryFromPath(getCurrentTemplatePath()) & "models",
            primary: "physical",
            inspectTemplate: "once"
        }
    ];
}

Dengan pemetaan ini, createObject("component", "models.User") dan new models.User() akan mencari dalam direktori models tanpa laluan penuh. Baca panduan Application.cfc untuk konfigurasi aplikasi. Selain direktori fizikal, pemetaan juga boleh menunjuk ke arkib Lucee (.lar) yang membungkus komponen terkompil, berguna apabila anda mengedarkan komponen tanpa mendedahkan kod sumber.

Amalan penamaan

Penamaan yang konsisten menjimatkan masa orang lain dan diri anda sendiri. Gunakan nama komponen dalam bentuk kata nama dengan huruf besar setiap kata seperti UserService dan OrderRepository. Gunakan nama kaedah dalam bentuk kata kerja dengan huruf kecil pada permulaan seperti dapatkanSenarai dan simpanPengguna. Nama property pula kata nama ringkas dalam camelCase.

Elakkan singkatan kabur seperti u dan usr; nama penuh lebih murah daripada masa yang dibuang meneka maksudnya. Simpan satu komponen bagi setiap fail, dan padankan nama fail dengan nama komponen supaya createObject dan new dapat mencarinya tanpa tekaan. Akhir sekali, nyatakan jenis data pada parameter dan nilai pulangan: ia mendokumenkan kontrak dan membolehkan Lucee mengesan ralat lebih awal. Kekal konsisten dengan bahasa yang anda guna dalam projek, sama ada Bahasa Melayu atau Inggeris, dan jangan campur kedua-duanya dalam satu kod asas.

Fungsi Biasa atau Komponen CFC?

Fungsi biasa dan komponen CFC bukan pilihan yang saling menolak, tetapi setiap satu sesuai untuk situasi yang berbeza. Jadual berikut meringkaskan bila menggunakan yang mana.

SituasiPilihanSebab
Logik pendek dalam satu halamanFungsi biasa (UDF)Tidak perlu struktur kelas
Logik berulang di banyak tempatKomponen CFCKaedah dan data boleh diguna semula
Gabungan data dan tingkah lakuKomponen CFCSetara kelas, simpan property dan fungsi
Panggilan HTTP terus (AJAX/API)Komponen CFC dengan remoteKaedah remote boleh dipanggil melalui HTTP

Apabila logik mula berulang di banyak tempat, itu isyarat untuk memindahkannya ke komponen CFC.

Soalan Lazim (FAQ)

Apa beza fungsi dan komponen dalam CFML?

Fungsi ialah blok kod boleh guna semula, manakala komponen ialah unit yang menggabungkan fungsi dan data, setara dengan kelas dalam bahasa objek lain.

Bagaimana cara memanggil komponen CFC?

Gunakan new ComponentName(...) atau createObject("component", "ComponentName"), kemudian panggil kaedahnya.

Apakah createObject("component", ...) memanggil init?

Tidak. createObject jenis component mencipta tika tanpa memanggil init, jadi anda perlu memanggil init secara manual.

Bolehkah komponen mewarisi komponen lain?

Ya, melalui atribut extends, dengan nama induk ditulis dalam notasi titik tanpa sambungan .cfc.

Apakah maksud accessors="true"?

Ia menjana getter dan setter secara automatik untuk setiap property komponen, jadi anda tidak perlu menulisnya dengan tangan.

Sumber

0 komen

Log masuk untuk menjawab atau memberi komen.

Log masuk