Analogi Piala Permen
Versi 1: Gelas untuk setiap permen
Katakanlah Anda menulis beberapa kode seperti ini:
Mod1.ts
export namespace A {
export class Twix { ... }
}
Mod2.ts
export namespace A {
export class PeanutButterCup { ... }
}
Mod3.ts
export namespace A {
export class KitKat { ... }
}
Anda telah membuat pengaturan ini:
Setiap modul (lembaran kertas) diberi nama cangkirnya sendiriA
. Ini tidak berguna - Anda tidak benar - benar mengatur permen Anda di sini, Anda hanya menambahkan langkah tambahan (mengeluarkannya dari cangkir) antara Anda dan camilan.
Versi 2: Satu cangkir dalam lingkup global
Jika Anda tidak menggunakan modul, Anda dapat menulis kode seperti ini (perhatikan kurangnya export
deklarasi):
global1.ts
namespace A {
export class Twix { ... }
}
global2.ts
namespace A {
export class PeanutButterCup { ... }
}
global3.ts
namespace A {
export class KitKat { ... }
}
Kode ini menciptakan ruang nama gabungan A
di lingkup global:
Pengaturan ini berguna, tetapi tidak berlaku untuk modul (karena modul tidak mencemari lingkup global).
Versi 3: Tanpa cangkir
Kembali ke contoh asli, cangkir A
, A
dan A
tidak melakukan apapun nikmat. Sebagai gantinya, Anda dapat menulis kode sebagai:
Mod1.ts
export class Twix { ... }
Mod2.ts
export class PeanutButterCup { ... }
Mod3.ts
export class KitKat { ... }
untuk membuat gambar yang terlihat seperti ini:
Jauh lebih baik!
Sekarang, jika Anda masih berpikir tentang seberapa besar Anda benar-benar ingin menggunakan namespace dengan modul Anda, baca terus ...
Ini Bukan Konsep yang Anda Cari
Kita perlu kembali ke asal-usul mengapa ruang nama ada di tempat pertama dan memeriksa apakah alasan itu masuk akal untuk modul eksternal.
Organisasi : Ruang nama berguna untuk mengelompokkan objek dan tipe yang berhubungan secara logis. Misalnya, dalam C #, Anda akan menemukan semua jenis koleksi di System.Collections
. Dengan mengatur jenis kami ke dalam ruang nama hierarkis, kami memberikan pengalaman "penemuan" yang bagus untuk pengguna jenis itu.
Konflik Nama : Ruang nama penting untuk menghindari penamaan tabrakan. Misalnya, Anda mungkin memiliki My.Application.Customer.AddForm
dan My.Application.Order.AddForm
- dua jenis dengan nama yang sama, tetapi ruang nama yang berbeda. Dalam bahasa di mana semua pengidentifikasi ada dalam ruang lingkup root yang sama dan semua majelis memuat semua jenis, sangat penting untuk memiliki semuanya di namespace.
Apakah alasan itu masuk akal dalam modul eksternal?
Organisasi : Modul eksternal sudah ada dalam sistem file, tentu saja. Kita harus menyelesaikannya dengan path dan nama file, jadi ada skema organisasi logis untuk kita gunakan. Kita dapat memiliki /collections/generic/
folder dengan list
modul di dalamnya.
Konflik Nama : Ini tidak berlaku sama sekali dalam modul eksternal. Dalam sebuah modul, tidak ada alasan yang masuk akal untuk memiliki dua objek dengan nama yang sama. Dari sisi konsumsi, konsumen dari setiap modul yang diberikan dapat memilih nama yang akan mereka gunakan untuk merujuk pada modul, sehingga konflik penamaan yang tidak disengaja tidak mungkin.
Bahkan jika Anda tidak percaya bahwa alasan-alasan itu cukup ditangani oleh bagaimana modul bekerja, "solusi" untuk mencoba menggunakan ruang nama dalam modul eksternal bahkan tidak berfungsi.
Kotak dalam Kotak dalam Kotak
Cerita:
Temanmu Bob memanggilmu. "Saya memiliki skema organisasi baru yang hebat di rumah saya", katanya, "lihatlah!". Rapi, mari kita lihat apa yang muncul Bob.
Anda mulai di dapur dan membuka dapur. Ada 60 kotak berbeda, masing-masing berlabel "Pantry". Anda memilih kotak secara acak dan membukanya. Di dalamnya ada satu kotak berlabel "Grains". Anda membuka kotak "Grains" dan menemukan satu kotak berlabel "Pasta". Anda membuka kotak "Pasta" dan menemukan satu kotak berlabel "Penne". Anda membuka kotak ini dan menemukan, seperti yang Anda harapkan, sekantong pasta penne.
Sedikit bingung, Anda mengambil kotak yang berdekatan, juga berlabel "Pantry". Di dalamnya ada satu kotak, sekali lagi berlabel "Grains". Anda membuka kotak "Grains" dan, sekali lagi, temukan satu kotak berlabel "Pasta". Anda membuka kotak "Pasta" dan menemukan satu kotak, yang ini diberi label "Rigatoni". Anda membuka kotak ini dan menemukan ... sekantong pasta rigatoni.
"Itu bagus!" kata Bob. "Semuanya ada dalam ruang nama!".
"Tapi Bob ..." jawabmu. "Skema organisasi Anda tidak berguna. Anda harus membuka banyak kotak untuk mencapai apa pun, dan sebenarnya tidak ada yang lebih nyaman untuk menemukan apa pun daripada jika Anda hanya meletakkan semuanya dalam satu kotak daripada tiga . Bahkan, karena Anda pantry sudah diurutkan dari rak ke rak, Anda tidak perlu kotak sama sekali. Mengapa tidak hanya meletakkan pasta di rak dan mengambilnya saat Anda membutuhkannya? "
"Kamu tidak mengerti - aku harus memastikan bahwa tidak ada orang lain yang memasukkan sesuatu yang tidak termasuk dalam ruang nama 'Pantry'. Dan aku telah dengan aman mengatur semua pastaku ke dalam Pantry.Grains.Pasta
ruang nama sehingga aku dapat dengan mudah menemukannya"
Bob adalah pria yang sangat bingung.
Modul adalah Kotaknya Sendiri
Anda mungkin pernah mengalami hal serupa terjadi dalam kehidupan nyata: Anda memesan beberapa hal di Amazon, dan setiap item muncul di kotaknya sendiri, dengan kotak yang lebih kecil di dalamnya, dengan barang Anda dibungkus dalam kemasannya sendiri. Bahkan jika kotak interiornya serupa, pengirimannya tidak bermanfaat "digabungkan".
Sesuai dengan analogi kotak, pengamatan utama adalah bahwa modul eksternal adalah kotak mereka sendiri . Ini mungkin item yang sangat kompleks dengan banyak fungsi, tetapi modul eksternal yang diberikan adalah kotaknya sendiri.
Panduan untuk Modul Eksternal
Sekarang kita sudah tahu bahwa kita tidak perlu menggunakan 'ruang nama', bagaimana kita mengatur modul kita? Beberapa prinsip dan contoh panduan mengikuti.
Ekspor sedekat mungkin ke tingkat atas
- Jika Anda hanya mengekspor satu kelas atau fungsi, gunakan
export default
:
MyClass.ts
export default class SomeType {
constructor() { ... }
}
MyFunc.ts
function getThing() { return 'thing'; }
export default getThing;
Konsumsi
import t from './MyClass';
import f from './MyFunc';
var x = new t();
console.log(f());
Ini optimal untuk konsumen. Mereka dapat memberi nama tipe Anda apa pun yang mereka inginkan ( t
dalam hal ini) dan tidak perlu melakukan titik-titik asing untuk menemukan objek Anda.
- Jika Anda mengekspor banyak objek, letakkan semuanya di tingkat atas:
MyThings.ts
export class SomeType { ... }
export function someFunc() { ... }
Konsumsi
import * as m from './MyThings';
var x = new m.SomeType();
var y = m.someFunc();
- Jika Anda mengekspor sejumlah besar hal, hanya maka Anda harus menggunakan
module
/ namespace
kata kunci:
MyLargeModule.ts
export namespace Animals {
export class Dog { ... }
export class Cat { ... }
}
export namespace Plants {
export class Tree { ... }
}
Konsumsi
import { Animals, Plants} from './MyLargeModule';
var x = new Animals.Dog();
Bendera merah
Semua yang berikut ini adalah tanda merah untuk penataan modul. Periksa ulang apakah Anda tidak mencoba untuk namespace modul eksternal Anda jika salah satu dari ini berlaku untuk file Anda:
- File yang hanya memiliki deklarasi tingkat atas
export module Foo { ... }
(hapus Foo
dan pindahkan semuanya ke tingkat atas)
- File yang memiliki satu
export class
atau export function
tidakexport default
- Banyak file yang memiliki tingkat yang sama
export module Foo {
di atas (jangan berpikir bahwa ini akan digabungkan menjadi satu Foo
!)