تحية! اسمي سوسنين ايليا. أنا أعمل في المطور Lamoda Android. أرسم الأزرار ، وتخطي القوائم ، وللأسف ، أكتب التحليلات ...
Lamoda هي شركة مدفوعة بالبيانات تتخذ فيها جميع القرارات بناءً على سلوك المستخدم. أولاً نلاحظ ونستخلص النتائج فقط. لذلك ، من السهل تخمين أن لدينا تحليلات ، ونحن بالفعل في حاجة إليها.
عند فك تشفير تقريري
بواسطة mitap Mosdroid # 18 Argon ، سأخبرك بكيفية
عمل SDK ولماذا التأمل ليس سيئًا دائمًا. وسأجيب أيضًا على السؤال الرئيسي لهذا الموضوع: "كيفية تنفيذ التحليلات وعدم كسر التطبيق؟".

للبدء ، سأطرح عليك سؤالًا بسيطًا: "كيف تفكر ، كم عدد عمليات التثبيت المتوفرة لدينا على Google؟"
10 مليون منشأة!
المؤشر في بداية يوليو 2019.
بالإضافة إلى حقيقة أننا نستخلص الاستنتاجات بناءً على المستخدمين ، لدينا أيضًا عملاء داخليون مهتمون أيضًا بالتحليلات.

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

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

بعض الأحداث تذهب إلى نظام واحد ، والبعض الآخر يذهب إلى عدة في وقت واحد ... وهناك خصوصية بحيث الأحداث مع المعلمات المختلفة وبأشكال مختلفة يمكن أن تذهب إلى أنظمة مختلفة. بالطبع ، لا نريد حقًا حل كل هذه التبعيات.
LStat هو SDK الخاصة بنا (إحصائيات Lamoda). هذا هو نظام ضخم ، والذي يأخذ أكثر من 60 ٪ من الأحداث المختلفة. غالبًا ما تم تجميع تلك الأحداث التي تذهب إلى أبعد من ذلك على Google ، Adjust ، مبدئيًا فقط في LStat.
SDK
SDK لدينا هو على النحو التالي.

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

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

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

بادئ ذي بدء ، يمكن أن يكون بطيئًا أو سريعًا. هناك طرق مثل getFields ، getConstructors التي تعمل بسرعة كبيرة بالنسبة لبقية التفكير. وهناك ، على سبيل المثال ، Constructor newInstance ، والذي يعمل ببطء شديد. بكلمة "بطيء" أعني الفرق بين العمودين الأيسر والأيمن في الجدول أعلاه بعدة ترتيب من حيث الحجم (فرق يبلغ حوالي مائة ضعف). لذلك ، إذا فهمت ما تفعله وتعرف مقدمًا ما تحتاج إلى الاستعداد له ، فليس كل شيء مخيفًا للغاية.
نحن نسحب أكثر من 500 طريقة من 7 فصول . ونحن نفعل ذلك مرة واحدة فقط في الجلسة. الوقت المستغرق لإكمال المقطع هو 40 مللي ثانية. هذا أقل من 3 إطارات (في مرحلة شاشة البداية). لقد كان بعيدًا عن الجهاز المتطور ، ولكنه جهاز NTC بسيط على نظام Android 6 ، والذي كان موجودًا منذ سنوات عديدة.
بطبيعة الحال ، فإن كل شيء على الجهاز النهائي سوف يعمل بشكل أسرع. وإذا تحدثنا عن الهواتف الصينية القديمة ، فحينئذٍ سيكون هناك 100 مللي ثانية مشروطة. إن مستخدمي هذه الهواتف معتادون بالفعل على حقيقة أن كل شيء يعمل ببطء من أجلهم ، لذا فهم غير مبالين بشدة بـ 40 مللي ثانية أو 100 هناك ، فما الفرق؟ أنها لا تزال تبطئ :)
والآن السؤال الرئيسي: كيفية تنفيذ التحليلات حتى لا تكسر الهندسة المعمارية؟
Arhitekturka
يستخدم تطبيقنا MVP.

هذا هو نوع من جوهر الله لدينا ، والذي "يعيش" على ApplicationScope ويتم حقنه بالضبط حيث نحتاج إليه. على سبيل المثال ، نحتاج إلى إيداع onClick (). من أجل عدم كسر البنية ، لن نقوم بإعادة توجيه الحدث من طبقة العرض إلى مقدم العرض ، بحيث ينتقل لاحقًا إلى مكان ما. بدلاً من ذلك ، نحن نفعل كل شيء مباشرةً من طريقة العرض ونمرع المسار إلى AnalyticsManager.
والآن قليلا عن إرسال. في AnalyticsManager ، تنجح إحدى الطرق - وهي طريقة التتبع ، والتي تقبل أي فئة حدث كمدخلات. ثم يحدث السحر الأسود.

