it-swarm.asia

OO تصميم في القضبان: حيث لوضع الاشياء

أنا أستمتع حقًا بـ Rails (على الرغم من أنني لست مستريحًا بشكل عام) ، وأستمتع بـ Ruby لكوني OO للغاية. ومع ذلك ، فإن الميل إلى إنشاء فئات فرعية ActiveRecord ضخمة ووحدات تحكم ضخمة أمر طبيعي للغاية (حتى إذا كنت تستخدم وحدة تحكم لكل مورد). إذا كنت تريد إنشاء عوالم كائنات أعمق ، فأين تضع الفئات (والوحدات ، أفترض)؟ أنا أسأل عن طرق العرض (في المساعدون أنفسهم؟) ، وحدات التحكم والنماذج.

Lib على ما يرام ، وقد وجدت بعض الحلول لجعله يعاد تحميله في بيئة مطورة ، لكن أود أن أعرف ما إذا كانت هناك طريقة أفضل للقيام بهذه الأشياء. أنا حقاً مهتم فقط بفصول الدراسة كبيرة جدًا. أيضا ، ماذا عن المحركات وكيف تتناسب؟

240
Dan Rosenstark

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

في مرحلة ما ، يشير شخص ما إلى نموذج "نموذج الدهون ، التحكم النحيف" ، والمطورين الوسيطين يستخلصون على عجل كل شيء من وحدات التحكم الخاصة بهم ويرمونها في النموذج ، الذي يبدأ في أن يصبح سلة مهملات جديدة لمنطق التطبيق.

في الواقع ، تعتبر أدوات التحكم النحيلة فكرة جيدة ، ولكن النتيجة الطبيعية - وضع كل شيء في النموذج ، ليست في الحقيقة أفضل خطة.

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

تذكر أنه عندما تقوم بتضمين وحدة نمطية في الفصل الدراسي ، فإن الطرق تصبح طرقًا للطبقة في الفصل الدراسي ، لذلك لا يزال ينتهي بك الأمر في فصل دراسي يحتوي على طن من الطرق ، يتم تنظيمها جيدًا في ملفات متعددة.

يمكن أن يعمل هذا الحل بشكل جيد في بعض الحالات - في حالات أخرى ، ستريد التفكير في استخدام فئات في التعليمات البرمجية الخاصة بك تكون لا النماذج أو المشاهدات أو وحدات التحكم.

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

إذا كانت لديك مفاهيم لا تتناسب تمامًا مع تلك الصناديق (الثبات ، إدارة الطلب/الاستجابة) ، فمن المحتمل أنك تريد التفكير في كيفية هل نموذج الفكرة في السؤال. يمكنك تخزين الفئات غير النموذجية في التطبيق/الفئات ، أو في أي مكان آخر ، وإضافة هذا الدليل إلى مسار التحميل الخاص بك عن طريق:

config.load_paths << File.join(Rails.root, "app", "classes")

إذا كنت تستخدم الركاب أو JRuby ، ​​فربما تحتاج أيضًا إلى إضافة المسار إلى مسارات التحميل المتلهفة:

config.eager_load_paths << File.join(Rails.root, "app", "classes")

خلاصة القول هي أنه بمجرد وصولك إلى نقطة في Rails حيث تجد نفسك تطرح هذا السؤال ، فقد حان الوقت لتعزيز مقاطع Ruby الخاصة بك وبدء نماذج النمذجة التي ليست فقط فئات MVC التي يوفرها لك Rails افتراضيًا.

التحديث: تنطبق هذه الإجابة على Rails 2.x أو أعلى.

377
Yehuda Katz

تحديث : تم تأكيد استخدام المخاوف كإعداد افتراضي جديد في Rails 4 .

ذلك يعتمد حقا على طبيعة الوحدة نفسها. عادةً ما أضع امتدادات جهاز التحكم/النموذج في مجلد/المخاوف داخل التطبيق.

# concerns/authentication.rb
module Authentication
  ...
end    

# controllers/application_controller.rb
class ApplicationController
  include Authentication
end



# concerns/configurable.rb
module Configurable
  ...
end    

class Model 
  include Indexable
end 

# controllers/foo_controller.rb
class FooController < ApplicationController
  include Indexable
end

# controllers/bar_controller.rb
class BarController < ApplicationController
  include Indexable
end

/ lib هو خياري المفضل للمكتبات العامة الغرض. لدي دائمًا مساحة اسم مشروع في lib حيث أضع كل المكتبات الخاصة بالتطبيق.

