نسيان المشاكل ،
توقف الجري
حقن بواسطة الروبوتات
رجل سعيد!
من الفيلم "فاصل الطفولة" "الكترونيات المغامرات"
مرحبًا ، اليوم سنتحدث عن الأداء مرة أخرى. حول إنتاجية المطورين.
سأتحدث عن كيفية ضخ هذه المهارة من خلال الأفكار. آمل أن تأتي نصائحي في متناول يدي ، والتعليقات والتحسينات هي موضع ترحيب. دعنا نذهب!
يقضي المطور العادي جزءًا كبيرًا من يوم عمله في الأنشطة الروتينية. حتى وقت قريب ، لقد تصرفت أيضا. ثم ظهرت بعض الأفكار البسيطة والواضحة في رأسي:
- نادرا ما نكتب حقا شيء جديد وغير عادي
- جزء كبير من وقت العمل ، يكتب المطور رمز القالب
- العديد من الإنشاءات البسيطة التي نستخدمها قابلة للتشكيل بسهولة ، وفي رؤوسنا نعبر عنها بكلمات قليلة
إن حصة الأسد من الوقت الذي أعمل فيه مع Spring Booth / Hibernate ، لذا فإن معظم إنشاء الشفرات والقوالب تهمهم ، على الرغم من أن النهج عالمي ويمكنك بسهولة إجراء تحسينات مماثلة لمشاريعك.
يبدأ المسرح بشماعات ، ويبدأ تطبيق Spring Booth بالإعدادات. عادةً ما يتم تسجيلهم في ملف application.yml
/ application.properties
، لكن يحدث أيضًا أن بعض الفاصوليا / التكوينات يجب أن توصف برمز:
@Configuration @EnableSwagger2 class SwaggerConfig { @Bean Docket documentationApi() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } }
يتضمن هذا الإعداد Swagger (عنصر مفيد في المزرعة). التفكير في ما يمكن أن يكون آليا؟ يعرف المطورون أن @Configuration
يوضع فوق فئة الإعدادات. أي يمكنك إنشاء نوع فارغ - قالب من فئة التكوين وإنشائه بنقرة من المعصم. تتيح ميزة "Idea" للمستخدم إمكانية تخصيص القوالب الحالية لأنفسهم:

ماذا سوف نستخدم:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end import org.springframework.context.annotation.Configuration; @Configuration class ${NAME} { }
للمطورين ذوي الخبرة ، كل شيء واضح هنا ، للمبتدئين سأشرح:
السطر 1: سيتم إضافة سطر مثل هذا إلى رمز الفئة المنشأة حديثًا
package com.example.-;
السطر 2: توصيل التعليق التوضيحي المطلوب
السطر 3: فئة الجسم.
لاحظ أن المتغير ${NAME}
سوف يتحول إلى نافذة منبثقة حيث سنحتاج إلى إدخال اسم الفصل.
المجموع:

هذا القالب @Configuration
من الاضطرار إلى كتابة @Configuration
في الفصل بأيدينا وحل الاستيراد. ليس كثيرًا ، ولكن من المهم بالنسبة لنا أن نبدأ ونحصل على بعض الخبرة.
فئة إعدادات فارغة وحدها يستحق القليل. دعونا نتعلم كيفية إنشاء الفول دون بذل جهد إضافي. للقيام بذلك ، من المحرر> ملف وقوالب الكود ، انتقل إلى المحرر> القوالب المباشرة . يمكنك هنا وصف الأنماط التي تم التعرف عليها عن طريق الكتابة. في بيئة التطوير الخاصة بي ، قمت بتحديد نوع فرعي منفصل للاستخدام مع Spring. في ذلك نقوم بإنشاء قالب:
@Bean public $CLASS_NAME$ $mthdName$() { return new $CLASS_NAME$($END$); }
تم CLASS_NAME
متغير CLASS_NAME
بواسطة المستخدم في نافذة منبثقة ، بالإضافة إلى الواجب المباشر ، يُستخدم لإنشاء اسم طريقة:

