ตอบช้า แต่ฉันทนไม่ได้
X คลาสส่วนใหญ่ใน Y ดีหรือต่อต้านแบบ?
ในกรณีส่วนใหญ่กฎส่วนใหญ่ที่นำไปใช้โดยไม่ได้คิดจะผิดอย่างมาก (รวมถึงกฎนี้)
ฉันจะเล่าเรื่องเกี่ยวกับการเกิดของวัตถุท่ามกลางความโกลาหลของรหัสขั้นตอนที่ถูกต้องรวดเร็วและสกปรกที่เกิดขึ้นไม่ใช่จากการออกแบบ แต่ไม่ใช่ความสิ้นหวัง
ฝึกงานของฉันและฉันเป็นคู่เขียนโปรแกรมเพื่อสร้างรหัสทิ้งอย่างรวดเร็วเพื่อขูดหน้าเว็บ เราไม่มีเหตุผลใดที่จะคาดหวังว่ารหัสนี้จะใช้งานได้นานดังนั้นเราจึงเพิ่งแก้ไขบางสิ่งที่ใช้งานได้ เราคว้าทั้งหน้าเป็นสตริงและตัดสิ่งที่เราต้องการด้วยวิธีที่บอบบางที่สุดที่คุณจะจินตนาการได้ อย่าตัดสิน มันได้ผล.
ตอนนี้ในขณะที่ทำสิ่งนี้ฉันได้สร้างวิธีการคงที่เพื่อทำการสับ นักศึกษาฝึกงานของฉันสร้างคลาส DTO ที่เหมือนคุณCatData
มาก
เมื่อฉันดู DTO ครั้งแรกมันทำให้ฉันเบื่อ หลายปีที่ความเสียหายของจาวาทำให้สมองของฉันหายไปทำให้ฉันหดตัวในที่สาธารณะ แต่เราทำงานใน C # C # ไม่จำเป็นต้องได้รับผู้ดูแลและผู้ตั้งค่าก่อนวัยเพื่อรักษาสิทธิ์ของคุณในการทำให้ข้อมูลไม่เปลี่ยนรูปหรือถูกห่อหุ้มในภายหลัง คุณสามารถเพิ่มได้ทุกเมื่อที่คุณต้องการ อาจเป็นเพียงเพื่อให้คุณสามารถตั้งค่าเบรกพอยต์ ทั้งหมดโดยไม่บอกลูกค้าเกี่ยวกับเรื่องนี้ ใช่ C # Boo Java
ดังนั้นฉันถือลิ้นของฉัน ฉันดูเมื่อเขาใช้วิธีการคงที่ของฉันเพื่อเริ่มต้นสิ่งนี้ก่อนที่จะใช้ เรามีพวกเขาประมาณ 14 คน มันน่าเกลียด แต่เราไม่มีเหตุผลที่จะดูแล
เราต้องการมันในที่อื่น เราพบว่าเราต้องการคัดลอกและวางรหัส 14 บรรทัดของการเริ่มต้นถูกโยนไปรอบ ๆ มันเริ่มเจ็บปวดแล้ว เขาลังเลและถามความคิดกับฉัน
ฉันถามอย่างไม่เต็มใจ "คุณจะพิจารณาวัตถุไหม"
เขามองกลับไปที่ DTO ของเขาและทำให้ใบหน้าของเขาสับสน "มันเป็นวัตถุ"
"ฉันหมายถึงวัตถุจริง"
"ฮะ?"
"ฉันจะแสดงให้คุณดูคุณตัดสินใจว่ามันมีประโยชน์หรือไม่"
ฉันเลือกชื่อใหม่และทำสิ่งที่ดูคล้าย ๆ อย่างรวดเร็ว:
public class Cat{
CatData(string catPage) {
this.catPage = catPage
}
private readonly string catPage;
public string name() { return chop("name prefix", "name suffix"); }
public string weight() { return chop("weight prefix", "weight suffix"); }
public string image() { return chop("image prefix", "image suffix"); }
private string chop(string prefix, string suffix) {
int start = catPage.indexOf(prefix) + prefix.Length;
int end = catPage.indexOf(suffix);
int length = end - start;
return catPage.Substring(start, length);
}
}
นี่ไม่ได้ทำสิ่งใดที่คงที่ไม่ได้ทำ แต่ตอนนี้ฉันดูด 14 วิธีการแบบคงที่เข้าไปในชั้นเรียนที่พวกเขาสามารถอยู่คนเดียวกับข้อมูลที่พวกเขาทำงาน
ฉันไม่ได้บังคับให้ฉันใช้งาน ฉันแค่เสนอมันและให้เขาตัดสินใจว่าเขาต้องการที่จะใช้วิธีการคงที่หรือไม่ ฉันกลับบ้านโดยคิดว่าเขาอาจจะยึดติดกับสิ่งที่เขาได้ทำไปแล้ว วันต่อมาฉันพบว่าเขาใช้มันในหลาย ๆ ที่ มันแยกส่วนที่เหลือของรหัสซึ่งยังน่าเกลียดและขั้นตอน แต่ตอนนี้ความซับซ้อนนี้ถูกซ่อนจากเราหลังวัตถุ มันดีขึ้นเล็กน้อย
ตอนนี้แน่ใจว่าทุกครั้งที่คุณเข้าถึงสิ่งนี้มันทำงานค่อนข้างดี DTO เป็นค่าแคชที่รวดเร็วดี ฉันกังวลเกี่ยวกับเรื่องนี้ แต่รู้ว่าฉันสามารถเพิ่มแคชได้หากเราต้องการโดยไม่ต้องแตะรหัสใด ๆ ดังนั้นฉันจะไม่รำคาญจนกว่าเราจะใส่ใจ
ฉันกำลังบอกว่าคุณควรติดอยู่กับวัตถุ OO มากกว่าของ DTO หรือไม่? ไม่เงางามของ DTO เมื่อคุณต้องข้ามเขตแดนซึ่งทำให้คุณไม่สามารถเคลื่อนที่ได้ DTO มีสถานที่ของพวกเขา
แต่วัตถุ OO ก็เช่นกัน เรียนรู้วิธีใช้เครื่องมือทั้งสอง เรียนรู้ค่าใช้จ่ายแต่ละอย่าง เรียนรู้การปล่อยให้ปัญหาสถานการณ์และการตัดสินใจฝึกงาน Dogma ไม่ใช่เพื่อนของคุณที่นี่
เนื่องจากคำตอบของฉันมีมานานแล้วอย่างน่าขันขอให้ฉันทำให้คุณเข้าใจผิดเกี่ยวกับการตรวจสอบรหัสของคุณ
ตัวอย่างเช่นคลาสมักจะมีสมาชิกชั้นเรียนและวิธีการเช่น:
public class Cat{
private String name;
private int weight;
private Image image;
public void printInfo(){
System.out.println("Name:"+this.name+",weight:"+this.weight);
}
public void draw(){
//some draw code which uses this.image
}
}
ตัวสร้างของคุณอยู่ที่ไหน สิ่งนี้ไม่ได้แสดงให้ฉันรู้ว่ามันมีประโยชน์
แต่หลังจากอ่านเกี่ยวกับหลักการความรับผิดชอบเดี่ยวและหลักการเปิดแบบปิดฉันชอบแยกคลาสออกเป็น DTO และคลาสตัวช่วยด้วยวิธีสแตติกเท่านั้นเช่น:
public class CatData{
public String name;
public int weight;
public Image image;
}
public class CatMethods{
public static void printInfo(Cat cat){
System.out.println("Name:"+cat.name+",weight:"+cat.weight);
}
public static void draw(Cat cat){
//some draw code which uses cat.image
}
}
ฉันคิดว่ามันเหมาะกับหลักการความรับผิดชอบเดี่ยวเพราะตอนนี้ความรับผิดชอบของ CatData คือการเก็บข้อมูลเท่านั้นไม่สนใจวิธีการ (เช่นสำหรับ CatMethods)
คุณสามารถทำสิ่งโง่ ๆ มากมายในนามของหลักการความรับผิดชอบเดี่ยว ฉันสามารถยืนยันได้ว่าควรแยก Cat Strings และ Ints Cat ออก วิธีการวาดภาพและรูปภาพนั้นต้องมีชั้นเรียนของตนเอง โปรแกรมที่ทำงานอยู่ของคุณเป็นความรับผิดชอบเดียวดังนั้นคุณควรมีเพียงชั้นเดียว : P
สำหรับฉันแล้ววิธีที่ดีที่สุดในการปฏิบัติตามหลักการความรับผิดชอบเดี่ยวคือการหาสิ่งที่เป็นนามธรรมที่ดีที่ให้คุณวางความซับซ้อนลงในกล่องเพื่อให้คุณสามารถซ่อนมันได้ หากคุณสามารถให้ชื่อที่ดีที่ทำให้ผู้คนไม่ต้องแปลกใจกับสิ่งที่พวกเขาพบเมื่อพวกเขามองเข้าไปข้างในคุณได้ปฏิบัติตามมันค่อนข้างดี คาดหวังให้กำหนดเพิ่มเติมตัดสินใจแล้วว่าจะถามปัญหา สุจริตรายชื่อรหัสของคุณทั้งคู่ทำอย่างนั้นฉันจึงไม่เห็นว่าทำไม SRP ถึงมีความสำคัญที่นี่
และมันยังเหมาะกับหลักการแบบเปิดเพราะการเพิ่มวิธีการใหม่ไม่จำเป็นต้องเปลี่ยนคลาส CatData
ไม่ดี หลักการปิดแบบเปิดไม่ได้เกี่ยวกับการเพิ่มวิธีการใหม่ มันเกี่ยวกับความสามารถในการเปลี่ยนแปลงการใช้วิธีการแบบเก่าและไม่ต้องแก้ไขอะไรเลย ไม่มีอะไรที่ใช้คุณและไม่ใช่วิธีเก่า ๆ ของคุณ คุณเขียนโค้ดใหม่แทนที่อื่นแทน รูปแบบความแตกต่างบางอย่างจะทำอย่างนั้น ไม่เห็นที่นี่
คำถามของฉันคือมันเป็นสิ่งที่ดีหรือต่อต้านรูปแบบ?
ฉันจะรู้ได้ยังไงดี? ดูสิการทำอย่างใดมีประโยชน์และค่าใช้จ่าย เมื่อคุณแยกรหัสจากข้อมูลคุณสามารถเปลี่ยนแปลงได้โดยไม่ต้องคอมไพล์อีกครั้ง บางทีนั่นอาจเป็นสิ่งสำคัญสำหรับคุณ บางทีมันอาจทำให้โค้ดของคุณซับซ้อนอย่างไม่มีจุดหมาย
ถ้ามันทำให้คุณรู้สึกดีขึ้นคุณจะไม่ได้ว่าห่างไกลจากสิ่งที่มาร์ตินฟาวเลอร์เรียกวัตถุพารามิเตอร์ คุณไม่จำเป็นต้องใช้พื้นฐานในวัตถุของคุณเท่านั้น
สิ่งที่ฉันต้องการให้คุณทำคือพัฒนาความรู้สึกในการแยกตัวคุณหรือไม่ในรูปแบบการเข้ารหัส เพราะเชื่อหรือไม่ว่าคุณไม่ได้ถูกบังคับให้เลือกสไตล์ คุณเพียงแค่ต้องอยู่กับทางเลือกของคุณ