CodeGym /Java Blog /এলোমেলো /জাভাতে বহিরাগত ইন্টারফেস
John Squirrels
লেভেল 41
San Francisco

জাভাতে বহিরাগত ইন্টারফেস

এলোমেলো দলে প্রকাশিত
ওহে! আজ আমরা জাভা অবজেক্টের সিরিয়ালাইজেশন এবং ডিসিরিয়ালাইজেশন জানতে পারব । শেষ পাঠে, আমরা সিরিয়ালাইজেবল মার্কার ইন্টারফেস জানতে পেরেছি, এর ব্যবহারের উদাহরণ পর্যালোচনা করেছি, এবং এছাড়াও শিখেছি কিভাবে আপনি সিরিয়ালাইজেশন প্রক্রিয়া নিয়ন্ত্রণ করতে ক্ষণস্থায়ী কীওয়ার্ড ব্যবহার করতে পারেন। ঠিক আছে, আমরা 'প্রক্রিয়া নিয়ন্ত্রণ করি' বললে এটাকে অতিবৃদ্ধি করা হতে পারে। আমাদের কাছে একটি কীওয়ার্ড, একটি সংস্করণ শনাক্তকারী রয়েছে এবং এটি এটি সম্পর্কে। বাকি প্রক্রিয়া জাভার ভিতরে লুকানো আছে, এবং আমরা এটি অ্যাক্সেস করতে পারি না। অবশ্যই, সুবিধার দিক থেকে, এটি ভাল। কিন্তু একজন প্রোগ্রামারকে শুধুমাত্র তার নিজের স্বাচ্ছন্দ্য দ্বারা পরিচালিত হওয়া উচিত নয়, তাই না? :) আপনি বিবেচনা করা প্রয়োজন যে অন্যান্য কারণ আছে. সেজন্য সিরিয়ালাইজেবলজাভাতে সিরিয়ালাইজেশন-ডিসারিয়ালাইজেশনের একমাত্র প্রক্রিয়া নয়। আজ আমরা Externalizable ইন্টারফেসের সাথে পরিচিত হব । কিন্তু আমরা এটি অধ্যয়ন শুরু করার আগে, আপনার একটি যুক্তিসঙ্গত প্রশ্ন থাকতে পারে: কেন আমাদের অন্য ব্যবস্থার প্রয়োজন? Serializableএর কাজ করেছে, এবং পুরো প্রক্রিয়াটির স্বয়ংক্রিয় বাস্তবায়ন সম্পর্কে কী পছন্দ করা উচিত নয়? এবং আমরা যে উদাহরণগুলি দেখেছি তাও জটিল ছিল না। তো সমস্যাটা কী? কেন আমরা অপরিহার্যভাবে একই কাজের জন্য অন্য ইন্টারফেস প্রয়োজন? আসল বিষয়টি হ'ল এর Serializableবেশ কয়েকটি ত্রুটি রয়েছে। আমরা তাদের কিছু তালিকাভুক্ত করি:
  1. কর্মক্ষমতা. ইন্টারফেসের Serializableঅনেক সুবিধা রয়েছে, তবে উচ্চ কার্যকারিতা স্পষ্টতই তাদের মধ্যে একটি নয়।

    এক্সটারনালাইজেবল ইন্টারফেস প্রবর্তন - 2

    প্রথমত, Serializable এর অভ্যন্তরীণ বাস্তবায়ন প্রচুর পরিমাণে পরিষেবা তথ্য এবং সমস্ত ধরণের অস্থায়ী ডেটা তৈরি করে।

    দ্বিতীয়ত, Serializable প্রতিফলন API এর উপর নির্ভর করে (আপনাকে এখনই এটির গভীরে ডুব দিতে হবে না; আপনি যদি আগ্রহী হন তবে আপনি আপনার অবসর সময়ে আরও পড়তে পারেন)। এই জিনিসটি আপনাকে জাভাতে আপাতদৃষ্টিতে অসম্ভব জিনিসগুলি করতে দেয়: উদাহরণস্বরূপ, ব্যক্তিগত ক্ষেত্রের মান পরিবর্তন করুন। CodeGym-এর প্রতিফলন API সম্পর্কে একটি চমৎকার নিবন্ধ রয়েছে । আপনি সেখানে এটি সম্পর্কে পড়তে পারেন.

  2. নমনীয়তা. আমরা যখন ইন্টারফেস ব্যবহার করি তখন আমরা সিরিয়ালাইজেশন-ডিসারিয়ালাইজেশন প্রক্রিয়া নিয়ন্ত্রণ করি না Serializable

    একদিকে, এটি খুব সুবিধাজনক, কারণ আমরা যদি পারফরম্যান্স সম্পর্কে বিশেষভাবে উদ্বিগ্ন না হই, তাহলে কোড লিখতে হবে না বলে মনে হয়। কিন্তু সিরিয়ালাইজেশন লজিকে যদি সত্যিই আমাদের নিজস্ব কিছু বৈশিষ্ট্য (আমরা নীচে একটি উদাহরণ প্রদান করব) যোগ করার প্রয়োজন হয়?

    মূলত, আমাদের সমস্ত প্রক্রিয়া নিয়ন্ত্রণ করতে হবে তা হল transientকিছু ডেটা বাদ দেওয়ার কীওয়ার্ড। এটাই. এটি আমাদের সম্পূর্ণ টুলবক্স :/

  3. নিরাপত্তা এই আইটেমটি পূর্ববর্তী আইটেম থেকে অংশে প্রাপ্ত.

    আমরা আগে এই বিষয়ে চিন্তা করার জন্য খুব বেশি সময় ব্যয় করিনি, তবে আপনার ক্লাসের কিছু তথ্য যদি অন্যদের চোখ ও কানের জন্য উদ্দিষ্ট না হয় তবে কী হবে? একটি সাধারণ উদাহরণ হল একটি পাসওয়ার্ড বা অন্যান্য ব্যক্তিগত ব্যবহারকারীর ডেটা, যা আজকের বিশ্বে একগুচ্ছ আইন দ্বারা পরিচালিত হয়৷

    যদি আমরা ব্যবহার করি Serializable, আমরা সত্যিই এটি সম্পর্কে কিছুই করতে পারি না। আমরা সবকিছু যেমন আছে সিরিয়াল করি।

    কিন্তু যদি আমরা এটি সঠিকভাবে করি, তাহলে আমাদের অবশ্যই এই ধরনের ডেটা একটি ফাইলে লেখার আগে বা নেটওয়ার্কে পাঠানোর আগে এনক্রিপ্ট করতে হবে। কিন্তু Serializableএটা সম্ভব করে না।

এক্সটারনালাইজেবল ইন্টারফেস প্রবর্তন - 3আচ্ছা, চলুন শেষ পর্যন্ত দেখা যাক ইন্টারফেস ব্যবহার করলে ক্লাস কেমন দেখাবে Externalizable

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class UserInfo implements Externalizable {

   private String firstName;
   private String lastName;
   private String superSecretInformation;

private static final long SERIAL_VERSION_UID = 1L;

   // ...constructor, getters, setters, toString()...

   @Override
   public void writeExternal(ObjectOutput out) throws IOException {

   }

   @Override
   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {

   }
}
আপনি দেখতে পারেন, আমরা উল্লেখযোগ্য পরিবর্তন আছে! প্রধানটি সুস্পষ্ট: Externalizableইন্টারফেস বাস্তবায়ন করার সময়, আপনাকে অবশ্যই দুটি প্রয়োজনীয় পদ্ধতি প্রয়োগ করতে হবে: writeExternal()এবংreadExternal(). আমরা আগেই বলেছি, সিরিয়ালাইজেশন এবং ডিসিরিয়ালাইজেশনের দায়িত্ব প্রোগ্রামারের উপর বর্তায়। কিন্তু এখন আপনি প্রক্রিয়ার উপর কোন নিয়ন্ত্রণের সমস্যা সমাধান করতে পারেন! পুরো প্রক্রিয়াটি সরাসরি আপনার দ্বারা প্রোগ্রাম করা হয়। স্বাভাবিকভাবেই, এটি অনেক বেশি নমনীয় প্রক্রিয়ার অনুমতি দেয়। উপরন্তু, নিরাপত্তা সঙ্গে সমস্যা সমাধান করা হয়. আপনি দেখতে পাচ্ছেন, আমাদের ক্লাসে একটি ব্যক্তিগত ডেটা ক্ষেত্র রয়েছে যা এনক্রিপ্ট ছাড়া সংরক্ষণ করা যায় না। এখন আমরা সহজেই কোড লিখতে পারি যা এই সীমাবদ্ধতাকে সন্তুষ্ট করে। উদাহরণস্বরূপ, আমরা আমাদের ক্লাসে সংবেদনশীল ডেটা এনক্রিপ্ট এবং ডিক্রিপ্ট করার জন্য দুটি সাধারণ ব্যক্তিগত পদ্ধতি যুক্ত করতে পারি। আমরা ফাইলটিতে ডেটা লিখব এবং এনক্রিপ্ট করা আকারে ফাইল থেকে পড়ব। বাকি ডেটা যেমন আছে তেমন লেখা ও পড়া হবে :) ফলস্বরূপ, আমাদের ক্লাসটি এরকম কিছু দেখায়:

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Base64;

public class UserInfo implements Externalizable {

   private String firstName;
   private String lastName;
   private String superSecretInformation;

   private static final long serialVersionUID = 1L;

   public UserInfo() {
   }

   public UserInfo(String firstName, String lastName, String superSecretInformation) {
       this.firstName = firstName;
       this.lastName = lastName;
       this.superSecretInformation = superSecretInformation;
   }

   @Override
   public void writeExternal(ObjectOutput out) throws IOException {
       out.writeObject(this.getFirstName());
       out.writeObject(this.getLastName());
       out.writeObject(this.encryptString(this.getSuperSecretInformation()));
   }

   @Override
   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
       firstName = (String) in.readObject();
       lastName = (String) in.readObject();
       superSecretInformation = this.decryptString((String) in.readObject());
   }

   private String encryptString(String data) {
       String encryptedData = Base64.getEncoder().encodeToString(data.getBytes());
       System.out.println(encryptedData);
       return encryptedData;
   }

   private String decryptString(String data) {
       String decrypted = new String(Base64.getDecoder().decode(data));
       System.out.println(decrypted);
       return decrypted;
   }

   public String getFirstName() {
       return firstName;
   }

   public String getLastName() {
       return lastName;
   }

   public String getSuperSecretInformation() {
       return superSecretInformation;
   }
}
আমরা দুটি পদ্ধতি প্রয়োগ করেছি যা একই ObjectOutputএবং ObjectInputপরামিতিগুলি ব্যবহার করে যা আমরা ইতিমধ্যে পাঠে দেখেছি Serializable। সঠিক মুহুর্তে, আমরা প্রয়োজনীয় ডেটা এনক্রিপ্ট বা ডিক্রিপ্ট করি এবং আমরা আমাদের অবজেক্টকে সিরিয়ালাইজ করতে এনক্রিপ্ট করা ডেটা ব্যবহার করি। চলুন দেখি এটি অনুশীলনে কেমন দেখায়:

import java.io.*;

public class Main {

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

       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

       UserInfo userInfo = new UserInfo("Paul", "Piper", "Paul Piper's passport data");

       objectOutputStream.writeObject(userInfo);

       objectOutputStream.close();

   }
}
encryptString()এবং পদ্ধতিতে decryptString(), আমরা বিশেষভাবে কনসোল আউটপুট যোগ করেছি ফর্ম যাচাই করার জন্য যেখানে গোপন ডেটা লেখা এবং পড়া হবে। উপরের কোডটি নিম্নলিখিত লাইনটি প্রদর্শন করেছে: SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRh এনক্রিপশন সফল হয়েছে! ফাইলটির সম্পূর্ণ বিষয়বস্তু দেখতে এইরকম: ¬н sr UserInfoГ!}ҐџC‚ћ xpt Ivant Ivanovt $SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRhx এখন আমাদের ডিসিরিয়ালাইজেশন লজিক ব্যবহার করার চেষ্টা করা যাক।

public class Main {

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

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);


       UserInfo userInfo = (UserInfo) objectInputStream.readObject();
       System.out.println(userInfo);

       objectInputStream.close();

   }
}
ঠিক আছে, এখানে কিছুই জটিল বলে মনে হচ্ছে না। এটার কাজ করা উচিত! আমরা এটি চালাই এবং পাই... "প্রধান" থ্রেডে ব্যতিক্রম java.io.InvalidClassException: UserInfo; কোনো বৈধ কনস্ট্রাক্টর নেই এক্সটারনালাইজেবল ইন্টারফেস প্রবর্তন - 4 উফ! :( দৃশ্যত, এটা এত সহজ নয়! ডিসিরিয়ালাইজেশন মেকানিজম একটি ব্যতিক্রম ছুড়ে দিয়েছে এবং দাবি করেছে যে আমরা একটি ডিফল্ট কনস্ট্রাক্টর তৈরি করব৷ আমি ভাবছি কেন৷ এর সাথে, আমরা Serializableএকটি ছাড়াই পেয়েছিলাম... :/ এখানে আমরা আরেকটি গুরুত্বপূর্ণ সূক্ষ্মতার সম্মুখীন হয়েছি৷ পার্থক্য Serializableশুধুমাত্র Externalizableপ্রোগ্রামারের 'প্রসারিত' অ্যাক্সেস এবং প্রক্রিয়াটিকে আরও নমনীয়ভাবে নিয়ন্ত্রণ করার ক্ষমতার মধ্যে নয়, বরং প্রক্রিয়ার মধ্যেও রয়েছে। সর্বোপরি, ডিসিরিয়ালাইজেশন প্রক্রিয়ায় । ব্যবহার করার সময়Serializable, মেমরি কেবল বস্তুর জন্য বরাদ্দ করা হয়, এবং তারপর মানগুলি স্ট্রীম থেকে পড়া হয় এবং বস্তুর ক্ষেত্র সেট করতে ব্যবহৃত হয়। যদি আমরা ব্যবহার করি Serializable, অবজেক্টের কনস্ট্রাক্টর বলা হয় না! সমস্ত কাজ প্রতিফলনের মাধ্যমে ঘটে (প্রতিফলন API, যা আমরা শেষ পাঠে সংক্ষেপে উল্লেখ করেছি)। সঙ্গে Externalizable, deserialization প্রক্রিয়া ভিন্ন. ডিফল্ট কনস্ট্রাক্টরকে প্রথমে বলা হয়। তার পরেই তৈরি করা UserInfoবস্তুর readExternal()পদ্ধতি বলা হয়। এটি বস্তুর ক্ষেত্র সেট করার জন্য দায়ী। তাই ইন্টারফেস বাস্তবায়নকারী যে কোনো ক্লাসের Externalizableএকটি ডিফল্ট কনস্ট্রাক্টর থাকতে হবে । আসুন আমাদের UserInfoক্লাসে একটি যোগ করি এবং কোডটি পুনরায় চালু করি:

import java.io.*;

public class Main {

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

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);


       UserInfo userInfo = (UserInfo) objectInputStream.readObject();
       System.out.println(userInfo);

       objectInputStream.close();
   }
}
কনসোল আউটপুট: পল পাইপারের পাসপোর্ট ডেটা UserInfo \ firstName = 'Paul', lastName = 'Piper', superSecretInformation = 'Paul Piper's passport data' } এখন এটি সম্পূর্ণ ভিন্ন কিছু! প্রথমত, গোপন তথ্য সহ ডিক্রিপ্ট করা স্ট্রিং কনসোলে প্রদর্শিত হয়েছিল। তারপরে আমরা ফাইল থেকে উদ্ধারকৃত বস্তুটি একটি স্ট্রিং হিসাবে প্রদর্শিত হয়েছিল! তাই আমরা সফলভাবে সমস্ত সমস্যার সমাধান করেছি :) সিরিয়ালাইজেশন এবং ডিসিরিয়ালাইজেশনের বিষয়টি সহজ বলে মনে হচ্ছে, কিন্তু, আপনি দেখতে পাচ্ছেন, পাঠগুলি দীর্ঘ হয়েছে। এবং আরও অনেক কিছু আছে যা আমরা কভার করিনি! এই প্রতিটি ইন্টারফেস ব্যবহার করার সময় এখনও অনেক সূক্ষ্মতা জড়িত আছে। কিন্তু অত্যধিক নতুন তথ্য থেকে আপনার মস্তিষ্কের বিস্ফোরণ এড়াতে, আমি সংক্ষেপে আরও কয়েকটি গুরুত্বপূর্ণ পয়েন্ট তালিকাবদ্ধ করব এবং আপনাকে অতিরিক্ত পড়ার লিঙ্ক দেব। সুতরাং, আপনার আর কি জানা দরকার? প্রথমতSerializable , সিরিয়ালাইজেশনের সময় (আপনি ব্যবহার করছেন কিনা তা নির্বিশেষে Externalizable), ভেরিয়েবলগুলিতে মনোযোগ দিন static। আপনি যখন ব্যবহার করেন Serializable, তখন এই ক্ষেত্রগুলি মোটেও সিরিয়াল করা হয় না (এবং, সেই অনুযায়ী, তাদের মান পরিবর্তন হয় না, কারণ staticক্ষেত্রগুলি ক্লাসের অন্তর্গত, বস্তুর নয়)। কিন্তু যখন আপনি ব্যবহার করেনExternalizable, আপনি নিজেই প্রক্রিয়াটি নিয়ন্ত্রণ করেন, তাই প্রযুক্তিগতভাবে আপনি সেগুলিকে সিরিয়ালাইজ করতে পারেন। তবে, আমরা এটি সুপারিশ করি না, কারণ এটি করার ফলে প্রচুর সূক্ষ্ম বাগ তৈরি হওয়ার সম্ভাবনা রয়েছে। দ্বিতীয়ত , আপনাকে মডিফায়ারের সাথে ভেরিয়েবলের দিকেও মনোযোগ দিতে হবে final। আপনি যখন ব্যবহার করেন Serializable, তখন সেগুলি যথারীতি সিরিয়ালাইজড এবং ডিসিরিয়ালাইজ করা হয়, কিন্তু আপনি যখন ব্যবহার করেন , তখন একটি ভেরিয়েবল Externalizableডিসিরিয়ালাইজ করা অসম্ভবfinal ! কারণটি সহজ: finalডিফল্ট কনস্ট্রাক্টর কল করা হলে সমস্ত ক্ষেত্র আরম্ভ করা হয় — এর পরে, তাদের মান পরিবর্তন করা যাবে না। অতএব, ক্ষেত্র আছে এমন বস্তুগুলিকে সিরিয়ালাইজ করতে final, দ্বারা প্রদত্ত প্রমিত ক্রমিককরণ ব্যবহার করুন Serializableতৃতীয় , আপনি যখন উত্তরাধিকার ব্যবহার করেন, তখন সমস্ত বংশধর শ্রেণী যা কিছু উত্তরাধিকারী হয়Externalizableক্লাসে অবশ্যই ডিফল্ট কনস্ট্রাক্টর থাকতে হবে। এখানে সিরিয়ালাইজেশন প্রক্রিয়া সম্পর্কে ভাল নিবন্ধের লিঙ্ক আছে: পরের বার পর্যন্ত! :)
মন্তব্য
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION