การขยายวิดเจ็ตเป็นการต่อต้านรูปแบบหรือไม่?
ฉันได้อ่านในสถานที่สองแห่งว่าการขยายวิดเจ็ต Flutter เป็นการต่อต้านรูปแบบ เป็นเช่นนั้นจริงหรือ?
ฉันใช้คลาสย่อยของวิดเจ็ตเพื่อลดการซ้อนโดยคลาสย่อยวิดเจ็ตที่ฉันกำลังลบและวางวิดเจ็ตไว้ในตัวสร้างเช่นนั้น
class Foo extends FormBuilder {
Foo() : super (
// bunch of widgets here
);
}
การขยายวิดเจ็ตไร้สถานะดูเหมือนจะได้รับความนิยมมากกว่า แต่จะเพิ่มโค้ดและวิดเจ็ตอีกสองสามบรรทัดให้กับโครงสร้างซึ่งไม่ใช่ความต้องการของฉัน:
class Foo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FormBuilder(
// bunch of widgets here
);
}
ฉันได้อ่านกลับวิดเจ็ตจากฟังก์ชั่นที่เป็น antipattern เพราะมันแบ่งการเพิ่มประสิทธิภาพการแสดงผล แนวทางแรกของฉันมีผลข้างเคียงที่ซ่อนอยู่หรือไม่? เช่นมันเป็นปฏิปักษ์จริงหรือ?
คำตอบ
การขยายวิดเจ็ตแบบ stateful อาจทำให้เกิดปัญหาได้เนื่องจากสถานะถูกพิมพ์ไปยัง superclass และคุณไม่สามารถขยายสถานะได้เนื่องจากคลาสของ state ส่วนใหญ่จะถูกเก็บไว้เป็นส่วนตัว วิธีการค้นหาจำนวนมากเช่นBuildContext.findAncestorStateOfType()
อาจล้มเหลว
การขยายวิดเจ็ตไร้สถานะควรใช้งานได้ในกรณีส่วนใหญ่ แต่ไม่แนะนำให้ใช้ดังที่คุณได้ค้นพบแล้ว
โดยทั่วไปกับลักษณะของการตอบสนองและวิดเจ็ตทั้งหมดของ Flutter หลักการขององค์ประกอบที่อยู่เหนือการสืบทอดเป็นรูปแบบที่ดีในการปฏิบัติตาม
คุณสร้างวิดเจ็ตเป็นวิดเจ็ตใหม่เป็นวิดเจ็ตใหม่ลงในวิดเจ็ตใหม่ลงในวิดเจ็ตใหม่ ... คุณเข้าใจตรงกัน
นอกจากนั้นคุณยังบันทึกโค้ด 2 บรรทัดซึ่งส่วนใหญ่สร้างขึ้นโดยอัตโนมัติ แต่คุณปล้นตัวช่วยง่ายๆทั้งหมดใน VSCode / IntelliJ เช่น "Wrap widget with padding" มันยากกว่ามากที่จะรวมส่วนขยายFormBuilder
ด้วยการเพิ่มช่องว่างในการใช้งานทั้งหมดในแอปของคุณ Foo
ถ้าคุณเขียนมันเป็นเรื่องง่ายเพียงแค่ห่อมันไว้ภายใน เช่นเดียวกันกับวิดเจ็ตอื่น ๆ ทั้งหมดที่คุณใช้สำหรับการกำหนดธีมสีรูปแบบตัวอักษร ฯลฯ - การเติมเป็นเพียงตัวอย่าง
กระพือเป็นมากกว่ามากกว่าcomposition
Inheritance
แต่การสืบทอดโดยใช้ StatelessWidget จะมีประโยชน์เสมอเมื่อต้องใช้วิดเจ็ตหลักในเด็ก
เช่น:
class FormBuilder extends StatelessWidget {
Widget getWidget() {
return Text('Child Text');
}
@override
Widget build(BuildContext context) {
return Text('FormBuilder Text');
}
}
class Foo extends FormBuilder {
Foo() : super();
@override
Widget build(BuildContext context) {
return getWidget();
}
}
ดังนั้น Widget ซึ่งจะเรียกFoo () Widget ว่า Widget Element tree จะเป็น
- ฟู
- ตู้คอนเทนเนอร์
ถ้า Composition ปกติต้นไม้ Elementก็จะเป็นเช่นนี้
class Foo extends StatelessWidget {
Foo() : super();
@override
Widget build(BuildContext context) {
return FormBuilder();
}
}
- ฟู
- FormBuilder
- ข้อความ
มีไม่ใด ๆ เอกสารอย่างเป็นทางการที่ระบุว่ารูปแบบที่ไม่ดี แต่พลิ้วได้รับการออกแบบโดยการใช้Composition
ในใจ ดังนั้นโดยส่วนตัวแล้วฉันไม่เคยสังเกตเห็นประสิทธิภาพหรือปัญหาที่ล้าหลังเกี่ยวกับการสืบทอดดังนั้นฉันขอแนะนำว่าInheritance
ไม่ใช่ทางเลือกที่ดีที่จะใช้