কেন 'চূড়ান্ত' কীওয়ার্ডটি কার্যকর হবে?


54

দেখে মনে হচ্ছে জাভা যুগে যুগে ক্লাসগুলি অযোগ্য নয় বলে ঘোষণা করার ক্ষমতা পেয়েছিল এবং এখন সি ++ এরও রয়েছে। যাইহোক, সলাইডে ওপেন / ক্লোজ নীতিটির আলোকে, কেন এটি কার্যকর হবে? আমার কাছে, finalকীওয়ার্ডটি ঠিক এর মতো শোনাচ্ছে friend- এটি আইনী তবে আপনি যদি এটি ব্যবহার করে থাকেন তবে সম্ভবত নকশাটি ভুল। অনুগ্রহ করে এমন কিছু উদাহরণ সরবরাহ করুন যেখানে একটি অ-বিভেদযোগ্য শ্রেণি একটি দুর্দান্ত আর্কিটেকচার বা ডিজাইন প্যাটার্নের অংশ হতে পারে।


43
আপনি কেন মনে করেন যে কোনও শ্রেণিটি এটির সাথে টিকা দেওয়া থাকলে ভুলভাবে ডিজাইন করা হয়েছে final? অনেক লোক (আমাকে সহ) দেখতে পান যে প্রতিটি নন-অ্যাবস্ট্রাক্ট বর্গ তৈরি করার জন্য এটি একটি ভাল নকশা final
স্পটড

20
উত্তরাধিকারের তুলনায় পছন্দ রচনা এবং আপনার প্রতিটি অ বিমূর্ত শ্রেণি থাকতে পারে final
অ্যান্ডি

24
উন্মুক্ত / ঘনিষ্ঠ নীতিটি 20 ম শতাব্দীর এক অর্থে অ্যানাক্রোনিজম, যখন মন্ত্রটি ক্লাসগুলি থেকে উত্তরাধিকার সূত্রে প্রাপ্ত অন্য শ্রেণীর বংশানুসারে প্রাপ্ত শ্রেণিকেন্দ্রিক শ্রেণিবদ্ধতা তৈরি করছিল। এটি অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং শেখানোর জন্য দুর্দান্ত ছিল তবে বাস্তব-বিশ্ব সমস্যার ক্ষেত্রে প্রয়োগ করার সময় এটি জটলা, অচিন্তনীয় মেসেস তৈরি করতে সক্ষম হয়েছিল। বর্ধমানযোগ্য হতে কোনও শ্রেণি নকশা করা শক্ত।
ডেভিড হামেন 12'16

34
@ ডেভিড আর্নো হাস্যকর হবেন না। উত্তরাধিকার হ'ল অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং-এর অভাবে সাইন কোয়া এবং এটি অতিমাত্রায়-গোড়ামী লোকেরা প্রচার করতে পছন্দ করার মতো জটিল বা অগোছালো কাছাকাছি কোথাও নেই। এটি অন্য সরঞ্জামের মতো একটি সরঞ্জাম এবং একটি ভাল প্রোগ্রামার জানেন যে কীভাবে কাজের জন্য সঠিক সরঞ্জামটি ব্যবহার করতে হয়।
ম্যাসন হুইলারের

48
পুনরুদ্ধারকারী বিকাশকারী হিসাবে, ক্ষতিকারক আচরণকে গুরুতর বিভাগগুলিতে প্রবেশ করা থেকে বিরত রাখার জন্য আমি চূড়ান্ত একটি উজ্জ্বল সরঞ্জাম হিসাবে মনে করি। আমি উত্তরাধিকার বিভিন্ন উপায়ে একটি শক্তিশালী হাতিয়ার হিসাবে মনে আছে বলে মনে হয়। এটি প্রায় যেন হাঁসফাঁসের বিভিন্ন সরঞ্জামগুলির পক্ষে মতামত এবং কনস রয়েছে এবং ইঞ্জিনিয়ার হিসাবে আমাদের সফ্টওয়্যার তৈরি করার সাথে সাথে আমাদের সেই কারণগুলিতে ভারসাম্য বজায় রাখতে হবে!
কর্সিকা

উত্তর:


136

final অভিপ্রায় প্রকাশ । এটি কোনও শ্রেণি, পদ্ধতি বা পরিবর্তনশীল ব্যবহারকারীকে বলে "" এই উপাদানটি পরিবর্তনের কথা নয় এবং আপনি যদি এটি পরিবর্তন করতে চান তবে আপনি বিদ্যমান নকশাটি বুঝতে পারেন নি। "

এটি গুরুত্বপূর্ণ কারণ প্রোগ্রাম আর্কিটেকচারটি সত্যই, সত্যই যদি কঠিন হয়ে থাকে তবে আপনি যদি অনুমান করতে থাকেন যে প্রতিটি শ্রেণি এবং আপনি যে কোনও পদ্ধতি লিখেছেন তখন একটি সাবক্লাস দ্বারা সম্পূর্ণ আলাদা কিছু করার জন্য পরিবর্তিত হতে পারে। কোন উপাদানগুলি পরিবর্তনযোগ্য এবং কোনটি নয় এবং কোনটি অপরিবর্তনযোগ্যতার মাধ্যমে প্রয়োগ করতে হবে তা আপ-ফ্রন্টের সিদ্ধান্ত নেওয়া আরও ভাল final

আপনি মন্তব্য এবং আর্কিটেকচার ডকুমেন্টের মাধ্যমে এটিও করতে পারেন, তবে ভবিষ্যতের ব্যবহারকারীরা ডকুমেন্টেশনটি পড়বেন এবং মানবেন এমন আশা করার চেয়ে কম্পাইলারটি এমন কিছু প্রয়োগ করতে দেওয়া ভাল।


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

8
@ কিলিয়ানফট ঠিক আছে, তবে সত্যি বলতে কী, অ্যাপ্লিকেশন প্রোগ্রামাররা আপনার সমস্যাটি কী করে?
coredump

20
@ কর্ডম্প্প লোকেরা আমার গ্রন্থাগারটি খারাপভাবে খারাপ সিস্টেম তৈরি করে। খারাপ সিস্টেমগুলি খারাপ খ্যাতি প্রজনন করে। ব্যবহারকারীরা ফ্রেড র‌্যান্ডমের মারাত্মকভাবে অস্থির অ্যাপ্লিকেশন থেকে কিলিয়ানর দুর্দান্ত কোডটি পার্থক্য করতে পারবেন না। ফলাফল: আমি প্রোগ্রামিং ক্রেডিট এবং গ্রাহকদের হারিয়েছি। আপনার কোডটির অপব্যবহার করা শক্ত করে তোলা ডলার এবং সেন্টের প্রশ্ন।
কিলিয়ান ফথ

21
বিবৃতি "এই উপাদানটি পরিবর্তন করার কথা নয় এবং আপনি যদি এটি পরিবর্তন করতে চান তবে আপনি বিদ্যমান নকশাটি বুঝতে পারেন নি।" অবিশ্বাস্যরূপে অহঙ্কারী এবং আমি যে লাইব্রেরির সাথে কাজ করেছি তার অংশ হিসাবে আমি যে মনোভাব চাই তা নয় not যদি শুধুমাত্র আমি প্রতি সময় জন্য একটি তুচ্ছ ছিল কিছু হাস্যকর ওভার encapsulated গ্রন্থাগার আমাকে কোন প্রক্রিয়া অবশিষ্ট যে ভেতরের রাষ্ট্রের কিছু টুকরা পরিবর্তন করতে পরিবর্তন করা প্রয়োজন কারণ লেখক একটি গুরুত্বপূর্ণ ব্যবহারের ক্ষেত্রে ... কহা করতে ব্যর্থ
ম্যাসন হুইলার

31
@ জিমিবি থাম্বের বিধি: আপনি যদি ভাবেন যে আপনার সৃষ্টির জন্য কী ব্যবহার করা হবে তা আপনি জানেন তবে আপনি ইতিমধ্যে ভুল wrong বেল টেলিফোনে মূলত একটি মুজাক সিস্টেম হিসাবে কল্পনা করেছিলেন। ক্লিনেক্স আরও সহজেই মেকআপ অপসারণের উদ্দেশ্যে উদ্ভাবিত হয়েছিল। আইবিএমের সভাপতি টমাস ওয়াটসন একবার বলেছিলেন "আমি মনে করি সম্ভবত পাঁচটি কম্পিউটারের জন্য বিশ্ব বাজার রয়েছে।" ২০০১ সালে প্যাট্রিয়ট অ্যাক্ট প্রবর্তনকারী প্রতিনিধি জিম সেনসেনব্রেনার রেকর্ডে রয়েছেন যে , এনএসএকে "প্যাট্রিয়ট অ্যাক্ট কর্তৃপক্ষের সাথে" করা কাজগুলি করা থেকে বিরত রাখার লক্ষ্যেই এটির উদ্দেশ্য ছিল । এবং আরও ...
ম্যাসন হুইলার

59

এটি ফ্রেজিলে বেস ক্লাসের সমস্যা এড়িয়ে চলে । প্রতিটি ক্লাসই স্পষ্ট বা স্পষ্ট গ্যারান্টি এবং আক্রমণকারীদের একটি সেট নিয়ে আসে। লিসকভ সাবস্টিটিউশন নীতিমালা আদেশ দেয় যে class শ্রেণীর সমস্ত উপ-প্রকারকে অবশ্যই এই সমস্ত গ্যারান্টি সরবরাহ করতে হবে। তবে, যদি আমরা এটি ব্যবহার না করি তবে এটি লঙ্ঘন করা সত্যিই সহজ final। উদাহরণস্বরূপ, আসুন একটি পাসওয়ার্ড পরীক্ষক থাকি:

public class PasswordChecker {
  public boolean passwordIsOk(String password) {
    return password == "s3cret";
  }
}

আমরা যদি সেই শ্রেণিকে ওভাররাইড করার অনুমতি দিই, একটি বাস্তবায়ন প্রত্যেককে লক আউট করতে পারে, অন্য একজন সবাইকে অ্যাক্সেস দিতে পারে:

public class OpenDoor extends PasswordChecker {
  public boolean passwordIsOk(String password) {
    return true;
  }
}

এটি সাধারণত ঠিক থাকে না, যেহেতু সাবক্লাসগুলির আচরণ এখন মূলের সাথে খুব বেমানান। আমরা যদি সত্যই শ্রেণীর অন্যান্য আচরণের সাথে প্রসারিত করার ইচ্ছা করি, তবে দায়বদ্ধতার একটি চেইন আরও ভাল হবে:

PasswordChecker passwordChecker =
  new DefaultPasswordChecker(null);
// or:
PasswordChecker passwordChecker =
  new OpenDoor(null);
// or:
PasswordChecker passwordChecker =
 new DefaultPasswordChecker(
   new OpenDoor(null)
 );

public interface PasswordChecker {
  boolean passwordIsOk(String password);
}

public final class DefaultPasswordChecker implements PasswordChecker {
  private PasswordChecker next;

  public DefaultPasswordChecker(PasswordChecker next) {
    this.next = next;
  }

  @Override
  public boolean passwordIsOk(String password) {
    if ("s3cret".equals(password)) return true;
    if (next != null) return next.passwordIsOk(password);
    return false;
  }
}

public final class OpenDoor implements PasswordChecker {
  private PasswordChecker next;

  public OpenDoor(PasswordChecker next) {
    this.next = next;
  }

  @Override
  public boolean passwordIsOk(String password) {
    return true;
  }
}

সমস্যাটি আরও স্পষ্ট হয়ে ওঠে যখন আরও জটিল শ্রেণি তার নিজস্ব পদ্ধতিগুলি কল করে এবং সেই পদ্ধতিগুলি ওভাররাইড করা যায়। ডেটা স্ট্রাকচারের প্রিন্ট-প্রিন্টিং বা এইচটিএমএল লেখার সময় আমি কখনও কখনও এটির মুখোমুখি হই। প্রতিটি পদ্ধতি কিছু উইজেটের জন্য দায়ী।

public class Page {
  ...;

  @Override
  public String toString() {
    PrintWriter out = ...;
    out.print("<!DOCTYPE html>");
    out.print("<html>");

    out.print("<head>");
    out.print("</head>");

    out.print("<body>");
    writeHeader(out);
    writeMainContent(out);
    writeMainFooter(out);
    out.print("</body>");

    out.print("</html>");
    ...
  }

  void writeMainContent(PrintWriter out) {
    out.print("<div class='article'>");
    out.print(htmlEscapedContent);
    out.print("</div>");
  }

  ...
}

আমি এখন একটি সাবক্লাস তৈরি করেছি যা আরও কিছু স্টাইলিং যুক্ত করেছে:

class SpiffyPage extends Page {
  ...;


  @Override
  void writeMainContent(PrintWriter out) {
    out.print("<div class='row'>");

    out.print("<div class='col-md-8'>");
    super.writeMainContent(out);
    out.print("</div>");

    out.print("<div class='col-md-4'>");
    out.print("<h4>About the Author</h4>");
    out.print(htmlEscapedAuthorInfo);
    out.print("</div>");

    out.print("</div>");
  }
}

এখন এই মুহুর্তের জন্য উপেক্ষা করা যে এইচটিএমএল পৃষ্ঠাগুলি উত্পন্ন করার খুব ভাল উপায় নয়, যদি আমি আবার লেআউটটি পরিবর্তন করতে চাই তবে কী হবে? আমাকে একটি SpiffyPageসাবক্লাস তৈরি করতে হবে যা কোনওভাবে সেই সামগ্রীটিকে আবৃত করে। আমরা এখানে যা দেখতে পাচ্ছি তা হ'ল টেম্পলেট পদ্ধতি প্যাটার্নের একটি দুর্ঘটনাজনক অ্যাপ্লিকেশন। টেমপ্লেট পদ্ধতিগুলি একটি বেস শ্রেণিতে ভাল-সংজ্ঞায়িত এক্সটেনশন পয়েন্টগুলি ওভাররাইড করার উদ্দেশ্যে তৈরি।

এবং বেস ক্লাস পরিবর্তন হলে কী হবে? এইচটিএমএল বিষয়বস্তু যদি খুব বেশি পরিবর্তন হয় তবে এটি সাবক্লাসগুলির সরবরাহিত বিন্যাসটি ভেঙে দিতে পারে। সুতরাং বেস ক্লাসের পরে পরিবর্তন করা সত্যই নিরাপদ নয়। আপনার সমস্ত ক্লাস একই প্রকল্পে থাকলে এটি স্পষ্ট নয়, তবে বেস ক্লাসটি যদি অন্য প্রকাশিত সফ্টওয়্যারগুলির অংশ হয় যা অন্য লোকেরা তৈরি করে তবে এটি খুব লক্ষণীয়।

যদি এই এক্সটেনশান কৌশলটি উদ্দেশ্য করা হয়, তবে আমরা ব্যবহারকারীকে প্রতিটি অংশ কীভাবে তৈরি করা যায় তার উপায়গুলি অদলবদলের অনুমতি দিতে পারতাম। হয়, প্রতিটি ব্লকের জন্য কৌশল থাকতে পারে যা বাহ্যিকভাবে সরবরাহ করা যেতে পারে। বা, আমরা সজ্জিত বাসা করতে পারি। এটি উপরের কোডের সমতুল্য, তবে আরও সুস্পষ্ট এবং অনেক বেশি নমনীয়:

Page page = ...;
page.decorateLayout(current -> new SpiffyPageDecorator(current));
print(page.toString());

public interface PageLayout {
  void writePage(PrintWriter out, PageLayout top);
  void writeMainContent(PrintWriter out, PageLayout top);
  ...
}

public final class Page {
  private PageLayout layout = new DefaultPageLayout();

  public void decorateLayout(Function<PageLayout, PageLayout> wrapper) {
    layout = wrapper.apply(layout);
  }

  ...
  @Override public String toString() {
    PrintWriter out = ...;
    layout.writePage(out, layout);
    ...
  }
}

public final class DefaultPageLayout implements PageLayout {
  @Override public void writeLayout(PrintWriter out, PageLayout top) {
    out.print("<!DOCTYPE html>");
    out.print("<html>");

    out.print("<head>");
    out.print("</head>");

    out.print("<body>");
    top.writeHeader(out, top);
    top.writeMainContent(out, top);
    top.writeMainFooter(out, top);
    out.print("</body>");

    out.print("</html>");
  }

  @Override public void writeMainContent(PrintWriter out, PageLayout top) {
    ... /* as above*/
  }
}

public final class SpiffyPageDecorator implements PageLayout {
  private PageLayout inner;

  public SpiffyPageDecorator(PageLayout inner) {
    this.inner = inner;
  }

  @Override
  void writePage(PrintWriter out, PageLayout top) {
    inner.writePage(out, top);
  }

  @Override
  void writeMainContent(PrintWriter out, PageLayout top) {
    ...
    inner.writeMainContent(out, top);
    ...
  }
}

( ডেকোরেটর চেইনের শীর্ষে topকলগুলি writeMainContentযেতে হবে তা নিশ্চিত করার জন্য অতিরিক্ত প্যারামিটারটি প্রয়োজনীয় This এটি ওপেন পুনরাবৃত্তি নামক সাবক্লাসিংয়ের একটি বৈশিষ্ট্য অনুকরণ করে ))

আমাদের যদি একাধিক সজ্জকার থাকে তবে আমরা এখন আরও অবাধে মিশ্রিত করতে পারি।

বিদ্যমান কার্যকারিতাটি সামান্য মানিয়ে নেওয়ার আকাঙ্ক্ষার চেয়ে প্রায়শই প্রায়শই বিদ্যমান শ্রেণীর কিছু অংশ পুনরায় ব্যবহার করার ইচ্ছা। আমি এমন একটি কেস দেখেছি যেখানে কেউ ক্লাস চেয়েছিল যেখানে আপনি আইটেমগুলি যুক্ত করতে পারেন এবং সেগুলির উপরে পুনরাবৃত্তি করতে পারেন। সঠিক সমাধানটি হ'ল:

final class Thingies implements Iterable<Thing> {
  private ArrayList<Thing> thingList = new ArrayList<>();

  @Override public Iterator<Thing> iterator() {
    return thingList.iterator();
  }

  public void add(Thing thing) {
    thingList.add(thing);
  }

  ... // custom methods
}

পরিবর্তে, তারা একটি সাবক্লাস তৈরি করেছে:

class Thingies extends ArrayList<Thing> {
  ... // custom methods
}

এর হঠাৎ এর অর্থ হ'ল পুরো ইন্টারফেসটি আমাদের ইন্টারফেসের ArrayListঅংশ হয়ে গেছে । ব্যবহারকারীরা নির্দিষ্ট জিনিসগুলিতে জিনিসগুলি বা জিনিসগুলি করতে পারেন । এটা কি এইভাবে উদ্দেশ্য ছিল? ঠিক আছে. তবে প্রায়শই, আমরা সমস্ত পরিণতিটি সাবধানতার সাথে চিন্তা করি না।remove()get()

সুতরাং এটি পরামর্শ দেওয়া হয়

  • extendসাবধান চিন্তা না করে কখনও ক্লাস করবেন না।
  • আপনার ক্লাসটি সর্বদা চিহ্নিত করুন finalযদি আপনি কোনও পদ্ধতির ওভাররাইড হওয়ার জন্য চান না।
  • ইন্টারফেসগুলি তৈরি করুন যেখানে আপনি কোনও প্রয়োগকরণ অদলবদল করতে চান, যেমন ইউনিট পরীক্ষার জন্য।

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

কিছু ভাষায় কঠোর প্রয়োগের ব্যবস্থা রয়েছে:

  • সমস্ত পদ্ধতি ডিফল্টরূপে চূড়ান্ত হয় এবং এটি স্পষ্টভাবে চিহ্নিত করতে হবে virtual
  • তারা ব্যক্তিগত উত্তরাধিকার সরবরাহ করে যা ইন্টারফেসের উত্তরাধিকার সূত্রে প্রাপ্ত হয় না শুধুমাত্র বাস্তবায়ন।
  • তাদের বেস ক্লাসের পদ্ধতিগুলি ভার্চুয়াল হিসাবে চিহ্নিত করা প্রয়োজন এবং সমস্ত ওভাররাইডগুলি পাশাপাশি চিহ্নিত করা প্রয়োজন। এটি এমন সমস্যাগুলিকে এড়িয়ে চলে যেখানে সাবক্লাস একটি নতুন পদ্ধতি সংজ্ঞায়িত করে, তবে একই স্বাক্ষরযুক্ত একটি পদ্ধতি পরে বেস শ্রেণিতে যুক্ত করা হয়েছিল তবে ভার্চুয়াল হিসাবে নয়।

3
"ভঙ্গুর বেস শ্রেণীর সমস্যা" উল্লেখ করার জন্য আপনার কমপক্ষে +100 প্রাপ্য। :)
ডেভিড আরনো

6
আমি এখানে তৈরি পয়েন্ট দ্বারা বিশ্বাসী না। হ্যাঁ, ভঙ্গুর বেস শ্রেণি একটি সমস্যা, তবে চূড়ান্ত কোনও বাস্তবায়ন পরিবর্তন করে সমস্ত সমস্যার সমাধান করে না। আপনার প্রথম উদাহরণটি খারাপ কারণ আপনি ধরে নিচ্ছেন যে আপনি পাসওয়ার্ডচেকারের জন্য সম্ভাব্য সমস্ত ব্যবহারের কেস জানেন ("প্রত্যেককে লক করা বা প্রত্যেককে অ্যাক্সেসের অনুমতি দেওয়া ... ঠিক আছে না" - কে বলে?)। আপনার শেষ "অতএব পরামর্শদায়ক ..." তালিকাটি সত্যই খারাপ - আপনি মূলত কোনও কিছু বাড়িয়ে না দেওয়ার এবং সবকিছুকে চূড়ান্ত হিসাবে চিহ্নিত করার পক্ষে পরামর্শ দিচ্ছেন - যা ওওপি, উত্তরাধিকার এবং কোড-পুনরায় ব্যবহারের কার্যকারিতা পুরোপুরি নিরস্ত করে।
অ্যাডেলফাস

4
আপনার প্রথম উদাহরণটি ভঙ্গুর বেস শ্রেণীর সমস্যার উদাহরণ নয়। ভঙ্গুর বেস ক্লাসের সমস্যায় একটি বেস ক্লাসে পরিবর্তিত হয়ে একটি সাবক্লাস ভাঙে। তবে সেই উদাহরণে আপনার সাবক্লাস একটি সাবক্লাসের চুক্তি অনুসরণ করে না। এ দুটি ভিন্ন সমস্যা। (অতিরিক্তভাবে, এটি আসলে যুক্তিসঙ্গত যে নির্দিষ্ট পরিস্থিতিতে আপনি একটি পাসওয়ার্ড চেকার অক্ষম করতে পারেন (উন্নয়নের জন্য বলুন))
উইনস্টন ইওয়ার্ট

5
"এটি ভঙ্গুর বেস শ্রেণীর সমস্যা এড়ায়" - একইভাবে নিজেকে হত্যা করা ক্ষুধার্ত হওয়া এড়ানো যায়।
ব্যবহারকারী 253751

9
@ মিমিবিস, এটি খাদ্য পোজিং এড়ানোর জন্য খাওয়া এড়িয়ে চলা। অবশ্যই, কখনও খাওয়ার সমস্যা হবে না। তবে কেবলমাত্র সেই জায়গাগুলিতেই খাওয়াই আপনার জ্ঞান লাভ করে।
উইনস্টন ইওয়ার্ট

33

আমি অবাক হয়েছি যে এখনও কেউ জোশুয়া ব্লচ দ্বারা কার্যকর জাভা, ২ য় সংস্করণ উল্লেখ করেনি (যা কমপক্ষে প্রতিটি জাভা বিকাশকারীকে পড়া দরকার)। বইয়ের 17 টি আইটেমটি এ সম্পর্কে বিশদ আলোচনা করেছে এবং শিরোনাম: " উত্তরাধিকারের জন্য নকশা এবং নথিপত্র বা অন্যথায় এটি নিষিদ্ধ করা হয়েছে "।

আমি বইয়ের সমস্ত ভাল পরামর্শটির পুনরাবৃত্তি করব না, তবে এই নির্দিষ্ট অনুচ্ছেদগুলি প্রাসঙ্গিক বলে মনে হচ্ছে:

তবে সাধারণ কংক্রিটের ক্লাসগুলি কী? Ditionতিহ্যগতভাবে, এগুলি সাবক্লাসিংয়ের জন্য চূড়ান্ত বা নকশাকৃত ও নথিবদ্ধ নয়, তবে এই পরিস্থিতিটি বিপজ্জনক। প্রতিবার যেমন একটি শ্রেণিতে পরিবর্তন করা হয়, এমন সুযোগ থাকে যে ক্লায়েন্টের ক্লায়েন্টগুলি ক্লাসে প্রসারিত হয় সেগুলি ভেঙে যায়। এটি কেবল একটি তাত্ত্বিক সমস্যা নয়। উত্তরাধিকারের জন্য নকশা করা এবং নথিভুক্ত নয় এমন একটি ননফাইনাল কংক্রিট শ্রেণীর ইন্টার্নালগুলি সংশোধন করার পরে সাবক্লাসিং-সংক্রান্ত বাগ রিপোর্টগুলি পাওয়া অস্বাভাবিক কিছু নয়।

এই সমস্যার সর্বোত্তম সমাধান হ'ল এমন ক্লাসগুলিতে সাবক্লাসিং নিষিদ্ধ করা যা নিরাপদে সাবক্ল্যাসড হওয়ার জন্য নকশাকৃত এবং নথিভুক্ত নয়। সাবক্লাসিং নিষিদ্ধ করার দুটি উপায় রয়েছে। দুজনের মধ্যে সহজ ক্লাস ফাইনাল ঘোষণা করা। বিকল্পটি হ'ল সমস্ত কনস্ট্রাক্টরকে বেসরকারী বা প্যাকেজ-প্রাইভেট করা এবং কনস্ট্রাক্টরের জায়গায় পাবলিক স্ট্যাটিক কারখানা যুক্ত করা। এই বিকল্পটি, যা অভ্যন্তরীণভাবে সাবক্লাসগুলি ব্যবহারের জন্য নমনীয়তা সরবরাহ করে আইটেম 15 এ আলোচনা করা হয়েছে ither


21

অন্যতম কার্যকর কারণ finalহ'ল এটি নিশ্চিত করে যে আপনি পিতামাত্ত শ্রেণীর চুক্তি লঙ্ঘন করবে এমন উপায়ে কোনও শ্রেণি সাবক্লাস করতে পারবেন না। এই জাতীয় সাবক্লাসিংটি সলিড (সমস্ত "এল" এর বেশিরভাগ ক্ষেত্রে) লঙ্ঘন হবে এবং একটি বর্গ তৈরি করা finalএটি প্রতিরোধ করে।

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

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

ফাইনাল কখনও কখনও সাধারণ পদ্ধতির মধ্যে দুটি জিনিসের জন্য একই ভেরিয়েবল পুনরায় ব্যবহার করা ইত্যাদি সাধারণ ভুল প্রতিরোধে সহায়ক Sc স্কালায় আপনাকে valজাভাতে চূড়ান্ত ভেরিয়েবলের সাথে মোটামুটি মিলে যায় এমন ব্যবহার করতে উত্সাহিত করা হয় , এবং আসলে কোনওরকমের ব্যবহার varবা অ-চূড়ান্ত পরিবর্তনশীলটিকে সন্দেহের দিকে তাকাতে হবে।

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


6
পরিশেষে, সংকলকরা কমপক্ষে তত্ত্বে => আমি ব্যক্তিগতভাবে ক্লেংয়ের ডেভেরচুয়ালাইজেশন পাসটি পর্যালোচনা করতে পেরেছি এবং আমি নিশ্চিত করেছি যে এটি ব্যবহারে ব্যবহার হয়েছে।
ম্যাথিউ এম।

তবে সংকলকটি আগে থেকেই বলতে পারে না যে এটির চিহ্নিত ফাইনাল কিনা তা নির্বিশেষে কেউই কোনও শ্রেণি বা পদ্ধতিকে উপেক্ষা করছে না?
জেসিটিজি

3
@ জেএসটিজি যদি এটির সমস্ত কোডে একবারে অ্যাক্সেস থাকে তবে সম্ভবত। যদিও পৃথক ফাইল সংকলন সম্পর্কে?
মনিকা পুনরায়

3
@ জেসিটিজি ডেভ্যাচুয়ালাইজেশন বা (মনোমরফিক / পলিমারফিক) ইনলাইন ক্যাচিংটি জেআইটি সংকলকগুলির একটি সাধারণ কৌশল, যেহেতু সিস্টেমটি বর্তমানে কোন ক্লাসগুলি বোঝা হচ্ছে তা জানে এবং কোডটি ডিওপিমাইজ করতে পারে যদি কোনও ওভাররাইডিং পদ্ধতি অনুমান করা ভুল না হয়। যাইহোক, সময়ের পূর্বে সংকলক পারে না। আমি যখন একটি জাভা ক্লাস এবং সেই ক্লাসটি ব্যবহার করে এমন কোড সংকলন করি, আমি পরে একটি সাবক্লাস সংকলন করতে পারি এবং গ্রাহক কোডটিতে একটি উদাহরণ দিয়ে যেতে পারি। সহজ উপায় হ'ল ক্লাসপাথের সামনের অংশে আরও একটি জার যুক্ত করা। সংকলক এই সমস্ত সম্পর্কে জানতে পারে না, যেহেতু রান টাইমে এটি ঘটে।
আমন

5
@ এমটিল্টড আপনি ধরে নিতে পারেন স্ট্রিংগুলি পরিবর্তনযোগ্য কারণ প্রতিবিম্বের মাধ্যমে স্ট্রিংগুলিকে পরিবর্তন করা নিষিদ্ধ হতে পারে a এর মাধ্যমে SecurityManager। বেশিরভাগ প্রোগ্রাম এটি ব্যবহার করে না তবে এগুলি কোনও অবিশ্বাস্য কোডও চালায় না। +++ আপনাকে ধরে নিতে হবে যে স্ট্রিংগুলি অপরিবর্তনীয় যেমনটি নাহলে আপনি শূন্য সুরক্ষা এবং বোনাস হিসাবে একগুচ্ছ স্বেচ্ছামূলক বাগ পেয়ে যাবেন। যে কোনও প্রোগ্রামার ধরে নিচ্ছেন যে জাভা স্ট্রিং উত্পাদনশীল কোডে পরিবর্তন আনতে পারে তা অবশ্যই উন্মাদ।
maaartinus

7

দ্বিতীয় কারণটি হল পারফরম্যান্স । প্রথম কারণটি হ'ল কিছু শ্রেণীর গুরুত্বপূর্ণ আচরণ বা রাষ্ট্র রয়েছে যা সিস্টেমকে কাজ করার অনুমতি দেওয়ার জন্য পরিবর্তন করার কথা নয়। উদাহরণস্বরূপ, যদি আমার কাছে "পাসওয়ার্ডচেক" শ্রেণি থাকে এবং সেই শ্রেণিটি তৈরি করতে আমি সুরক্ষা বিশেষজ্ঞদের একটি দল নিয়োগ করেছি এবং এই শ্রেণিটি কয়েকশ এটিএমের সাথে সুশিক্ষিত এবং সংজ্ঞায়িত প্রকল্পের সাথে যোগাযোগ করে। বিশ্ববিদ্যালয় থেকে নতুন একজন ভাড়া নেওয়া লোককে "ট্রাস্টমিপাসওয়ার্ডচেক" শ্রেণি তৈরি করার মঞ্জুরি দিন যা উপরের শ্রেণিটি প্রসারিত আমার সিস্টেমের জন্য খুব ক্ষতিকারক হতে পারে; এই পদ্ধতিগুলি ওভাররাইড হওয়ার কথা নয়, এটি এটি।



জেভিএম চূড়ান্ত ঘোষনা না করা সত্ত্বেও তাদের কোন সাবক্লাস না থাকলে ক্লাসগুলি চূড়ান্ত হিসাবে বিবেচনা করার জন্য যথেষ্ট স্মার্ট।
ব্যবহারকারী 253751

ডাউনভোটেড কারণ 'পারফরম্যান্স' দাবিটি এতবার অস্বীকার করা হয়েছে।
পল স্মিথ

7

আমার যখন ক্লাস দরকার তখন আমি একটা ক্লাস লিখব। আমার যদি সাবক্লাসের প্রয়োজন না হয় তবে আমি সাবক্লাসের বিষয়ে চিন্তা করি না। আমি নিশ্চিত করেছি যে আমার ক্লাসটি ইচ্ছাকৃত আচরণ করে এবং আমি যে জায়গাগুলি ক্লাসটি ব্যবহার করি সেগুলি অনুমান করে যে ক্লাসটি উদ্দেশ্য হিসাবে আচরণ করে।

যদি কেউ আমার ক্লাসটি সাবক্লাস করতে চায় তবে যা ঘটে তার জন্য আমি যে কোনও দায়বদ্ধতা পুরোপুরি অস্বীকার করতে চাই। আমি ক্লাসটিকে "ফাইনাল" করে এটি অর্জন করেছি। আপনি যদি এটি সাবক্লাস করতে চান তবে মনে রাখবেন যে আমি ক্লাসটি লেখার সময় সাবক্লাসিংয়ের বিষয়টি বিবেচনায় রাখিনি। সুতরাং আপনাকে ক্লাস সোর্স কোডটি নিতে হবে, "চূড়ান্ত" মুছে ফেলতে হবে এবং তারপরে যা কিছু ঘটবে তা সম্পূর্ণরূপে আপনার দায়িত্ব

আপনি কি মনে করেন যে এটি "অবজেক্ট ওরিয়েন্টেড নয়"? আমাকে এমন একটি ক্লাস করার জন্য অর্থ প্রদান করা হয়েছিল যা এটি করার কথা বলে does সাবক্ল্যাসড হতে পারে এমন ক্লাস করার জন্য কেউ আমাকে অর্থ প্রদান করেনি। আপনি যদি আমার ক্লাসটিকে পুনরায় ব্যবহারযোগ্য করে দেওয়ার জন্য অর্থ প্রদান করেন তবে এটি করতে আপনাকে স্বাগতম। "চূড়ান্ত" কীওয়ার্ডটি সরিয়ে শুরু করুন।

(এগুলি ব্যতীত, "চূড়ান্ত" প্রায়শই যথেষ্ট পরিমাণে অপটিমাইজেশনের অনুমতি দেয় For উদাহরণস্বরূপ, পাবলিক ক্লাসে বা একটি পাবলিক ক্লাসের কোনও পদ্ধতিতে সুইফ্ট "ফাইনাল" তে, এর অর্থ হ'ল সংকলকটি কোনও পদ্ধতি কল কী কোডটি কার্যকর করবে তা পুরোপুরি জানতে পারে, এবং স্ট্যাটিক প্রেরণের (ক্ষুদ্র সুবিধা) সহ গতিশীল প্রেরণকে প্রতিস্থাপন করতে পারে এবং প্রায়শই ইনলাইনিং (সম্ভবত বিশাল সুবিধা) সহ স্ট্যাটিক প্রেরণকে প্রতিস্থাপন করতে পারে।

অ্যাডেলফাস: "আপনি যদি এটি সাবক্লাস করতে চান, উত্স কোডটি নিতে চান, 'চূড়ান্ত' অপসারণ করতে চান, এবং এটি আপনার দায়বদ্ধতা" কী তা বোঝা এত কঠিন? "চূড়ান্ত" সমান "ন্যায্য সতর্কতা" সমান।

এবং আমাকে পুনরায় ব্যবহারযোগ্য কোড করার জন্য অর্থ প্রদান করা হয়নি । আমাকে কোড লিখতে দেওয়া হয়েছে যা এটি করার কথা বলেছিল does যদি আমাকে দুটি অনুরূপ কোডের বিট দেওয়ার জন্য অর্থ প্রদান করা হয় তবে আমি সাধারণ অংশগুলি বের করি কারণ এটি সস্তা এবং আমার সময় নষ্ট করার জন্য আমাকে অর্থ প্রদান করা হয় না। পুনরায় ব্যবহারযোগ্য কোডটি পুনরায় ব্যবহারযোগ্য করা আমার সময়ের অপচয়।

এম 4ks: আপনি সর্বদা এমন সব কিছু ব্যক্তিগত করে রাখেন যা বাইরে থেকে অ্যাক্সেস করার কথা নয়। আবার, আপনি যদি সাবক্লাস করতে চান তবে আপনি উত্স কোডটি গ্রহণ করেন, আপনার প্রয়োজন মতো জিনিসগুলিকে "সুরক্ষিত" এ পরিবর্তন করেন এবং আপনি যা করেন তার জন্য দায়বদ্ধ হন। আপনি যদি মনে করেন যে আমি ব্যক্তিগতভাবে চিহ্নিত করেছি এমন জিনিসগুলিতে আপনার অ্যাক্সেস করা দরকার, আপনি কী করছেন তা আপনি আরও ভাল জানেন।

উভয়: সাবক্লাসিং পুনরায় ব্যবহারের কোডের একটি ক্ষুদ্র, ক্ষুদ্র অংশ। সাবক্লাসিং ছাড়াই মানিয়ে নেওয়া যায় এমন বিল্ডিং ব্লক তৈরি করা অনেক বেশি শক্তিশালী এবং "চূড়ান্ত" থেকে প্রচুর উপকারী কারণ ব্লকের ব্যবহারকারীরা যা পান তার উপর নির্ভর করতে পারেন।


4
-1 এই উত্তরটি সফ্টওয়্যার বিকাশকারীদের সাথে যা ভুল তা বর্ণনা করে। কেউ যদি সাবক্লাসিং করে আপনার ক্লাসটি পুনরায় ব্যবহার করতে চায় তবে তাদের দিন। তারা কীভাবে এটি ব্যবহার করবে (বা অপব্যবহার করবে) আপনার দায়িত্ব কেন হবে? মূলত, আপনি আফকে হিসাবে আপনাকে চূড়ান্ত ব্যবহার করছেন , আপনি আমার ক্লাস ব্যবহার করছেন না। * "কেউ ক্লাস করার জন্য আমাকে অর্থ প্রদান করেনি যা সাবক্ল্যাস করা যেতে পারে" । আপনি গুরুতর? ঠিক সেই কারণেই সফ্টওয়্যার ইঞ্জিনিয়াররা নিযুক্ত হয়েছেন - সলিড, পুনরায় ব্যবহারযোগ্য কোড তৈরি করতে।
অ্যাডেলফাস

4
-1 কেবল সবকিছু ব্যক্তিগত করে রাখুন, তাই কেউ প্রত্যেকে এমনকি সাবক্লাসিংয়ের কথা
ভাবেনা

3
@ অ্যাডেলফাস যদিও এই উত্তরের শব্দটি অস্পষ্ট, কঠোর সাথে সীমাবদ্ধ, এটি কোনও "ভুল" দৃষ্টিকোণ নয়। প্রকৃতপক্ষে এটি কেবলমাত্র কম ক্লিনিকাল টোন দিয়ে এই প্রশ্নের উত্তর সংখ্যাগরিষ্ঠ হিসাবে একই দৃষ্টিভঙ্গি।
NemesisX00

আপনি 'ফাইনাল' অপসারণ করতে পারেন উল্লেখ করার জন্য +1। আপনার কোডের সমস্ত সম্ভাব্য ব্যবহারের পূর্বসূচী দাবি করা অহঙ্কারী। তবুও এটি স্পষ্ট করে বলা নম্র যে আপনি কয়েকটি সম্ভাব্য ব্যবহার বজায় রাখতে পারবেন না এবং এই ব্যবহারগুলির জন্য কাঁটাচামচ বজায় রাখা দরকার।
gmatht

4

আসুন কল্পনা করুন যে প্লাটফর্মের এসডিকে নিম্নলিখিত শ্রেণীর পাঠানো হয়েছে:

class HTTPRequest {
   void get(String url, String method = "GET");
   void post(String url) {
       get(url, "POST");
   }
}

একটি অ্যাপ্লিকেশন এই শ্রেণীর সাবক্লাস করে:

class MyHTTPRequest extends HTTPRequest {
    void get(String url, String method = "GET") {
        requestCounter++;
        super.get(url, method);
    }
}

সবকিছু ঠিকঠাক, তবে এসডিকে নিয়ে কাজ করা কেউ সিদ্ধান্ত নিয়েছে যে কোনও পদ্ধতিটি পাস getকরা মূর্খ, এবং ইন্টারফেসটিকে আরও ভালভাবে পিছনের সামঞ্জস্যতা প্রয়োগ করার বিষয়টি নিশ্চিত করে।

class HTTPRequest {
   @Deprecated
   void get(String url, String method) {
        request(url, method);
   }

   void get(String url) {
       request(url, "GET");
   }
   void post(String url) {
       request(url, "POST");
   }

   void request(String url, String method);
}

উপরে থেকে অ্যাপ্লিকেশনটি নতুন এসডিকে সঙ্গে সংযুক্ত না হওয়া পর্যন্ত সবকিছু ঠিক আছে বলে মনে হচ্ছে। হঠাৎ, ওভারডেন গেট পদ্ধতিটি আর কল করা হচ্ছে না, এবং অনুরোধটি গণনা করা হচ্ছে না।

একে ভঙ্গুর বেস শ্রেণির সমস্যা বলা হয়, কারণ আপাতদৃষ্টিতে নিরীহ পরিবর্তনের ফলে একটি সাবক্লাস ভেঙে যায়। ক্লাসের অভ্যন্তরে যে পদ্ধতিগুলি বলা হয় তা যেকোন সময় পরিবর্তনের ফলে একটি সাবক্লাস ভেঙে যেতে পারে। এর মানে হল যে প্রায় কোনও পরিবর্তনই একটি সাবক্লাস বিচ্ছিন্ন হতে পারে।

ফাইনাল আপনার ক্লাসটি সাবক্লাসিং থেকে কাউকে বাধা দেয়। এইভাবে, ক্লাসের অভ্যন্তরে কোন পদ্ধতিগুলি উদ্বেগ ছাড়াই পরিবর্তিত হতে পারে যে কোথাও কেউ ঠিক কোন পদ্ধতি কলগুলি করা হচ্ছে তার উপর নির্ভর করে।


1

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

চূড়ান্ত অর্থ হ'ল আপনি আপনার শ্রেণিটি আচরণের কোনও অনিচ্ছাকৃত পরিবর্তন ছাড়া অন্য ব্যক্তির কোডে বেজে যায় যা আপনার বেস হিসাবে নির্ভর করে।

উদাহরণস্বরূপ, আমি হব্বিটকিলার নামে একটি ক্লাস লিখি, এটি দুর্দান্ত, কারণ সমস্ত শখের কৌশলটি কৌশলযুক্ত এবং সম্ভবত মারা যেতে পারে। স্ক্র্যাচ করুন যে, তাদের অবশ্যই মারা যাওয়ার দরকার।

আপনি এটিকে বেস ক্লাস হিসাবে ব্যবহার করেন এবং শিখার যন্ত্র ব্যবহার করার জন্য একটি দুর্দান্ত একটি নতুন পদ্ধতি যুক্ত করুন, তবে আমার ক্লাসটিকে বেস হিসাবে ব্যবহার করুন কারণ হব্বিটগুলি লক্ষ্য করে তোলার জন্য আমার কাছে দুর্দান্ত পদ্ধতি রয়েছে (ট্র্যাকসি হওয়া ছাড়াও তারা দ্রুত), যা আপনি আপনার শিখার শক্তি লক্ষ্যতে সহায়তা করতে ব্যবহার করেন।

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

সুতরাং আমার বিবেকবান বিকাশকারী হওয়ার জন্য এবং আমার ক্লাসটি ব্যবহার করে ভবিষ্যতে মসৃণ হোবিট মৃত্যুর বিষয়টি নিশ্চিত করার জন্য, আমি যে ক্লাসে বাড়ানো যেতে পারে তার যে পরিবর্তন করি সে সম্পর্কে আমাকে খুব যত্নবান হতে হবে।

ক্লাসটি প্রসারিত করার ক্ষেত্রে আমি বিশেষভাবে যে বিষয়গুলি চাইছি সেগুলি ব্যতীত প্রসারের ক্ষমতা অপসারণ করে আমি নিজেকে (এবং আশা করি অন্যরা) প্রচুর মাথাব্যাথা বাঁচিয়েছি।


2
আপনি যদি লক্ষ্যবস্তু পদ্ধতি পরিবর্তন করতে চলেছেন তবে কেন আপনি এটিকে সর্বজনীন করেছেন? এবং যদি আপনি কোনও শ্রেণীর আচরণকে উল্লেখযোগ্যভাবে পরিবর্তন করেন তবে অতিরিক্ত final
সুবিধার

কেন এই পরিবর্তন হবে আমার কোন ধারণা নেই। হোবিটস ট্রিক্সি এবং পরিবর্তনের প্রয়োজন ছিল। মুল বক্তব্যটি হ'ল আমি যদি এটি চূড়ান্ত হিসাবে গড়ে তুলি তবে আমি উত্তরাধিকার রোধ করি যা আমার লোকদের কোডগুলি সংক্রামিত হতে বাধা দেয় other
স্কট টেলর

0

এর ব্যবহার finalকোনওভাবেই সলিড নীতি লঙ্ঘন নয়। দুর্ভাগ্যক্রমে, ওপেন / ক্লোজড নীতি ("সফ্টওয়্যার সত্তাগুলি এক্সটেনশনের জন্য উন্মুক্ত হওয়া উচিত তবে পরিবর্তনের জন্য বন্ধ করা উচিত") অর্থ "শ্রেণিটি পরিবর্তনের পরিবর্তে, এটি সাবক্লাস করে নতুন বৈশিষ্ট্য যুক্ত করার" অর্থ হিসাবে পরিচিত হওয়া অত্যন্ত সাধারণ। এটি মূলত এর দ্বারা বোঝানো হয়নি, এবং সাধারণত এটির লক্ষ্য অর্জনের সর্বোত্তম পন্থা হিসাবে বিবেচিত হয় না।

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

আরেকটি পদ্ধতি হ'ল আপনার শ্রেণিকে তার সর্বজনীন API সহ বিমূর্ত শ্রেণি (বা ইন্টারফেস) হিসাবে প্রয়োগ করা। তারপরে আপনি সম্পূর্ণ নতুন বাস্তবায়ন তৈরি করতে পারবেন যা একই ক্লায়েন্টগুলিতে প্লাগ ইন করতে পারে। যদি আপনার নতুন ইন্টারফেসের মূল হিসাবে মূলত বিস্তৃতভাবে একই আচরণের প্রয়োজন হয় তবে আপনি তা করতে পারেন:

  • আসল, বা এর বিদ্যমান আচরণ পুনরায় ব্যবহার করতে ডেকোরেটর ডিজাইন প্যাটার্নটি ব্যবহার করুন
  • আপনি কোনও সাহায্যকারী অবজেক্টে রাখতে চান এবং আপনার নতুন বাস্তবায়নে একই সহায়ক ব্যবহার করতে চান এমন আচরণের অংশগুলি রিফ্যাক্টর (রিফ্যাক্টরিং কোনও পরিবর্তন নয়)।

0

আমার কাছে এটি ডিজাইনের বিষয়।

ধরা যাক আমার কাছে এমন একটি প্রোগ্রাম রয়েছে যা কর্মীদের বেতন নির্ধারণ করে। যদি আমার কাছে এমন কোনও শ্রেণি থাকে যা দেশের উপর ভিত্তি করে 2 তারিখের (প্রতিটি দেশের জন্য এক শ্রেণি) মধ্যে কার্যদিবসের সংখ্যা দেয়, তবে আমি সেই চূড়ান্ত প্রতিস্থাপন করব এবং প্রতিটি এন্টারপ্রাইজকে কেবল তাদের ক্যালেন্ডারের জন্য একটি বিনামূল্যে দিন সরবরাহ করার জন্য একটি পদ্ধতি সরবরাহ করব।

কেন? সহজ। আসুন আমরা বলি যে কোনও বিকাশকারী একটি ক্লাস ওয়ার্কিংডেস ইউএসএমপি কম্পানিতে বেসড ক্লাস ওয়ার্কিংডেস ইউএসএ উত্তরাধিকারী হতে চায় এবং এটি সংশোধন করে এটি প্রতিস্থাপন করতে পারে যে তার উদ্যোগটি ধর্মঘট / রক্ষণাবেক্ষণ / ২ য় মার্সের কারণেই বন্ধ থাকবে।

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

অথবা যাক তারা ক্লাসের উত্তরাধিকারী এবং সংশোধন করে প্রতিফলিত করে যে এই সংস্থাটি শনিবারে কাজ করে না যেখানে তারা যেখানে শনিবার অর্ধবার কাজ করে। তারপরে একটি ভূমিকম্প, বিদ্যুতের সঙ্কট বা কোনও পরিস্থিতিতে রাষ্ট্রপতি 3 টি অ-কার্যদিবস ঘোষণা করেছিলেন যেমন ভেনেজুয়েলায় সম্প্রতি হয়েছিল। উত্তরাধিকার সূত্রে প্রাপ্ত শ্রেণীর পদ্ধতি যদি প্রতি শনিবার ইতিমধ্যে বিয়োগ হয় তবে মূল শ্রেণিতে আমার পরিবর্তনগুলি একই দিন দু'বার বিয়োগ করতে পারে। আমাকে প্রতিটি ক্লায়েন্টের প্রতিটি সাবক্লাসে যেতে হবে এবং সমস্ত পরিবর্তনগুলি সামঞ্জস্যপূর্ণ কিনা তা যাচাই করতে হবে।

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.