يستخدم المتغير mthdName
طريقة camelCase()
، والتي يتم تمريرها بقيمة CLASS_NAME
. يتم الإعداد في تحرير المتغيرات :

المتغير $END$
يعني موضع المؤشر بعد التقديم. من المحتمل أن يكون للفاصوليا تبعيات (يتم تنفيذها من خلال المُنشئ) ، لذلك عليك أن تجعلها متغيرات على الطريقة التي تُرجع الفاصوليا:

الآن دعنا نذهب من خلال التطبيق من أعلى إلى أسفل ونرى ما يمكن تسريع المهام اليومية الأخرى بهذه الطريقة البسيطة.
خدمة
تشير الفطرة السليمة إلى أن هذه الطريقة ستكون مفيدة للغاية في الحالات التي يكون لدينا فيها عدد كبير من التعليمات البرمجية التي تتجول من مكان إلى آخر. على سبيل المثال ، من المحتمل أن تعتمد خدمة الزنبرك المنتظمة على المستودعات (مما يعني الحاجة إلى معاملات) ، ونوع ما من التسجيل ، ويتم تطبيق التبعيات من خلال المُنشئ. حتى لا يتم سرد جميع التعليقات التوضيحية على الفصل الذي تم إنشاؤه حديثًا في كل مرة ، نصف القالب:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java") import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; @Log4j2 @Service @Transactional @RequiredArgsConstructor public class ${NAME} { }
في العمل:

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

private final $CLASS_NAME$ $fieldName$; $END$
لكي لا تضغط على Ctrl + Alt + L (المحاذاة) في كل مرة ، قم بتمكين مربع إعادة التكوين وفقًا لمربع الاختيار الخاص بالأناقة وستقوم البيئة بكل شيء لك:

المستودعات والكيانات
حتى في أبسط الكيانات ، لدينا العديد من التعليقات التوضيحية. يمكنك إنشاء قالب فعال للغاية بالنسبة لهم:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java") import lombok.Getter; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Getter @Table @Entity public class ${NAME} { @Id private Long id; }

في عام 2019 ، إذا كنت تستخدم Hibernate ، فمن المؤكد أنك تستخدم Spring Date ، وإذا كان الأمر كذلك ، فأنت بحاجة إلى إنشاء مستودعات. دعنا تسريع إنشائها:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java") import org.springframework.data.jpa.repository.JpaRepository; public interface ${Entity_name}Repository extends JpaRepository<${Entity_name}, ${Key}>{ }

سيكون من الرائع إذا ، عند تعيين المؤشر على الكيان (الفئة المميزة بـ @Entity
و @Table
@Entity
) والضغط على Alt + Enter ، فإن "Idea" تقترح إنشاء مستودع على الفور ، لكنه ليس ذكيًا جدًا :). حاليًا ، ليس لدى المستخدمين القدرة على تغيير / إضافة النوايا ( محرر> النوايا ) ، ولكن يمكنك كتابة المكوّن الإضافي الخاص بك:

تجريب
بشكل عام ، كلما زاد إنشاء القالب في الشفرة ، زاد كسب الأتمتة. واحدة من أكثر قطع العمل تكرارًا هي الاختبارات. أولئك الذين شاهدوا تقرير Cyril Tolkachev "The Curse of the Spring Test" يعرفون أن هناك طريقة سهلة لجعل السياق يرتفع مرة واحدة فقط لجميع الاختبارات: إنشاء فئة مجردة ورث جميع الاختبارات منه.
وصف شيء من هذا القبيل
package com.example; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; import org.springframework.test.context.junit.jupiter.SpringExtension; @Transactional @SpringBootTest @ExtendWith(SpringExtension.class) public abstract class BaseTest { }
يمكننا بسهولة جعل جميع الاختبارات التي تم إنشاؤها حديثا ترث BaseTest
. للقيام بذلك ، تحتاج إلى تغيير القالب الذي ينشئ الاختبار الافتراضي:

