ว่าจะเขียน review ตั้งแต่สอนเสร็จล่ะครับ ว่าเป็นยังไงมั่ง ก็ขอสรุปแยกเป็นเรื่องๆ ละกันนะครับ
คนที่มาอบรม
เรื่องคนที่มาอบรมนี่ บอกตามตรงว่าเป็นปัญหากับผมและทีมงานค่อนข้างมาก เพราะว่า background หลากหลายเหลือเกิน ส่วนมากอาจจะมีประสบการณ์เขียน Java มาก่อนบ้าง แต่นอกนั้นถึงจะมีประสบการณ์เขียนโปรแกรมมาก่อน ก็เป็นพวก Web developer สาย PHP ซึ่งจะไม่ค่อยมีประสบการณ์ด้านการออกแบบ OOP เท่าไหร่นัก
ทำให้ผมค่อนข้างจะมั่นใจว่า การปูพื้นฐาน Object-Oriented ใหม่หมด โดยเฉพาะอย่างยิ่ง patterns ที่ Cocoa Framework ใช้งาน ไม่ว่าจะเป็น Property, Getter/Setter, Model-View-Controller, Target/Action, Outlet เป็นสิ่งที่ถูกต้องที่สุด เพราะว่าถึงจะเคยเขียน Java มาก่อน ก็ไม่ได้แปลว่าเราจะเข้าใจเรื่องพวกนี้ตรงกัน หรือว่าไปในทางที่เป็นประโยชน์ต่อการเขียนโปรแกรมใน Cocoa Framework
Objective-C
ผมเห็นว่า Objective-C มีปัญหากับหลายคนน้อยกว่าที่ผมคิด โดยเฉพาะอย่างยิ่งพวกที่เป็นภาษา Java มาก่อน เพราะว่ามันคล้ายกันมากๆ โดยเฉพาะอย่างยิ่งเมื่อมันมี Garbage Collector (ซึ่งใน Objective-C 2.0 มี แต่ยังไม่มีใน iPhone OS)
ปัญหาที่พบก็คือเรื่องความสับสนใน syntax ระหว่าง [] (messaging notation) กับ . (dot notation) ในการเข้าถึง property ว่าเมื่อไหร่ควรจะใช้ตัวไหน
ถ้าเป็น Objective-C 1.0 ไม่มีทางเลือก เพราะว่ามีแต่ messaging notation นั่นคือ ไม่มีการแบ่งแยกระหว่าง การให้ object หนึ่งๆ ตอบสนองเชิงพฤติกรรม กับ การเข้าถึง property ของ object นั้นๆ ทางเลือกเดียวของเราก็คือ ส่ง message ไปให้มัน
แต่ว่าพอมา Objective-C 2.0 มุมมองตรงนี้เปลี่ยนไป แยกแยะระหว่างการเข้าถึง property ของ object และการให้ object ตอบสนองเชิงพฤติกรรมอย่างชัดเจน อันแรกจะเป็นการเข้าถึงโดยการผ่าน dot-notation แต่ว่าอย่างหลังเป็นการส่ง message (ใช้ messaging notation)
พูดง่ายๆ invoking method ใช้ messaging notation แต่ว่าถ้าเป็น getter/setter ล่ะก็ ใช้ dot notation
@property, @synthesize
ตรงนี้หลายคนงงครับ ใน Objective-C มีความซ้ำซ้อนสูงในจุดหนึ่ง คือ เรื่องการกำหนด property ให้กับ object เพราะว่าก่อนอื่นเราต้องกำหนดก่อน ว่า object จะมี data/attribute อะไรบ้าง
@interface Fruit : NSObject {
NSString *name;
NSString *detail;
}
ซึ่งเป็นการบอกว่า Object Fruit นี้จะมี data สองอย่างคือ name, detail จากนั้นเราก็ต้องกำหนด property ให้มันแต่ละตัวว่า
@property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSString *detail;
ซึ่งเป็นการบอกว่า data แต่ละตัว name, detail นี้จะถูกเข้าถึง (ผ่าน dot-notation) อย่างไรได้บ้าง ก็คือ การบอกว่า getter/setter ของ property เหล่านี้ จะต้องถูกสร้างหรือเปล่า ถ้าใช่ จะต้องถูกสร้างอย่างไร
ที่หลายคนงง ก็คือ @synthesize ที่อยู่ใน implementation ครับ หลายคนจะเข้าใจผิดว่า เป็นการสั่งให้ "สร้าง property ตัวนั้นขึ้นมา" ด้วยเหตุว่า syntax มันคือ
@synthesize name, detail;
แปลตรงๆ ตัวก็คือ สร้าง name, detail ซึ่งน่าจะหมายถึงการที่เราสร้าง object ชนิด NSString ชื่อ name และ NSString ชื่อ detail ขึ้นมาให้เราใช้ โดยที่เราไม่ต้องไป new (alloc, init) มัน ... แต่ว่า ผิดถนัด ครับ เพราะว่าจริงๆ แล้วเป็นการสั่งให้สร้าง getter/setter ตามคุณลักษณะที่เรากำหนดไว้ต่างหาก นั่นคือ เราไม่ต้องไปสร้าง method พวกนี้เอง
-(NSString *)name; -(void)setName:(NSString *)newName;
แต่ว่า compiler มันจะจัดการให้ โดยภายในมันจะมีวิธีการ implement ในแบบที่กำหนดไว้ตอนกำหนด @property
Cocoa
มาถึง Cocoa สิ่งที่พบก็คือ แม้ผมจะมองว่า Cocoa เป็น MVC framework ที่ทำได้สวยมากที่สุดตัวหนึ่ง แต่ว่าหลายคนจะยังมีปัญหากับมันอยู่พอสมควร ด้วยเหตุที่ว่า มันเป็น MVC แบบจริงจังมาก ... อ้าว แล้วมันเป็นปัญหายังไงล่ะ
ปัญหาง่ายๆ ก็คือ หลายคนถึงจะมีประสบการณ์กับการเขียน Java, .NET หรือว่าอย่างอื่นมาบ้าง ก็ไม่ได้แปลว่าจะเขียนแยก MVC เพราะว่าลักษณะของ tools หลายตัวที่มี มันไม่เอื้อหรือบังคับเช่นนั้น สิ่งที่หลายคนคุ้นมากกว่าคือ View-based application และเน้นที่ตัว View Controller
ตัวอย่างง่ายที่สุดคือ พวก Java, .NET ที่มี Form designer ทั้งหลาย เมื่อเราวาดหน้าตาโปรแกรมเรียบร้อยแล้ว เรา double click ที่ปุ่ม โปรแกรมก็จะสร้าง method ตัวหนึ่งขึ้นมาใน code ให้เรา ที่คอยรับ action เมื่อเรากดปุ่มนั้น ซึ่งเป็นการ hard-binding ระหว่าง ปุ่มกับ code และหลายคนจะติดนิสัย ฝัง code ทั้งหมดที่เกี่ยวข้องกับการทำงานของปุ่มนั้นๆ ลงไปในส่วนนั้นเลย นั่นคือ การทำงานจาก View เป็นหลัก จากนั้นค่อยๆ เขียนส่วนของ View Controller เท่าที่จำเป็น และส่วนมากไม่ได้ design ความเกี่ยวข้องอะไรกันไว้ล่วงหน้าซะด้วย
พอมาเจอ MVC แท้ๆ แบบ Cocoa เลยเกิดอาการงงกันบ้าง
อีกอย่าง เพราะว่า Cocoa ไม่ค่อยจะ encourage ให้ทำ programmatic view สำหรับ View ที่เป็น static เท่าไหร่นัก โดยให้ทำใน Interface Builder แทน และ View ส่วนนี้จะถูก serialize ไปอยู่ในไฟล์ XIB (NIB) ซึ่งแต่ละ component ในไฟล์นั้นจะถูกสร้างเองใน runtime ... แต่ไม่มี code (ยกเว้นจะถือว่าในไฟล์ XIB เป็น code) ซึ่งก็ทำให้หลายคนไม่เข้าใจ เพราะว่าเคยชินกับการที่ออกแบบ interface ใน Form Designer แล้วมันกลายเป็นการสร้าง code ขึ้นในส่วนของ View Controller
เช่น ลองไปใช้ Java, .NET ออกแบบ form จะพบว่า ทุกอย่างที่เราออกแบบไป มันจะโผล่มาเป็น code ในส่วนของ [ชื่อform].java หรือว่า [ชื่อform].cs อะไรทำนองนี้เสมอ
ก็เป็นเรื่องที่ต้องปรับตัวกันไป
Framework
เรื่องนี้เรื่องสำคัญมาก การทำงานกับ Framework ที่ดี คือ เราต้องไม่ต่อสู้กับมัน ต้องค่อยๆ เรียนรู้ว่า Framework มันทำงานอย่างไร แล้วทำงานตามจังหวะของมัน
หลายคนพยายามจะคิดดัด Cocoa Framework ให้เข้ากับวิธีคิดของตัวเอง ว่าทำแบบนั้นแบบนี้ได้มั้ย เพราะว่าตัวเองเคยทำมาแบบนั้นแบบนี้ ในภาษานั้นภาษานี้ ซึ่งข้อแนะนำของผมก็คือ อย่าแม้แต่จะคิด เพราะว่าเสียเวลาเปล่า ถึงทำได้ ก็ยาก และโปรแกรมที่ทำออกมาได้ ก็จะมีประสิทธิภาพการทำงานที่ต่ำกว่าโปรแกรมที่ทำงานตาม Framework
น้อง @FordAntitrust เคยจำแนกไว้สวยๆ เลยว่า "Library เราใช้ code ของมัน ที่มันรวบรวมไว้ แต่ Framework น่ะ เราต้องเขียน code ตามที่มันกำหนด เอาไปให้มันใช้ มันเป็นคนใช้ code ไม่ใช่เรา"
วันนี้เอาไว้แค่นี้ก่อนก็แล้วกัน เดี๋ยวผมจะมารีวิวต่อวันหลัง
Recent comments
9 weeks 2 days ago
9 weeks 5 days ago
10 weeks 1 day ago
12 weeks 1 day ago
12 weeks 1 day ago
16 weeks 2 days ago
16 weeks 3 days ago
16 weeks 3 days ago
16 weeks 3 days ago
17 weeks 2 days ago