JavaRush /בלוג Java /Random-HE /הפסקת קפה מס' 124. דפוס עיצוב בונה. כיצד פועלים סריאליזצי...

הפסקת קפה מס' 124. דפוס עיצוב בונה. כיצד פועלים סריאליזציה ודה-סריאליזציה ב-Java

פורסם בקבוצה

דפוס עיצוב Builder ב-Java

מקור: בינוני במאמר זה, נלמד כיצד לעצב וליצור אובייקטים עבור מחלקה באמצעות דפוס העיצוב של Builder . הפסקת קפה מס' 124.  דפוס עיצוב בונה.  כיצד פועלים סריאליזציה ודה-סריאליזציה ב-Java - 1

למה אנחנו צריכים את דפוס העיצוב של Builder?

תבנית ה- Builder נועדה ליצור אובייקטים באמצעות מחלקה סטטית ציבורית מקוננת שיש לה אותם שדות נתונים כמו המחלקה החיצונית. תבנית ה- Builder נוצרה כדי לפתור בעיות שהיו קיימות בדפוסי העיצוב של Factory ו- Abstract Factory כאשר אובייקט מחלקה מכיל ערכי שדה ו/או נתונים רבים. לפני שנעבור לדפוס ה- Builder , הבה נבחן בדיוק אילו בעיות מתעוררות בדפוסי המפעל והמופשט של המפעל עבור תרחישים שבהם לאובייקט יש ערכי שדה רבים:
  1. יותר מדי ארגומנטים לעבור מתוכנת הלקוח למחלקה Factory עלול לגרום לשגיאות מכיוון שלרוב סוג הארגומנט זהה וקשה בצד הלקוח לשמור על סדר הארגומנטים.

  2. חלק מהפרמטרים עשויים להיות אופציונליים, אבל בתבנית Factory אנחנו נאלצים לשלוח את כל הפרמטרים, ויש לשלוח פרמטרים אופציונליים כקבצי NULL .

  3. אם האובייקט הוא "כבד" ועם עיצוב מורכב, אז כל הקשיים האלה יהפכו לחלק משיעורי המפעל, מה שמוביל לעתים קרובות לבלבול.

ניתן לפתור את הבעיות לעיל כאשר לאובייקט יש מספר רב של פרמטרים. כדי לעשות זאת, אתה פשוט צריך לספק לבנאי את הפרמטרים הנדרשים, ולאחר מכן שיטות מגדיר שונות כדי להגדיר את הפרמטרים האופציונליים. שים לב שהבעיה בשיטה זו היא שמצב האובייקט יישאר לא עקבי אלא אם כל התכונות מוגדרות בבירור.

מהי דפוס העיצוב של Builder?

דפוס ה- Builder פותר את הבעיה של הרבה פרמטרים אופציונליים ומצבים לא עקביים על ידי מתן דרך לבנות אובייקט צעד אחר צעד. זה משתמש בשיטה שלמעשה מחזירה את האובייקט הסופי.

כיצד ליישם את דפוס העיצוב של Builder ב-Java?

אם נבצע את השלבים שלהלן, נקבל את התהליך שלב אחר שלב של יצירת אובייקט ושליפה שלו:
  1. צור מחלקה מקוננת סטטית כמחלקת Builder , ולאחר מכן העתק את כל השדות מהמחלקה החיצונית למחלקה Builder . עלינו לעקוב אחר מוסכמות שמות, כך שאם שם המחלקה הוא Person , אז המחלקה Builder צריכה להיקרא PersonBuilder .

  2. למחלקה Builder חייב להיות בנאי ציבורי עם כל השדות הנדרשים כפרמטרים.

  3. למחלקה Builder חייבות להיות שיטות להגדרת פרמטרים אופציונליים, והיא חייבת להחזיר את אותו אובייקט Builder לאחר הגדרת השדה האופציונלי.

  4. השלב האחרון הוא לספק מתודה build() במחלקה Builder , שתחזיר את האובייקט הדרוש לתוכנית הלקוח. לשם כך אנחנו צריכים בנאי פרטי במחלקה הראשית עם המחלקה Builder כטיעון.

דוגמא:

בואו נסתכל על דוגמה כדי לקבל הבנה ברורה של דפוס העיצוב של Builder .
public class Employee {

    private String name;
    private String company;
    private boolean hasCar;//optional
    private boolean hasBike;//optional

    private Employee(EmployeeBuilder employeeBuilder) {
        name = employeeBuilder.name;
        company = employeeBuilder.company;
        hasCar = employeeBuilder.hasCar;
        hasBike = employeeBuilder.hasBike;
    }

    public String getName() {
        return name;
    }

    public String getCompany() {
        return company;
    }

    public boolean isHasCar() {
        return hasCar;
    }

    public boolean isHasBike() {
        return hasBike;
    }

    public static class EmployeeBuilder {
        private String name;
        private String company;
        private boolean hasCar;//optional
        private boolean hasBike;//optional

