JavaRush /Blog Jawa /Random-JV /Napa NULL ala?
Helga
tingkat

Napa NULL ala?

Diterbitake ing grup

Napa NULL ala?

Punika conto prasaja nggunakake NULL ing Jawa: public Employee getByName(String name) { int id = database.find(name); if (id == 0) { return null; } return new Employee(id); } Apa salah karo metode iki? Bisa ngasilake NULL tinimbang obyek - sing salah. Nggunakake NULL minangka praktik sing nggegirisi ing OOP lan kudu dihindari ing kabeh biaya. Akeh panemu sing beda-beda wis diterbitake babagan masalah iki, kalebu presentasi Tony Hoare "Zero Links: A Milyar Dolar Kesalahan" lan kabeh buku David West "Pemikiran Berorientasi Objek." Ing kene aku bakal nyoba ngringkes kabeh argumen lan nuduhake conto carane sampeyan bisa nyegah nggunakake NULL kanthi ngganti karo konstruksi berorientasi obyek sing cocog. Pisanan, ayo goleki rong alternatif kanggo NULL. Kapisan yaiku pola desain Obyek Null (paling diimplementasikake kanthi konstan): public Employee getByName(String name) { int id = database.find(name); if (id == 0) { return Employee.NOBODY; } return Employee(id); } Alternatif kapindho yaiku "gagal cepet" kanthi mbuwang pengecualian yen obyek kasebut ora bisa dibalekake: public Employee getByName(String name) { int id = database.find(name); if (id == 0) { throw new EmployeeNotFoundException(name); } return Employee(id); } Saiki ayo goleki argumen nglawan nggunakake NULL Sadurunge nulis iki Sajrone kirim, Aku dadi kenalan, saliyane kanggo presentations ndhuwur-kasebut dening Tony Hoare lan buku dening David West, karo sawetara publikasi. Iki minangka "Kode Bersih" dening Robert Martin, "Kode Bersih" dening Steve McConnell, "Say No to NULL" dening John Sonmez, lan diskusi babagan StackOverflow sing diarani "Is Returning NULL a Bad Practice?"
Nangani kesalahan kanthi manual
Saben-saben sampeyan nampa obyek minangka input, sampeyan kudu mriksa apa iku referensi kanggo obyek nyata utawa NULL a. Yen sampeyan lali mriksa, program sampeyan bisa uga diganggu ing tengah eksekusi dening NullPointerExeption (NPE) sing dibuwang. Amarga iki, kode sampeyan wiwit diisi karo akeh mriksa lan yen / banjur / cabang liyane. // this is a terrible design, don't reuse Employee employee = dept.getByName("Jeffrey"); if (employee == null) { System.out.println("can't find an employee"); System.exit(-1); } else { employee.transferTo(dept2); } Iki carane pengecualian kudu ditangani ing C lan basa pamrograman prosedural liyane. Ing OOP, penanganan pangecualian dikenalake utamane kanggo nyingkirake blok pangolahan sing ditulis kanthi manual. Ing OOP, kita ngidini pangecualian kanggo gelembung nganti tekan panangan kesalahan ing aplikasi, lan iki ndadekake kode kita luwih resik lan luwih cendhek: dept.getByName("Jeffrey").transferTo(dept2); Coba referensi NULL minangka peninggalan gaya pemrograman prosedural lan gunakake 1) Objek Null utawa 2) Pengecualian. .
Pangerten ambigu
Kanggo kanthi akurat menehi makna apa sing kedadeyan ing jeneng kasebut, cara kasebut getByName() kudu diganti jeneng dadi getByNameOrNullIfNotFound(). Sing padha kudu ditindakake kanggo saben cara sing ngasilake obyek utawa NULL, yen ora bakal ana ambiguitas nalika maca kode kasebut. Dadi, supaya jeneng metode akurat, sampeyan kudu menehi jeneng metode sing luwih dawa. Kanggo ngindhari ambiguitas, tansah bali obyek nyata, obyek null, utawa uncalan pangecualian. Siji bisa mbantah manawa kadhangkala kita mung kudu bali NULL kanggo entuk asil sing dikarepake. Contone, metode get()antarmuka Peta ing Jawa ngasilake NULL nalika ora ana obyek ing Peta. Employee employee = employees.get("Jeffrey"); if (employee == null) { throw new EmployeeNotFoundException(); } return employee; Thanks kanggo nggunakake Peta NULL, kode iki mung mbutuhake siji siklus panelusuran kanggo entuk asil. Yen kita nulis maneh Map supaya cara njaluk () mbalang pangecualian yen ora ketemu, kode kita bakal katon kaya iki: if (!employees.containsKey("Jeffrey")) { // first search throw new EmployeeNotFoundException(); } return employees.get("Jeffrey"); // second search Temenan, cara iki kaping pindho minangka alon minangka asli. Apa sing kudu ditindakake? Ana (ora ana pelanggaran) cacat desain ing antarmuka Peta. Cara entuk () kudu ngasilake Iterator, banjur kode kita bakal katon kaya iki: Iterator found = Map.search("Jeffrey"); if (!found.hasNext()) { throw new EmployeeNotFoundException(); } return found.next(); Miturut cara, iki pancen cara peta STL:: golek () dirancang ing C ++.
Computational vs. Object Oriented Thinking
Baris kode if (employee == null) cukup dingerteni kanggo wong sing ngerti yen obyek ing Jawa minangka penunjuk menyang struktur data, lan NULL minangka penunjuk ora ana apa-apa (ing prosesor Intel x86 - 0x00000000). Nanging, yen sampeyan miwiti mikir ing gaya obyek, baris iki ndadekake akèh kurang pangertèn. Mangkene tampilan kode kita saka sudut pandang obyek:
- Halo, iki departemen pangembangan piranti lunak? - Ya. - Mangga, ngajak pegawe Jeffrey kanggo telpon. - Enteni sedhela... - Halo. - Apa sampeyan NULL?
Pitakonan pungkasan muni rada aneh, ta? Yen, tinimbang, sawise panjalukan kanggo ngajak Jeffrey menyang telpon, wong ing mburi mung macet munggah, iki bakal nimbulaké kangelan tartamtu kanggo kita (Istiméwa). Ing kasus iki, kita bisa nyoba kanggo nelpon maneh, utawa kita bisa laporan kanggo boss kita ora bisa ngomong karo Jeffrey lan ngrampungake tugas utama. Kajaba iku, ing sisih liyane, sampeyan bisa uga dijaluk ngobrol karo wong liya sing, sanajan dudu Jeffrey, bisa uga nulungi sampeyan karo pitakonan sing paling akeh, utawa ora gelem nulungi yen kita kudu ngerti babagan sing mung Jeffrey (Zero Object) ngerti. ).
Gagal alon
Tinimbang metu kanthi cepet , kode ing ndhuwur nyoba mati alon-alon, mateni wong liya ing dalan. Tinimbang supaya kabeh wong ngerti yen ana sing salah lan kudu miwiti ngolah acara sing luar biasa, mula nyoba ndhelikake kegagalan saka klien. Iki meh padha karo penanganan pangecualian manual sing kita rembugan ing ndhuwur. Nggawe kode minangka rapuh sabisa lan ngidini kanggo break yen perlu iku laku apik. Nggawe metode sampeyan nuntut banget babagan data sing bisa digunakake. Ngidini wong-wong mau sambat kanthi mbuwang pangecualian yen data sing diwenehake ora cukup, utawa yen data kasebut mung ora cocok kanggo digunakake ing cara sing dimaksud. Yen ora, bali Obyek Null sing tumindak ing sawetara cara conventional lan uncalan pangecualian ing kabeh kasus liyane. public Employee getByName(String name) { int id = database.find(name); Employee employee; if (id == 0) { employee = new Employee() { @Override public String name() { return "anonymous"; } @Override public void transferTo(Department dept) { throw new AnonymousEmployeeException( "I can't be transferred, I'm anonymous" ); } }; } else { employee = Employee(id); } return employee; }
Obyek sing bisa diganti lan ora lengkap
Umumé, dianjurake banget kanggo ngrancang obyek supaya ora bisa diganti. Iki tegese obyek kudu nampa kabeh data sing dibutuhake nalika digawe lan ora bakal ngganti kahanane sajrone kabeh siklus urip. Nilai NULL asring digunakake ing pola desain Lazy Loading kanggo nggawe obyek ora lengkap lan bisa diganti. Conto: public class Department { private Employee found = null; public synchronized Employee manager() { if (this.found == null) { this.found = new Employee("Jeffrey"); } return this.found; } } Senadyan kasunyatan manawa teknologi iki nyebar, iku minangka anti-pola kanggo OOP. Lan utamané amarga ndadekake obyek tanggung jawab kanggo masalah kinerja karo platform komputasi, kang persis apa obyek Karyawan ora bisa weruh. Tinimbang ngatur negara lan tumindak kanthi cara sing cocog karo tujuan sing dituju, obyek kudu kuwatir babagan cache asil dhewe - iki minangka asil loading malas. Nanging caching dudu apa sing ditindakake karyawan ing kantor, ta? metu? Aja nggunakake loading kesed kanthi cara primitif kaya ing conto ing ndhuwur. Nanging, pindhah cache masalah menyang lapisan liyane saka aplikasi sampeyan. Contone, ing Jawa sampeyan bisa njupuk kauntungan saka fitur program orientasi aspek. Contone, jcabi-aspek duwe @Cacheable anotasi sing caches Nilai bali saka cara. import com.jcabi.aspects.Cacheable; public class Department { @Cacheable(forever = true) public Employee manager() { return new Employee("Jacky Brown"); } } Mugi analisis iki cukup mestekake kanggo sampeyan kanggo mungkasi NULLing kode :) Artikel asli kene . Sampeyan bisa uga kasengsem ing topik kayata: • DI Containers minangka Code PollutersGetters / Setters. ala. Periode. Anti-Pola ing OOPNgindhari String ConcatenationObyek Kudu Immutable
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION