คุณหาโซลูชัน "สมบูรณ์" สำหรับปัญหา testing แบบไวล์ด์ ทำได้แค่ override constant DEFAULT_HOST และจะรवानाได้
แต่มันต้องปิด warnings เพื่อซ่อนข้อความ醜陋นั้น แต่มัน ตอนนี้ tests ทั้งหมดผ่าน และเปลี่ยนแค่ไม่กี่บรรทัด!
ยกเว้น test หนึ่งที่คุณ ไม่ อยาก override host แต่อาจ re-override constant ปิด warnings อีกครั้ง และ reset ท้าย test ใกล้เสร็จแล้ว คุณเกือบลิ้ม!
แต… แต… แต…
และอีกไม่กี่วัน ตอนค้างที่ครั้งที่ 27 และแอปกลายเป็นกลุ่ม hacks ยักษ์ คุณจะนั่งสงสัย: ทำไมผมถึง ทำ ทุกอย่างนี้? โซลูชันแย่กว่าปัญหาไหม?
วิธีแก้ปัญหา Too-Clever
ชัดเจนว่าแนวคิดเดิมแก้ปัญหาไม่หมด ดังนั้นหา โซลูชันที่ดีกว่า ที่แก้ edge cases ทั้งหมดที่แนวคิดเดิมแก้ไม่ได้ จะทำอย่างไร?
ทำไม่ได้ คุณไม่สามารถต่อสู้ความฉลาดเกินไป ด้วยความฉลาดมากขึ้น โดยตรงไม่ได้ อย่างน้อยก็ไม่ได้โดยตรง ให้ไปทางตรงข้าม ไปแบบง่าย ไปแบบตรงไปตรงมา
มันหมายถึงอะไร?
Inline โค้ดที่พยายาม abstract ไป Do repeat yourself ระบุโค้ดชัดเจน
ถ้าพยายาม override constant DEFAULT_HOST ด้วย default host อื่น ลืมทั้งแนวคิด default เลย ระบุทุกครั้ง
แทนที่จะเป็น:
require 'test_helper' silence_warnings do Rack::Test::DEFAULT_HOST = "www.justinweiss.com" end class WelcomeTest < ActionDispatch::IntegrationTest include Rack::Test::Methods test "can visit the homepage" do get "/" # ... end # ... end ให้ทำแบบนี้:
require 'test_helper' class WelcomeTest < ActionDispatch::IntegrationTest test "can visit the homepage" do get "https://www.justinweiss.com/" # ... end # ... end ทุกครั้งที่โซลูชัน "สมบูรณ์" ของผมพัง มันเพราะผมไม่อาจจินตนาการ edge cases ที่จะต้องจัดการภายหลัง
โอเค เราทำนายอนาคตไม่ได้ แตตอนรู้สึกว่ามันเกิดหยุดขุด อย่าทำ patch ซ้อน patch แทนให้ unwind โซลูชันเดิม และ extract โซลูชันที่ดีกว่า
วิธี Extract โซลูชันที่ดีกว่า
ตอนโค้ดเขียนออกมา explicit และตรงไปตรงมาแล้ว คุณจะเริ่มคิดวิธีจัดระเบียบใหม่
ปกติ Extract Method หรือ Extract Class ที่จุดที่ถูกต้องก็พอ ทริกคือการตัดสินใจว่าจุดไหนถูกต้อง แต่มันง่ายกว่าเวลาเห็นการซ้ำซ้อนมากมายหน้าตา
และพึ่งพา inheritance และ delegation บล็อกก่อสร้างง่ายๆ ที่ช่วย cleanup โค้ดโดยไม่ได้ฉลาดเกินไป
อีกอย่างนึง
อย่าลืมอ่านเอกสาร:
require 'test_helper' class WelcomeTest < ActionDispatch::IntegrationTest setup do # นี้มีอยู่แล้ว: host! "www.justinweiss.com" end test "can visit the homepage" do get "/" # ... end # ... end คำตอบไม่ได้ชัดเจนเสมอไป แต่น่าล้มเลิกที่สุดคือการรู้ว่ามี built-in method เดียวที่แก้ปัญหาเดียวกันที่คุณเขียน 3 คลาสและ 1 gem ไป
โซลูชันที่ดีกว่าในที่สุด
โซลูชันที่ 2 ของคุณมักจะดีกว่า ทุกด้าน โซลูชันแรก
ทำไม?
-
คุณมีประสบการณ์มากขึ้น
มีไอเดียดีกว่าเกี่ยวกับโค้ดที่ดี
-
คุณรู้ระบบที่สร้างมากขึ้น
ตัดสินใจได้ดีกว่าโค้ดที่เขียนเข้ากับระบบอย่างไร
-
คุณรู้ว่าสมมติฐานไหนผิด
โซลูชันจึงเข้ากับปัญหาจริง ไม่ใช่ปัญหาที่จินตนาการ อาจ มี
และในที่สุด อาจมีที่สำหรับความฉลาดที่ดีที่สุดของคุณเข้ามาอีกครั้ง คราวนี้โดยไม่มี hacks
ต้องหยุดขุด
โค้ดฉลาด เขียนสนุก ใน Ruby เขียนง่ายด้วย และโดยเฉพาะ ง่ายเกินไปที่จะเดินต่อบนเส้นทาง แม้รู้ว่ามันนำไปสู่ที่ผิด
แตตอนได้ความรู้สึกว่าบางอย่างไม่ตรง หยุดพักสักครู่ Un-factor โค้ด อ่านเอกสาร ทำโค้ดตรงไปตรงมา explicit และหาทางที่ดีกว่า
คุณจำได้ไหมครั้งสุดท้ายที่คุณขุดหลุมลึกๆ ที่จบไม่สิ้นสุด? คุณ ออก ได้ยังไง? โค้ดที่เหลือสุดท้ายเป็นอย่างไร?