/lib/myapp.rb
module MyApp
  VERSION = ...
end

/lib/myapp/CacheKey.rb
/lib/myapp/somecustomlib.rb

عادةً ما تحدث امتدادات Ruby/Rails الأساسية في مُهيئات التهيئة بحيث يتم تحميل المكتبات مرة واحدة فقط على شريط التعزيز Rails.

/config/initializer/config.rb
/config/initializer/core_ext/string.rb
/config/initializer/core_ext/array.rb

بالنسبة إلى أجزاء التعليمات البرمجية القابلة لإعادة الاستخدام ، غالبًا ما أقوم بإنشاء مكونات إضافية (micro) حتى يمكنني إعادة استخدامها في مشاريع أخرى.

عادةً ما تحتوي ملفات المساعدة على طرق مساعدة وأحيانًا فئات عندما يكون الغرض من الكائن هو استخدامها من قبل المساعدين (على سبيل المثال ، Form Builders).

هذه هي نظرة عامة حقا. يرجى تقديم مزيد من التفاصيل حول أمثلة محددة إذا كنت ترغب في الحصول على مزيد من الاقتراحات المخصصة. :)

62
Simone Carletti

... الميل إلى جعل فئات ActiveRecord الضخمة ووحدات التحكم الضخمة أمر طبيعي جدًا ...

"ضخمة" هي كلمة مثيرة للقلق ... ؛-)

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

كيف تصبح نماذجك ضخمة؟ هل يجب أن تبحث عن طرق لتقليل عدد المسؤوليات في كل فصل؟ هل هناك أي سلوكيات شائعة يمكنك استخراجها إلى خليط؟ أو مجالات الوظائف التي يمكنك تفويضها إلى دروس مساعدة؟

تحرير: محاولة توسيع قليلا ، ونأمل ألا تشوه أي شيء سيء للغاية ...

المساعدون: يعيشون في app/helpers وغالبًا ما يستخدمون لجعل المشاهدات أكثر بساطة. إما أن تكون خاصة بوحدة التحكم (متوفرة أيضًا لجميع طرق العرض لوحدة التحكم هذه) أو متوفرة عمومًا (module ApplicationHelper في application_helper.rb).

عوامل التصفية: قل أن لديك نفس سطر التعليمات البرمجية في العديد من الإجراءات (في كثير من الأحيان ، استرجاع كائن باستخدام params[:id] أو ما شابه). يمكن استخراج هذا الازدواج أولاً إلى طريقة منفصلة ثم الخروج من الإجراءات تمامًا عن طريق إعلان مرشح في تعريف الفئة ، مثل before_filter :get_object. راجع القسم 6 في دليل ActionController Rails اجعل البرمجة التعريفية هي صديقك.

إعادة بيع النماذج هي أكثر شيئًا دينيًا. سيقترح تلاميذ العم بوب ، على سبيل المثال ، اتباع الوصايا الخمسة لـ الصلبة . جويل وجيف قد يوصي أكثر ، إيه ، "براغماتية" النهج ، على الرغم من أنها يبدو أنها أكثر قليلا التوفيق في وقت لاحق. يعد العثور على طريقة أو أكثر داخل فصل دراسي يعمل على مجموعة فرعية محددة بوضوح من سماته إحدى الطرق لمحاولة تحديد الفئات التي قد يتم إعادة تكوينها خارج النموذج المشتق من ActiveRecord.

لا يجب أن تكون نماذج القضبان من الفئات الفرعية لـ ActiveRecord :: Base ، بالمناسبة. أو بعبارة أخرى ، لا يجب أن يكون النموذج مماثلاً لجدول ، أو حتى يتعلق بأي شيء مخزّن على الإطلاق. والأفضل من ذلك ، طالما قمت بتسمية ملفك في app/models وفقًا لقواعد Rails (اطلب # unerscore على اسم الفصل لمعرفة ما الذي تبحث عنه Rails) ، فسوف تجد Rails ذلك دون أي requires.

10
Mike Woodhouse

في ما يلي منشور مدون ممتاز حول إعادة تشكيل نماذج الدهون التي يبدو أنها ناشئة عن فلسفة "جهاز التحكم الرفيع":

http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

الرسالة الأساسية هي "لا تستخلص الخلاطات من نماذج الدهون" ، استخدم فئات الخدمة بدلاً من ذلك ، ويقدم المؤلف 7 أنماط للقيام بذلك

1
bbozo