การขยายวิดเจ็ตเป็นการต่อต้านรูปแบบหรือไม่?

Aug 20 2020

ฉันได้อ่านในสถานที่สองแห่งว่าการขยายวิดเจ็ต 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 เพราะมันแบ่งการเพิ่มประสิทธิภาพการแสดงผล แนวทางแรกของฉันมีผลข้างเคียงที่ซ่อนอยู่หรือไม่? เช่นมันเป็นปฏิปักษ์จริงหรือ?

คำตอบ

3 kuhnroyal Aug 20 2020 at 20:22

การขยายวิดเจ็ตแบบ stateful อาจทำให้เกิดปัญหาได้เนื่องจากสถานะถูกพิมพ์ไปยัง superclass และคุณไม่สามารถขยายสถานะได้เนื่องจากคลาสของ state ส่วนใหญ่จะถูกเก็บไว้เป็นส่วนตัว วิธีการค้นหาจำนวนมากเช่นBuildContext.findAncestorStateOfType()อาจล้มเหลว

การขยายวิดเจ็ตไร้สถานะควรใช้งานได้ในกรณีส่วนใหญ่ แต่ไม่แนะนำให้ใช้ดังที่คุณได้ค้นพบแล้ว

โดยทั่วไปกับลักษณะของการตอบสนองและวิดเจ็ตทั้งหมดของ Flutter หลักการขององค์ประกอบที่อยู่เหนือการสืบทอดเป็นรูปแบบที่ดีในการปฏิบัติตาม

คุณสร้างวิดเจ็ตเป็นวิดเจ็ตใหม่เป็นวิดเจ็ตใหม่ลงในวิดเจ็ตใหม่ลงในวิดเจ็ตใหม่ ... คุณเข้าใจตรงกัน

นอกจากนั้นคุณยังบันทึกโค้ด 2 บรรทัดซึ่งส่วนใหญ่สร้างขึ้นโดยอัตโนมัติ แต่คุณปล้นตัวช่วยง่ายๆทั้งหมดใน VSCode / IntelliJ เช่น "Wrap widget with padding" มันยากกว่ามากที่จะรวมส่วนขยายFormBuilderด้วยการเพิ่มช่องว่างในการใช้งานทั้งหมดในแอปของคุณ Fooถ้าคุณเขียนมันเป็นเรื่องง่ายเพียงแค่ห่อมันไว้ภายใน เช่นเดียวกันกับวิดเจ็ตอื่น ๆ ทั้งหมดที่คุณใช้สำหรับการกำหนดธีมสีรูปแบบตัวอักษร ฯลฯ - การเติมเป็นเพียงตัวอย่าง

2 jitsm555 Aug 20 2020 at 21:16

กระพือเป็นมากกว่ามากกว่า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ไม่ใช่ทางเลือกที่ดีที่จะใช้