هذه الطريقة قادرة على حل جميع مشاكلنا.
أولاً ، سيساعد على
الإيداع في عدة أنظمة مختلفة . معالجات جميع الأحداث لدينا التي سيتم جمعها من أي وقت مضى. بعد ذلك ، نحن نبحث عن الطريقة المطلوبة هنا. وفقًا لذلك ، إذا كان لدينا حدث مسار مكتوب ، على سبيل المثال ، في 4 أدوات تجميع ، فسيتم تخزينه في 4 نسخ. أي أنه في 4 دورات من الدورة ، سنجدها ونرسلها إلى جميع الأنظمة الأربعة مع المعلمات المقابلة.
ثانياً ،
يساعد على حل المشكلة مع الأحداث لمرة واحدة . هذه هي الأحداث التي يجب التعهد بها بدقة مرة واحدة لكامل دورة التطبيق. وضع علامة e.once ، المتغير المنطقي المعتاد. إذا قلنا أن هذا حدث لمرة واحدة ، فإننا ببساطة نحذفه من المجموعة. ماذا يحدث بعد ذلك إذا حاولنا أن نعيدها مرة أخرى؟ من الواضح أننا ببساطة لن نجدها في هذه المجموعة. يمكنك محاولة إطلاق النار على قدمك كما تشاء أثناء متابعة كتابة analyticsManager.track (AppStartEvent ()) ، وسيستمر هذا الأمر مرة واحدة ولن يكون هناك المزيد.
ما هو الربح؟
1.
نحن لا نكسر بنية تطبيقنا ، لأن AnalyticsManager يكمن ويعمل خارج الهيكل. هذا يتيح لنا تضمينه في أي جزء من التطبيق.
2.
يسمح لك بجمع أي أحداث في سطر واحد في أي عدد من أنظمة التحليل. للقيام بذلك ، نكتب ببساطة: analyticsManager.track (Event ()). لأنه بعد ذلك يحل هو نفسه أين ، وبأي كمية ، مع أي معلمات ، ومتى ، وهلم جرا.
3.
يحل مشكلة "الأحداث لمرة واحدة" . الآن نحن لسنا بحاجة للقيام بأنواع مختلفة من الشيكات. بمجرد إرسالها ، إزالتها ، ولن نلتقي به مرة أخرى.
4.
يحل مشكلة جمع نفس العنصر في أنظمة مختلفة . بسبب حقيقة أننا كتبنا كل شيء في جامعي مختلفين ، فقد ذهب إلى جامعي مختلفين. وبالتالي ، لا يتعين عليك اللجوء إلى الإيماءات غير الضرورية. في رأيي ، هذا رائع.
اختبار ...
نحن اختبار يدويا. لماذا لا أتمتة ، تسأل؟ وبعد ذلك يتحول شيء محزن.
أولاً ، لسوء الحظ ، لن تغطي هذا عادةً مع اختبار وحدة. لأن معظم مشاكل الأحداث في التحليلات لا تنشأ بسبب حقيقة أن بعض المعلمات التي لم تجمعها. في تجربتي الشخصية ، تنشأ 90٪ من المشكلات لأنك لم ترسل الحدث الذي كان من المفترض أن يذهب إليه. لا يمكن اكتشاف مثل هذه الحالات إلا في اختبارات واجهة المستخدم ، والتي لم نكتبها بعد لكل هذا.
وثانياً ، في الوقت الحالي ، نعتمد قليلاً على حقيقة أن المحللين يصفون الأحداث بتنسيق صارم إلى حد ما (في التقاء) ، ولكن هذا التنسيق ليس بتنسيق مواصفات صارم ، مثل Swagger. وفقًا لذلك ، هناك اختلافات طفيفة ، وهناك تكرارات (رغم أنه في هذه الحالة ، يتم إنشاء رابط لصفحة أخرى في الغالب). حتى الآن ، هذا يحدنا في إمكانات أتمتة اختبار التحليلات. لكننا نعمل على ذلك.
النتائج
ما الذي يمكن القيام به مع هذا القرار؟
1.
الكتابة autotests للتحليلات . هذا سوف يتطلب الكثير من العمل التحضيري. ولكن لا يمكن القول أن هذا مستحيل.
2. طرق تتبع زائد ناقص متشابهة جدا. في كل منها ، نولد بعض المعلمات "العالمية" التي يحتاجها الجميع. وجمع فقط خريطة القيم. بشكل عام ، يمكن للمرء
كتابة إما مكون إضافي أو أداة مساعدة . لا يهم الشيء الرئيسي هو أنها تولد حدثًا المسار للفصول المعنية.
ولكن قد تنشأ مشكلة صغيرة هنا إذا بدأت الأحداث تختفي بشكل مختلف قليلاً (على سبيل المثال ، لأنظمة تحليلية مختلفة). وبسبب هذا ، لا يمكن حل كل شيء بشكل كاف. وإلى جانب ذلك ، لا أريد إنتاج رمز غير ضروري في مشروع ، حيث يوجد الكثير في العديد من المشروعات على android (hello Dagger ، Moksi وغيرها من المشاريع التي تعمل على codegen).
3.
تكامل التطبيق مع مواصفات المحللين . ربما ، هذا حلم متسامٍ للغاية ، لكنه لا يزال ... نود حقاً أن يكتب محللونا بتنسيق صارم ، ويمكننا تحليل أعمالهم الفنية ودمجها. ثم يأتي السلام والوئام. الجميع سيكون سعيدا :)
إذن ماذا أريد أن أقول مع كل هذا؟
أولاً ، لا تزال هناك حاجة إلى التحليلات. لأنه يتيح لك توفير المال والموارد والجهد. هذا يوفر عليك كتابة التعليمات البرمجية غير الضرورية أو حذف التعليمات البرمجية التي يبدو أنها ليست قديمة ، ولكن لا تزال هناك حاجة هنا. إرث أقل دائما جيدة.
ثانياً ، التأمل ليس سيئًا دائمًا. نعم انها بطيئة. لكن في بعض الأحيان نخسر القليل في الأداء ، لكننا نحصل على الكثير ، على سبيل المثال ، في مجال التطوير ومعالجة الأخطاء.
وثالثا ، نحن نضع التحليلات في مرحلة تخطيط الميزة. نتيجة لهذا ، يمكننا التفاوض مع المحللين في وقت مبكر ، والتوصل إلى حل وسط. كما أنه يتيح لنا الفرصة لتقدير الوقت اللازم لكتابة التحليلات مقدما.