نقاتل مع Msg كبير جدا في تطبيقات الدردار

وفقًا لـ Elm Architecture ، يتركز كل منطق التطبيق في مكان واحد. يعد هذا أسلوبًا بسيطًا ومريحًا إلى حد ما ، ولكن مع نمو التطبيق ، يمكنك رؤية وظيفة update بطول 700 سطر ، مع Msg تضم مائة منشئي Model ، والتي لا تناسب الشاشة.


من الصعب تعلم هذا الكود والحفاظ عليه في كثير من الأحيان. أود أن أظهر أسلوبًا بسيطًا للغاية من شأنه تحسين مستوى التجريد في التطبيق الخاص بك.


دعنا ننظر إلى مثال بسيط.


أولاً ، قم بإنشاء تطبيق صغير مع حقل نص واحد فقط. يمكن العثور على الرمز الكامل هنا .


 type alias Model = { name : String } view : Model -> Html Msg view model = div [] [ input [ placeholder "Name", value model.name, onInput ChangeName ] [] ] type Msg = ChangeName String update : Msg -> Model -> Model update msg model = case msg of ChangeName newName -> { model | name = newName } 

التطبيق ينمو ، نضيف الاسم الأخير ، "عن أنفسنا" وزر "حفظ". ارتكب هنا .


 type alias Model = { name : String , surname : String , bio : String } view : Model -> Html Msg view model = div [] [ input [ placeholder "Name", value model.name, onInput ChangeName ] [] , br [] [] , input [ placeholder "Surname", value model.surname, onInput ChangeSurname ] [] , br [] [] , textarea [ placeholder "Bio", onInput ChangeBio, value model.bio ] [] , br [] [] , button [ onClick Save ] [ text "Save" ] ] type Msg = ChangeName String | ChangeSurname String | ChangeBio String | Save update : Msg -> Model -> Model update msg model = case msg of ChangeName newName -> { model | name = newName } ChangeSurname newSurname -> { model | surname = newSurname } ChangeBio newBio -> { model | bio = newBio } Save -> ... 

لا شيء رائع ، كل شيء على ما يرام.


لكن التعقيد يزداد بشكل كبير عندما نقرر إضافة عنصر آخر إلى صفحتنا لا علاقة له تمامًا بالمكون الحالي - نموذج الكلب. الالتزام .


 type Msg = ChangeName String | ChangeSurname String | ChangeBio String | Save | ChangeDogName String | ChangeBreed String | ChangeDogBio String | SaveDog update : Msg -> Model -> Model update msg model = case msg of ChangeName newName -> { model | name = newName } ChangeSurname newSurname -> { model | surname = newSurname } ChangeBio newBio -> { model | bio = newBio } Save -> ... ChangeDogName newName -> { model | dogName = newName } ChangeBreed newBreed -> { model | breed = newBreed } ChangeDogBio newBio -> { model | dogBio = newBio } SaveDog -> ... 

بالفعل في هذه المرحلة ، يمكنك أن ترى أن Msg يحتوي على "مجموعتين" من الرسائل. تشير "ميلي البرنامجي" إلى ضرورة تجريد مثل هذه الأشياء. ماذا سيحدث عندما تظهر 5 مكونات أخرى؟ ماذا عن المكونات الفرعية؟ سيكون من المستحيل تقريبًا التنقل في هذا الرمز.


هل يمكننا تقديم هذه الطبقة الإضافية من التجريد؟ بالطبع !


 type Msg = HoomanEvent HoomanMsg | DoggoEvent DoggoMsg type HoomanMsg = ChangeHoomanName String | ChangeHoomanSurname String | ChangeHoomanBio String | SaveHooman type DoggoMsg = ChangeDogName String | ChangeDogBreed String | ChangeDogBio String | SaveDog update : Msg -> Model -> Model update msg model = case msg of HoomanEvent hoomanMsg -> updateHooman hoomanMsg model DoggoEvent doggoMsg -> updateDoggo doggoMsg model updateHooman : HoomanMsg -> Model -> Model updateHooman msg model = case msg of ChangeHoomanName newName -> { model | name = newName } -- Code skipped -- updateDoggo : DoggoMsg -> Model -> Model -- Code skipped -- view : Model -> Html Msg view model = div [] [ h3 [] [ text "Hooman" ] , input [ placeholder "Name", value model.name, onInput (HoomanEvent << ChangeHoomanName) ] [] , -- Code skipped -- , button [ onClick (HoomanEvent SaveHooman) ] [ text "Save" ] , h3 [] [ text "Doggo" ] , input [ placeholder "Name", value model.dogName, onInput (DoggoEvent << ChangeDogName) ] [] , -- Code skipped -- ] 

باستخدام نظام نوع الدردار ، قسمنا رسالتنا إلى نوعين: الإنسان وكلاب. الآن سيكون الحد الأدنى لإدخال هذا الرمز أسهل بكثير. بمجرد أن يحتاج بعض المطورين إلى تغيير شيء ما في أحد المكونات ، سيتمكن من تحديد هيكل الأجزاء التي يحتاجها من التعليمات البرمجية فورًا. تحتاج إلى إضافة المنطق إلى الاحتفاظ المعلومات الكلب؟ انظر إلى الرسائل وابدأ البحث عنها.


تخيل الرمز الخاص بك هو إشارة ضخمة. كيف تبحث عن المعلومات التي تهتم بها؟ حسب جدول المحتويات (Msg و Model). هل سيكون من السهل عليك التنقل في جدول المحتويات دون التقسيم إلى أقسام وأقسام فرعية؟ بالكاد.


استنتاج


هذه هي تقنية بسيطة للغاية يمكن استخدامها في أي مكان وسهلة للغاية لتضمينها في التعليمات البرمجية الموجودة. سيكون إعادة إنشاء تطبيق موجود مؤلمًا تمامًا ، وذلك بفضل الكتابة الثابتة ومترجم الدردار المفضل لدينا.


بعد قضاء ساعة واحدة فقط من وقتك (قضينا أقل من 20 دقيقة على كل تطبيق في مشروعنا) ، يمكنك تحسين قابلية قراءة التعليمات البرمجية الخاصة بك بشكل كبير وتحديد المعيار لكيفية كتابتها في المستقبل. ليس الكود السهل تصحيح الأخطاء جيدًا ، لكن الكود الذي يحظر الأخطاء ويضرب مثالًا على كيفية كتابة الكود.


بالضبط نفس الأسلوب يمكن تطبيقه على Model ، مع إبراز المعلومات اللازمة في الأنواع. على سبيل المثال ، في المثال الخاص بنا ، يمكن تقسيم النموذج إلى نوعين فقط: Hooman و Doggo ، مما يقلل عدد الحقول في النموذج إلى نوعين.


حفظ الله نظام نوع الدردار.


يمكن العثور على مستودع PS مع الكود هنا إذا كنت تريد رؤية الاختلافات

Source: https://habr.com/ru/post/ar455553/


All Articles