في الكود:
import com.example.BaseTest; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; #parse("File Header.java") class ${NAME} extends BaseTest { ${BODY} }
التالي وصفنا التبعيات. لا اريد الاتصال في كل مرة
@Autowired private MyService service;
لذلك ، في القسم محرر> القوالب الحية ، والكتابة
@Autowired private $CLASS_NAME$ $fieldName$; $END$
يوصف المتغير $fieldName$
بالطريقة نفسها تمامًا كما في مثال إنشاء الحبة ، مع استثناء واحد: مباشرة بعد إنشاء حقل ، لا يتحول المؤشر إليه ، تحتاج إلى التحقق من تخطي إذا تم تعريفه :

بشكل أساسي ، هناك حاجة إلى @Autowired
فقط لحقول الفصول @Autowired
، لذا تأكد من تعيين الإعلان في المطبق في القائمة المنسدلة:

نحن ننظر:

بالمناسبة ، نظرًا لأننا نقوم بإنشاء اختبار لفئة معينة ، فلا شيء يمنعنا من تقديم التبعية اللازمة فورًا عند إنشائها ( toCamelCase()
لا يعمل هنا ، لذلك يتم استخدام السرعة ):
import com.example.demo.BaseTest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; #parse("File Header.java") class ${NAME} extends BaseTest { #set($bodyLength = $NAME.length() - 4) #set($field = $NAME.substring(0, 1).toLowerCase() + $NAME.substring(1, $bodyLength)) @Autowired private ${CLASS_NAME} ${field}; ${BODY} }

تشير تجربتي إلى أنه كلما أمكن ، يجب أن تكون جميع الاختبارات شاملة. حتى إذا تم التحقق من الخدمة التي تخرج الكيان وتقطع جزءًا من أحد حقولها ، فلا يزال من الأفضل الحصول على الكيان بأمانة ، أي من قاعدة البيانات. لذلك ، بالنسبة لمعظم الاختبارات ، آخذ بيانات صادقة من إحدى البيئات وقمت @Sql
قبل تشغيل الاختبار باستخدام @Sql
.
يجب أن يتم أخذ عينات البيانات يدويًا لكل مهمة ، ولكن ربطها بالاختبار المطلوب يمكن أن يكون آلياً بسهولة. مرة أخرى ، انتقل إلى المحرر> القوالب المباشرة ، قسم JUnit واكتب:
@Sql("/sql/$CLASS_NAME$.sql") $END$

الآن ، اكتب sql
، حصلنا على قائمة منسدلة بسجل واحد ، ونختار ما نحصل عليه:
@Sql("/sql/MyEntityRepositoryTest.sql") class MyEntityRepositoryTest extends BaseTest { }
يرجى ملاحظة أن الملف الذي نشير إليه غير موجود حتى الآن ، لذلك عند تشغيل الاختبار في شكله الخام ، فمن المؤكد أنه سيتعطل. ومع ذلك ، بدءًا من الإصدار 193.1617 ، تسلط Idea الضوء على ملف غير موجود ، والأهم من ذلك ، إنها تقترح إنشاؤه!

لواحق
واحدة من أقوى الأدوات هي إنشاء / إضافة التعليمات البرمجية باستخدام تعبيرات postfix (إنهاء). أبسط مثال:

هناك الكثير من الإكمالات ، يمكنك الاطلاع عليها جميعًا في قسم المحرر> عام> استكمال إتمام الإصلاح :

هناك أيضًا مجال لأنواع مختلفة من التجارب. بنفسي ، لقد انتهيت من الاستعاضة عن متغير في تعبير اختبار يستند إلى AssertJ :

في الحياة ، يبدو مثل هذا:

روابط مفيدة
إذا كنت ترغب في تحسين مهاراتك مع الفكرة ، فتأكد من مراجعة تقريرين رائعين:
انطون Arkhipov - العمل الفعال مع IntelliJ IDEA
تاجير فالييف - إعادة بيع الذرات في IntelliJ IDEA: نثني IDE لأنفسنا
هذا كل شيء ، نادراً ما يصرف انتباهك وتذكر أن الوقت هو موردنا الوحيد غير المتجدد حقًا.