พลังของเมทาดาทา: วิธีทำงานกับโค้ดสปาเก็ตตี้
ที่มา: Hackernoon เราทุกคนพยายามใช้วิธีการทั่วไปและรูปแบบที่ทราบเพื่อสร้างแอปพลิเคชันโดยใช้ความพยายามน้อยที่สุดและให้ผลกระทบสูงสุด เรามีไลบรารีที่ยอดเยี่ยมและเฟรมเวิร์กอันทรงพลังที่ดำเนินการตามปกติให้เรา เราใช้ทั้งหมดนี้เพื่อมุ่งเน้นเฉพาะตรรกะทางธุรกิจเท่านั้น อย่างไรก็ตาม การแสวงหานี้มักจะนำเราไปสู่โค้ดสปาเก็ตตี้ โดยเฉพาะอย่างยิ่งเมื่อเป็นเรื่องของการนำฟังก์ชันไปใช้โดยไม่มีโซลูชันสำเร็จรูป ในบทความนี้ ฉันต้องการแบ่งปันเครื่องมืออันทรงพลังอย่างหนึ่งที่นักพัฒนาบางคนไม่เห็นคุณค่าจากประสบการณ์ของฉัน เครื่องมือนี้มีอยู่ในภาษาการเขียนโปรแกรมส่วนใหญ่ และมักใช้ในหลายเฟรมเวิร์ก - คำอธิบายประกอบ
คุณชอบสปาเก็ตตี้ไหม?
ลองดูตัวอย่างที่ฉันเจอเมื่อสองสามปีก่อน ฉันจำเป็นต้องแยกวิเคราะห์สเปรดชีต Excel เพื่อใส่ข้อมูลที่แยกวิเคราะห์ลงในฐานข้อมูล ฉันยังต้องการรวบรวมข้อมูลบางส่วนจากฐานข้อมูลและสร้างสเปรดชีต สำหรับการนำไปใช้งาน ฉันใช้ไลบรารี Java ที่รู้จักกันดี - Apache POI API ของไลบรารีทำให้งานของคุณง่ายขึ้น เนื่องจากช่วยให้คุณสร้างแผ่นงาน แถว เซลล์ และองค์ประกอบอื่นๆ ได้ด้วยตนเอง นี่เป็นสิ่งที่ดีมาก แต่เมื่อจำเป็นต้องสร้างสเปรดชีต Excel ต่างๆ โค้ดจะไม่สามารถอ่านได้อย่างสมบูรณ์และไม่รองรับ ตามปกติแล้วแอปพลิเคชันเวอร์ชันแรกกลับกลายเป็นว่าแย่มาก การใช้งานประกอบด้วยคลาสข้อมูลที่แสดงถึงสตริงที่มีฟิลด์ทั้งหมดที่จำเป็นสำหรับการแยกวิเคราะห์ นอกจากนี้ยังมีตัวแยกวิเคราะห์ที่ช่อง Excel ถูกแยกวิเคราะห์ทีละเซลล์และวางลงในอินสแตนซ์คลาสข้อมูลที่สร้างขึ้นใหม่ ในตอนแรกโปรแกรมทำงานได้ดีมากและทำสิ่งที่ต้องการได้ ปัญหาเริ่มต้นเมื่อถึงเวลาที่ต้องแก้ไขบางอย่าง ไม่ได้อ่านรหัส แม้แต่ฉันซึ่งเป็นผู้เขียนโค้ดนี้ก็ยังไม่สามารถหาที่ที่เหมาะสมในการขึ้นบรรทัดใหม่เพื่อใช้ฟังก์ชันใหม่ที่ฉันต้องการได้ช่วยเหลือในคำอธิบายประกอบ
บันทึกแอปพลิเคชันจากโค้ดสปาเก็ตตี้คำอธิบายประกอบนี้ ในการกำจัดโค้ดที่ไม่รองรับ ฉันจำเป็นต้องย้ายตรรกะในการพิจารณาว่าคอลัมน์ใดที่จะแยกวิเคราะห์ ประเภทข้อมูลในเซลล์ และข้อมูลอื่นๆ ทั้งหมดไปยังตำแหน่งอื่น เมื่อต้องการทำสิ่งนี้ ฉันได้สร้างคำอธิบายประกอบซึ่งฉันระบุชื่อคอลัมน์สำหรับแต่ละฟิลด์คลาส ในคำอธิบายประกอบ ฉันยังเพิ่มตัวแปรที่ช่วยให้คุณสามารถเลือกสีและแบบอักษรของเซลล์ได้ ดังนั้นโค้ดในคลาสการแยกวิเคราะห์จึงลดลงอย่างมาก โปรเซสเซอร์เพียงตัวเดียวเท่านั้นที่สร้างสเปรดชีตแบบไดนามิกตามพารามิเตอร์ที่นำมาจากคำอธิบายประกอบ มันเป็นชัยชนะ จากนั้น หากต้องการเปลี่ยนแปลงแอปพลิเคชัน ฉันเพียงแค่ต้องสร้างคลาสที่มีคำอธิบายประกอบ วิธีแก้ปัญหานี้ชวนให้นึกถึงไลบรารีของ Jackson ซึ่งแยกวิเคราะห์ JSON โดยใช้คำอธิบายประกอบ และฉันคิดว่าไม่จำเป็นต้องบอกว่า Jackson หรือไลบรารีที่คล้ายกันสะดวกเพียงใด@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ColumnExcel {
String name() default "";
int position();
ExcelColumnDataFormat cellTypePattern() default ExcelColumnDataFormat.NONE;
IndexedColors cellColor() default IndexedColors.AUTOMATIC;
ExcelTotalFormula total() default ExcelTotalFormula.NONE;
}
ColumnExcel columnExcel = field.getAnnotation(ColumnExcel.class);
เมื่อแอปพลิเคชันพัฒนาขึ้น ก็ได้รับคำอธิบายประกอบใหม่ที่สามารถใช้เพื่อสร้างเซลล์ในสเปรดชีตที่มีฟังก์ชันอยู่ข้างใน เขตข้อมูลต่างๆ สามารถคูณ ลบ และสามารถใช้ฟังก์ชัน Excel ทั่วไปได้ ฉันยังเพิ่มแถวผลรวมเพื่อแสดงผลรวมตามคอลัมน์ และฉันทำทั้งหมดนี้เพียงแค่แก้ไข parser หลักเล็กน้อยและเพิ่มคำอธิบายประกอบให้กับคลาส
@ColumnExcel(
name = "Views",
position = 4,
total = ExcelTotalFormula.SUM)
private BigDecimal variableC;
@ColumnExcelFormula(
name = "Conversion",
position = 5,
cellTypePattern = CellDataTypeFormatPattern.PERCENTAGE
)
public String variableD(int rowNumber) {
return new CellAddress(rowNumber, 4).formatAsString() + "*"
+ new CellAddress(rowNumber, 2).formatAsString();
}
@ColumnExcelTotalFormula(position = 4, cellTypePattern = CellDataTypeFormatPattern.RUR)
public static String getVariableCTotalFormula(int firstRowNum, int lastRowNum) {
return "SUM( " + new CellAddress(firstRowNum, 4).formatAsString() + ":"
+ new CellAddress(lastRowNum, 4).formatAsString() + ")";
}
การรวบรวมขยะใน Java - วิธีการทำงานและข้อดีของมันคืออะไร
ที่มา: Dev.to Garbage collection หมายถึงการทำลายหรือล้างวัตถุที่ไม่ได้ใช้ในหน่วยความจำ Java จัดการการจัดสรรหน่วยความจำโดยอัตโนมัติเนื่องจากเมื่อวัตถุถูกสร้างขึ้น มันจะใช้หน่วยความจำบางส่วนบนฮีป
มันทำงานอย่างไร?
ก่อน Java ภาษาโปรแกรมยอดนิยมคือ C หรือ C++ หากคุณพูดภาษาเหล่านี้ คุณควรรู้ว่าพวกเขาจัดการหน่วยความจำของตนเองด้วยตนเอง ตัวอย่างเช่น C มีเมธอดเช่นcalloc() , malloc()และrealloc()ที่จะช่วยให้คุณใช้หน่วยความจำบัฟเฟอร์ได้ คุณต้องกำหนดจำนวนหน่วยความจำที่คุณต้องการสำหรับโปรแกรมของคุณและระบุสิ่งที่เรียกโดย API นี้ จากนั้นคุณจะได้รับบัฟเฟอร์หน่วยความจำเพื่อสร้างโหนดรายการที่เชื่อมโยงหรืออย่างอื่น เมื่อโปรแกรมของคุณหยุดทำงาน คุณยังต้องรับผิดชอบในการล้างหน่วยความจำนั้นด้วย ดังนั้นแอปพลิเคชันขนาดใหญ่ที่เขียนด้วยภาษา C จะจัดสรรหน่วยความจำบัฟเฟอร์และบางครั้งก็ลืมล้างข้อมูล ในที่สุดสิ่งนี้ทำให้เกิดการรั่วไหลของหน่วยความจำและปัญหามากมายในแอปพลิเคชัน ภาษา Java ต่างจาก C และ C++ ตรงที่มีการจัดการหน่วยความจำอัตโนมัติผ่านเธรดที่เรียกว่าตัวรวบรวมขยะ วัตถุประสงค์หลักคือเพื่อเพิ่มหน่วยความจำฮีปโดยการทำลายวัตถุที่ไม่สามารถเข้าถึงได้ ตัวรวบรวมขยะจะทำงานอยู่เบื้องหลังเสมอวัตถุที่ไม่สามารถเข้าถึงได้ใน Java คืออะไร?
วัตถุจะมีโอกาสเริ่มเก็บขยะเมื่อใด หากมีวัตถุที่ไม่สามารถเข้าถึงได้ - วัตถุที่ไม่มีลิงก์ที่ใช้งานอยู่ ลองดูตัวอย่าง:public static void main(String[] args)
{
// StringBuffer object sb is not eligible for garbage collection
StringBuffer sb = new StringBuffer("Flower Brackets");
System.out.println(sb);
// StringBuffer object sb is eligible for garbage collection
sb = null;
}
ในวิธีการหลัก ฉันได้สร้าง วัตถุ StringBufferและการอ้างอิงถึงมัน ณ จุดนี้ วัตถุ StringBufferไม่มีสิทธิ์สำหรับการรวบรวมขยะ ตอนนี้ฉันจะตั้ง ค่าวัตถุ StringBufferเป็น "null" ขณะนี้วัตถุมีสิทธิ์สำหรับการรวบรวมขยะและกลายเป็นวัตถุที่ไม่สามารถเข้าถึงได้ในหน่วยความจำฮีป นั่นคือ โดยทั่วไปการรวบรวมขยะจะใช้ได้ในกรณีที่วัตถุไม่สามารถเข้าถึงได้ ซึ่งหมายความว่าวัตถุมักจะถูกสร้างขึ้นในบริบทของ "if block" หรือวิธีการ ดังนั้นออบเจ็กต์จะออกจากขอบเขตเมื่อการดำเนินการวิธีการเสร็จสิ้นและผู้รวบรวมขยะสามารถกำจัดทิ้งได้ เนื่องจากการอ้างอิงจากอ็อบเจ็กต์เก่าไปยังอ็อบเจ็กต์ใหม่นั้นมีอยู่ในจำนวนที่จำกัด ซึ่งหมายความว่าอ็อบเจ็กต์ที่มีอยู่ในแอปพลิเคชันของคุณมาเป็นเวลานานมักจะไม่ใช่อ็อบเจ็กต์ที่สร้างขึ้นใหม่ ต่อไปนี้เป็นคำศัพท์สองสามคำที่เราควรทำความคุ้นเคย หนึ่งในนั้นคือวัตถุที่มีชีวิต เป็นวัตถุในแอปพลิเคชันที่ถูกอ้างอิงโดยวัตถุอื่นในแอปพลิเคชันเดียวกัน มีวัตถุ "ตาย" อยู่ด้วย วัตถุที่ไม่ทำงานเป็นวัตถุที่ไม่สามารถเข้าถึงได้ซึ่งถูกสร้างขึ้นในระหว่างการเรียกเมธอด และเมื่อการเรียกเมธอดเสร็จสิ้น วัตถุนั้นจะไม่อยู่ในบริบทและอยู่บนฮีป
วัตถุจะมีสิทธิ์ในการรวบรวมขยะเมื่อใด
หากออบเจ็กต์ไม่มีตัวแปรอ้างอิงใดๆ แสดงว่าออบเจ็กต์นั้นมีสิทธิ์สำหรับการรวบรวมขยะจะทำให้วัตถุพร้อมสำหรับการรวบรวมขยะได้อย่างไร?
ด้านล่างมีหลายวิธี:-
null reference variable Student obj = new Student(); obj = null;
-
re-assign reference variable Student obj1 = new Student(); Student obj2 = new Student(); obj1 = obj2;
-
reate anonymous object new Student();
เมื่อวัตถุถูกจัดเตรียมให้กับคนเก็บขยะแล้ว มันจะไม่ถูกทำลายในทันที
-
วิธีการSystem.gc()
-
วิธีการสรุป ()
-
Runtime.getRuntime().gc()วิธีการ
public class GarbageCollector
{
public static void main(String[] args)
{
Employee obj1 = new Employee();
Employee obj2 = new Employee();
obj1 = null;
obj2 = null;
System.gc();
}
public void finalize()
{
System.out.println("object garbage collected");
}
}
ผลลัพธ์:
รวบรวมขยะวัตถุ รวบรวมขยะวัตถุ
เมธอดFinalize()ถูกเรียกก่อนที่วัตถุจะถูกล้างข้อมูล วิธีการนี้ถูกกำหนดไว้ใน คลาส Object :
protected void finalize() throws Throwable
-
วิธีการFinalizeใช้เพื่อปิดการเชื่อมต่อกับฐานข้อมูล
-
เมธอดนี้ถูกเรียกโดยตัวรวบรวมขยะ ไม่ใช่ JVM
-
เรา จำเป็นต้องแทนที่ เมธอด Finalize() เนื่องจากมีการดำเนินการที่ว่างเปล่า
-
มันถูกเรียกเพียงครั้งเดียวต่อวัตถุ
public class Demo
{
public static void main(String[] args)
{
Demo obj1 = new Demo();
Demo obj2 = new Demo();
// nullifying reference variable
obj1 = null;
// nullifying reference variable
obj2 = null;
// running Garbage Collector
Runtime.getRuntime().gc();
}
@Override
protected void finalize() throws Throwable
{
System.out.println("Garbage collector called");
System.out.println("Object garbage collector: " + this);
}
}
ผลลัพธ์:
ตัวรวบรวมขยะที่เรียกว่าตัวรวบรวมขยะวัตถุ: Demo@2130772 ตัวรวบรวมขยะที่เรียกว่าตัวรวบรวมขยะวัตถุ: Demo@cd4e940
ประโยชน์ของการเก็บขยะ:
- การรวบรวมขยะใน Java เกิดขึ้นโดยอัตโนมัติ ซึ่งช่วยเราจากภาระเพิ่มเติมในการเพิ่มหน่วยความจำที่ใช้แล้ว ทำให้หน่วยความจำของโปรแกรม Java มีประสิทธิภาพมากขึ้น
- การรวบรวมขยะช่วยให้มั่นใจถึงความสมบูรณ์ของโปรแกรม
- เราไม่จำเป็นต้องเขียนโค้ดเพิ่มเติมใดๆ เนื่องจากตัวรวบรวมขยะเป็นส่วนหนึ่งของ JVM
GO TO FULL VERSION