        //constructor for required fields
        public EmployeeBuilder(String name, String company) {
            this.name = name;
            this.company = company;
        }

        //setter methods for optional fields
        public EmployeeBuilder setHasCar(boolean hasCar) {
            this.hasCar = hasCar;
            return this;
        }

        public EmployeeBuilder setHasBike(boolean hasBike) {
            this.hasBike = hasBike;
            return this;
        }

        //Build the Employee object
        public Employee build() {
            return new Employee(this);
        }
    }
}

class TestBuilder {
    public static void main(String[] args) {
        //Building the object of Employee thru the build() method provided in EmployeeBuilder class.
        Employee employee = new Employee.EmployeeBuilder("Vikram", "ABC").setHasBike(false).setHasBike(true).build();
    }
}
דוגמה לתבנית Builder : java.lang.StringBuilder ו- java.lang.StringBuffer השתמשו בתבנית Builder כדי לבנות אובייקטים.

כיצד פועלים סריאליזציה ודה-סריאליזציה ב-Java

מקור: בינוני עברתי לג'אווה בינואר השנה לאחר התמחות. לפני זה, כתבתי בעיקר ב-PHP ומעט JavaScript. מעולם לא נתקלתי בסריאליזציה לפני כן, למרות שהסדרה קיימת למעשה ב-PHP. נכון, ב-Java משתמשים בזה הרבה יותר. היום אציג בפניכם את אופן הפעולה של סריאליזציה וסידריאליזציה ב-Java וכמה דרכים להשתמש בהן.

מהי סריאליזציה וסריאליזציה

סריאליזציה היא הפיכת אובייקט ממחלקה לרצף של בתים ב-Java Virtual Machine (JVM) לשידור ל-Java Virtual Machine אחר. אם ה-Java Virtual Machine יוצר מחדש אובייקט מבייטים, התהליך נקרא דה-סריאליזציה.

דוגמה לסריאליזציה וסריאליזציה

סדרה

בואו ניצור מחלקה שהאובייקט שלה יעבור בסידרה:
import java.io.*;

public class Person implements Serializable{

int id = 0;
String name = "empty";

public Person(int identity, String nomenclature) {

name = nomenclature;
id = identity;
}
}
המחלקה Person מיישמת את Serializable כך שניתן להסיד/לבטל את האובייקט שלה. למחלקה Person יש שני שדות: מזהה ושם, המשתנים מערך ברירת המחדל כאשר מופע של המחלקה נוצר. הממשק Serializable ומחלקות אחרות המשמשות בתוכנית יובאו לחבילת Java.io.
public static void main(String[] args) throws FileNotFoundException, IOException {

String filename = "filename here";
Person person = new Person(1, "John");

// serialization
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename));

try {

out.writeObject(person);
System.out.println("Success");
} catch(Exception e) {

System.out.println("Unsuccessful");
} finally {

if(out != null) {

out.close();
}
}
}
כידוע, השיטה הראשית מתחילה את ההסדרה ומדפיסה הודעת הצלחה, אחרת מודפסת הודעת שגיאה. כדי לבצע סדרה של אובייקטים אנו משתמשים ב- ObjectOutputStream ובמתודה writeObject .

דה-סריאליזציה

public static void main(String[] args) throws FileNotFoundException, IOException {

String filename = "filename here";
Person person = new Person(1, "John");

// Deserialization
ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));

try {

Person personObj = (Person)in.readObject();
System.out.println("Person Id is " +personObj.id + " while name is " + personObj.name);
} catch (Exception e) {

e.printStackTrace();
} finally {

if(in != null) {

in.close();
}
}
}
דה-סריאליזציה היא ההיפך של סריאליזציה. כדי לבנות מחדש אובייקט מרצף של בתים, השתמש ב- ObjectInputStream ובמתודה readObject . שים לב שכדי לספק גישה לשדות במחלקה Person , האובייקט מועבר לסוג הנתונים Person . אובייקט מחלקה שאינו מיישם את ממשק הסדרת לא ניתן להסיד. לכן, כל מחלקה שמתייחסת למחלקה שמיישמת ממשק סריאליזציה חייבת בעצמה ליישם את ממשק ההמשכה, אחרת יזרק חריגה. סריאליזציה היא בלתי תלויה בפלטפורמה, כלומר זרם הבתים המועבר בסידרה יכול להיות מובטל על ידי מכונה וירטואלית אחרת של Java. שדות סטטיים וחולפים אינם ניתנים לסידרה, כך שאם יש לך שדה שאינך רוצה לעשות אותו בסידרה, הפוך אותו לזמני או סטטי. במקרה של שדה סטטי, הוא לא מסודר מכיוון ששדה סטטי שייך למחלקה ולא לאובייקט. בגלל זה, מצב המעבר מונע מהשדה להיות סידורי. נעשה שימוש בסריאליזציה ב-Hibernate, JPA ו-RMI. ניתן להתאים אישית גם סידורי סידור. זה נקרא סדרה מותאמת אישית.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION