Tagged: side effect

ฟังก์ชั่นต้องไม่มี side effect

แปลมาจากหนังสือ “Clean Code: A Handbook of Agile Software Craftsmanship” ครับ
Have No Side Effects
Side Effects เป็นเรื่องเลวร้ายมากๆ ยังจำกันได้ไหมว่าฟังก์ชั่นที่ดีควรทำงานเพียงอย่างเดียวและก็เพราะ ฟังก์ชั่นของเราต้องทำงานหนึ่งอย่างเสมอแต่ในบางครั้งมันก็แอบทำอย่างอื่นไปด้วยแบบแอบซ่อนๆ เช่นบางครั้งก็ไปแอบเปลี่ยนค่าของตัวแปรในคลาส บางครั้งก็แอบไปเปลี่ยนค่าตัวแปรแบบ Global ซึ่งสิ่งเหล่านี้จะทำลายข้อตกลงอันดีงามของเราและส่งผลให้ซอฟท์แวร์ของเรามี ระดับของ coupling ที่สูงมากยกตัวอย่างเช่นเรามีฟังก์ชั่นที่ ทำงานด้วยอัลกอริธึมที่แสนจะธรรมดาเพื่อเปรียบเทียบ userName กับ password มันจะ return ค่า true ในกรณีที่มันเปรียบเทียบได้สำเร็จและส่งค่า false ถ้าผิดพลาด แต่!!! คุณว่ามันมี side effect ไหม

public class UserValidator {
  private Cryptographer cryptographer;
  public boolean checkPassword(String userName, String password) {
  User user = UserGateway.findByName(userName);
  if (user != User.NULL) {
    String codedPhrase = user.getPhraseEncodedByPassword();
    String phrase = cryptographer.decrypt(codedPhrase, password);
    if ("Valid Password".equals(phrase)) {
      Session.initialize();
      return true;
    }
  }
  return false;
  }
}

มอง ดีๆเราจะเห็นว่า Side Effect คือ Session.initialize() ถ้าเราพิจรณากันแล้วตามชื่อฟังก์ชั่นนั้นมันชื่อ UserValidator มันไม่น่าจะเกี่ยวอะไรกับ Session.initialize() เลยดังนั้นชื่อที่เราใช้ไม่ได้สื่อกับการทำงานเลยที่หนักกว่านั้นคือ คนที่จะมาใช้ฟังก์ชั่นนี้เมื่อดูชื่อของฟังก์ชั่นแล้วก็ไม่ได้คิดว่าจะมีการ ทำงานนอกเหนือไปจากการ validate user ??? ใครจะไปรู้ว่ามันยังทำ Session.initialize() อีกการเขียนโค้ดแบบนี้ทำให้เกิดสิ่งที่เรียกว่า temporal coupling การมีสิ่งนี้อยู่ในโค้ดจะก่อให้เกิดความสับสนโดยอย่างไรก็ตามในกรณีที่ จำเป็นต้องมี Side Effect ในฟังก์ชั่นก็ขอให้ใส่ไว้ในชื่อฟังก์ชั่นให้ชัดเจนเช่น checkPasswordAndInitializeSession