অন্য বিকাশকারীদের কাজ শেষ করার পরে কল করার জন্য বল প্রয়োগ করুন


34

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

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

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

দ্রষ্টব্য: আমি release()পদ্ধতিটিতে পদ্ধতিটি কল করতে পারি না doWork(), কারণ doWork() পরবর্তী সময়ে যখন ডাকা হয় তখন objects বস্তুগুলির প্রয়োজন।


46
আপনি সেখানে যা করছেন তা হ'ল অস্থায়ী সংযুক্তির একটি ফর্ম এবং সাধারণত একটি কোড গন্ধ হিসাবে বিবেচিত। পরিবর্তে আপনি আরও ভাল ডিজাইন নিয়ে আসতে বাধ্য করতে পারেন want
ফ্রাঙ্ক

1
@ ফ্র্যাঙ্ক আমি সম্মত হই, যদি অন্তর্নিহিত স্তরটির নকশা পরিবর্তন করা যদি একটি বিকল্প হয় তবে এটি সর্বোত্তম বাজি হবে। তবে আমি সন্দেহ করি এটি অন্য কারও পরিষেবাতে মোড়ক is
ডার ব্রেট

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

18
এটি প্রয়োজন খুব "আন-জাভা"। জাভা আবর্জনা সংগ্রহের একটি ভাষা এবং এখন আপনি কিছু ধরণের contraceptions নিয়ে এসেছেন যাতে আপনার বিকাশকারীদের "পরিষ্কার করতে" প্রয়োজন।
পিটার বি

22
@ পিটারবি কেন? AutoCloseableএই সঠিক উদ্দেশ্যে তৈরি করা হয়েছিল।
বিজিআর ওয়ার্কার

উত্তর:


48

ব্যবহারিক সমাধানটি ক্লাস তৈরি করা AutoCloseableএবং finalize()ব্যাকস্টপ হিসাবে একটি পদ্ধতি সরবরাহ করা (যদি উপযুক্ত হয় ... নীচে দেখুন!)। তারপরে আপনি রিসোর্স উইথ রিসোর্স বা close()স্পষ্টভাবে কল করার জন্য আপনার শ্রেণীর ব্যবহারকারীদের উপর নির্ভর করেন ।

অবশ্যই আমি এটি ডকুমেন্ট করতে পারি, তবে আমি তাদের জোর করতে চাই।

দুর্ভাগ্যবশত, কোন উপায় নেই 1 জাভা ডান জিনিস করতে প্রোগ্রামার বলপূর্বক। আপনি যেটি সবচেয়ে ভাল আশা করতে পারেন তা হ'ল স্থিতিশীল কোড বিশ্লেষকের ভুল ব্যবহার বাছাই করা।


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

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

এবং কেবলমাত্র যদি আমি উপরে যা বলি তা আপনি না পেয়ে থাকেন ... প্রোডাকশন কোডে চূড়ান্তকরণগুলি ব্যবহার করা প্রায়শই উপযুক্ত নয় এবং আপনার কখনই তাদের উপর নির্ভর করা উচিত নয় !


1 - উপায় আছে। আপনি যদি ব্যবহারকারী কোড থেকে পরিষেবা অবজেক্টগুলিকে "আড়াল" করতে প্রস্তুত হন বা তাদের জীবনচক্রকে শক্তভাবে নিয়ন্ত্রণ করতে চান (যেমন https://softwareengineering.stackexchange.com/a/345100/172 ) তবে ব্যবহারকারীদের কোড কল করার প্রয়োজন নেই release()। তবে, API আরও জটিল, সীমাবদ্ধ ... এবং "কুরুচিপূর্ণ" আইএমও হয়ে যায়। এছাড়াও, এটি প্রোগ্রামারকে সঠিক জিনিস করতে বাধ্য করছে না । এটি প্রোগ্রামারটির ভুল কাজ করার ক্ষমতা সরিয়ে দিচ্ছে!


1
ফাইনালাইজাররা খুব খারাপ পাঠ দেয় - আপনি যদি এটি স্ক্রু করেন তবে আমি এটি আপনার জন্য ঠিক করব। আমি নেটটির পদ্ধতির পছন্দ করি -> একটি কনফিগারেশন প্যারামিটার যা (বাইটবফার) কারখানাকে এলোমেলোভাবে একটি ফাইনালাইজারের সাহায্যে এক্স% বাইটবফারগুলির সম্ভাব্যতা তৈরি করতে নির্দেশ দেয় যা এই বাফারটি যেখানে স্থান অর্জন করেছিল (যেখানে ইতিমধ্যে প্রকাশিত হয়নি) তা মুদ্রণ করে। সুতরাং উত্পাদনে এই মান 0% - যেমন কোনও ওভারহেড সেট করা যাবে না এবং পরীক্ষার সময় এবং পণ্যটি ছাড়ার আগে
ফাঁসগুলি

11
এবং মনে রাখবেন যে চূড়ান্তকরণগুলি কখনও চালানোর গ্যারান্টিযুক্ত নয়, এমনকি যদি বস্তুর উদাহরণটি আবর্জনা সংগ্রহ করা হয়!
jwenting

3
এটি লক্ষণীয় যে, যদি একটি অটো-ক্লাসেবল বন্ধ না করা হয় তবে Eclipse একটি সংকলক সতর্কতা প্রেরণ করে। আমি অন্যান্য জাভা আইডিইও এটির আশা করি।
মেরিটন -

1
@ জওয়ান্টিং যখন জিনিসটি জিসিডি করা হয় তখন তারা কোন ক্ষেত্রে চলবে না? এটির বিবরণী বা ব্যাখ্যা দেওয়ার মতো কোনও উত্স আমি পাই না।
সিড্রিক রেইচেনবাচ

3
@ ভু আপনি আমার মন্তব্য ভুল বুঝেছেন। আপনি দুটি বাস্তবায়নের আছে -> DefaultResourceএবং FinalizableResourceযা প্রথম এক প্রসারিত এবং একটি finalizer যোগ করা হয়েছে। উত্পাদনে আপনি ব্যবহার করেন DefaultResourceযা চূড়ান্ত নয় -> ওভারহেড নেই। বিকাশ এবং পরীক্ষার সময় আপনি অ্যাপটিকে ব্যবহার করতে কনফিগার করেন FinalizableResourceযার একটি চূড়ান্তকরণকারী রয়েছে এবং তাই ওভারহেড যুক্ত করে। দেব এবং পরীক্ষার সময় এটি কোনও সমস্যা নয়, তবে এটি আপনাকে ফুটা সনাক্ত করতে এবং উত্পাদন পৌঁছানোর আগে এগুলি ঠিক করতে সহায়তা করে। তবুও যদি কোনও ফাঁস পিআরডি পৌঁছে যায় তবে আপনি FinalizableResourceফাঁস
আইডিতে

55

এই জন্য ব্যবহারে-কেস মত মনে হয় AutoCloseableইন্টারফেস এবং try-with-resourcesবিবৃতি জাভা 7. চালু তোমার মত কিছু থাকে, তাহলে

public class MyService implements AutoCloseable {
    public void doWork() {
        // ...
    }

    @Override
    public void close() {
        // release resources
    }
}

তাহলে আপনার গ্রাহকরা এটি হিসাবে ব্যবহার করতে পারেন

public class MyConsumer {
    public void foo() {
        try (MyService myService = new MyService()) {
            //...
            myService.doWork()
            //...
            myService.doWork()
            //...
        }
    }
}

এবং releaseতাদের কোডটি ব্যতিক্রম ছোঁড়ে কিনা তা নির্বিশেষে সুস্পষ্ট কল করার বিষয়ে চিন্তা করার দরকার নেই ।


অতিরিক্ত উত্তর

আপনি যা খুঁজছেন তা যদি নিশ্চিত হয় যে কেউ আপনার ফাংশনটি ব্যবহার করতে ভুলে যেতে না পারে, আপনাকে কয়েকটি জিনিস করতে হবে

  1. নিশ্চিত করুন যে সমস্ত নির্মাণকারীই MyServiceব্যক্তিগত।
  2. ব্যবহারের জন্য প্রবেশের একক পয়েন্টটি সংজ্ঞায়িত করুন MyServiceযা এটি পরে পরিষ্কার হয়ে গেছে তা নিশ্চিত করে।

আপনি যেমন কিছু করতে হবে

public interface MyServiceConsumer {
    void accept(MyService value);
}

public class MyService implements AutoCloseable {
    private MyService() {
    }


    public static void useMyService(MyServiceConsumer consumer) {
        try (MyService myService = new MyService()) {
            consumer.accept(myService)
        }
    }
}

আপনি তারপর এটি হিসাবে ব্যবহার করবে

public class MyConsumer {
    public void foo() {
        MyService.useMyService(new MyServiceConsumer() {
            public void accept(MyService myService) {
                myService.doWork()
            }
        });
    }
}

আমি মূলত এই পাথটি সুপারিশ করিনি কারণ এটি জাভা -8 ল্যাম্বডাস এবং ক্রিয়ামূলক ইন্টারফেসগুলি (যেখানে MyServiceConsumerহয় Consumer<MyService>) ছাড়াই ঘৃণ্য এবং এটি আপনার গ্রাহকদের উপর মোটামুটি চাপিয়ে দিচ্ছে। তবে আপনি যদি কেবল যা চান তা release()অবশ্যই কল করা উচিত, এটি কার্যকর হবে।


1
এই উত্তরটি আমার চেয়ে সম্ভবত ভাল। আমার পথ আবর্জনা আগে একটি বিলম্ব কালেক্টর কিক হয়েছে।
দার ব্রেট

1
আপনি কিভাবে নিশ্চিত যে ক্লায়েন্ট ব্যবহার করবে try-with-resourcesএবং মাত্র বাদ না try, এইভাবে অনুপস্থিত closeকল?
ফ্রাঙ্ক

@ ওয়ালপেন এইভাবে একই সমস্যা রয়েছে। আমি কীভাবে ব্যবহারকারীকে ব্যবহার করতে বাধ্য করতে পারি try-with-resources?
hasanghaforian

1
@ ফ্র্যাঙ্ক / @ হাসানঘাফোরিয়ান, হ্যাঁ, এই পথটি কাছাকাছি ডাকার জন্য জোর করে না। এতে পরিচিতির সুবিধা রয়েছে: জাভা বিকাশকারীরা জানেন .close()ক্লাস যখন প্রয়োগ করে তখন আপনাকে অবশ্যই বলা উচিত AutoCloseable
ওয়ালেপেন

1
usingডিটারমিনিস্টিক চূড়ান্তকরণের জন্য আপনি কোনও ব্লকের সাথে চূড়ান্তকরণকারীর জুটি রাখতে পারেননি ? কমপক্ষে সি # এ, নির্বাহী চূড়ান্তকরণের প্রয়োজন এমন সংস্থানসমূহের উত্তোলন করার সময় বিকাশকারীদের ব্যবহারের অভ্যাস পেতে এটি একটি খুব স্পষ্ট নিদর্শন হয়ে ওঠে। আপনি কাউকে কিছু করার জন্য জোর করতে না পারলে কিছু সহজ এবং অভ্যাস গঠনের পরের সেরা জিনিস thing stackoverflow.com/a/2016311/84206
AaronLS

52

হ্যা, তুমি পারো

আপনি তাদের মুক্তি দিতে একেবারে বাধ্য করতে পারেন, এবং এটি তৈরি করে 100% ভুলে যাওয়া অসম্ভব, তাদের পক্ষে নতুন Serviceউদাহরণ তৈরি করা অসম্ভব করে ।

তারা যদি এর আগে এমন কিছু করে থাকে:

Service s = s.new();
try {
  s.doWork("something");
  if (...) s.doWork("something else");
  ...
}
finally {
  s.release(); // oops: easy to forget
}

তারপরে এটি পরিবর্তন করুন যাতে তাদের অবশ্যই এটির মতো অ্যাক্সেস করতে হবে।

// Their code

Service.runWithRelease(new ServiceConsumer() {
  void run(Service s) {
    s.doWork("something");
    if (...) s.doWork("something else");
    ...
  }  // yay! no s.release() required.
}

// Your code

interface ServiceConsumer {
  void run(Service s);
}

class Service {

   private Service() { ... }      // now: private
   private void release() { ... } // now: private
   public void doWork() { ... }   // unchanged

   public static void runWithRelease(ServiceConsumer consumer) {
      Service s = new Service();
      try {
        consumer.run(s);
      }
      finally {
        s.release();
      } 
    } 
  }

আদেশ সহকারে:

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

2
ডাউনভোটের জন্য মন্তব্য সম্পর্কে আমি খুশি, তাই আমি উত্তরটি উন্নত করতে পারি।
আনোই

2
আমি ডাউনভিট করিনি, তবে এই নকশাটি এর মূল্য হিসাবে বেশি ঝামেলা হতে পারে। এটি জটিলতার একটি মহান চুক্তি যুক্ত করে এবং কলকারীদের উপর একটি বিশাল বোঝা চাপিয়ে দেয়। বিকাশকারীদের চেষ্টা-সংস্থান-স্টাইলের ক্লাসগুলির সাথে যথেষ্ট পরিচিত হওয়া উচিত যে যখনই কোনও শ্রেণি যথাযথ ইন্টারফেস প্রয়োগ করে তবে এগুলি ব্যবহার করা দ্বিতীয় প্রকৃতির।
jpmc26

30
@ jpmc26, অদ্ভুতভাবে আমি মনে করি যে পদ্ধতির হ্রাস উপর জটিলতা এবং বোঝা কলারের তাদের সকলের দিকে রিসোর্স জীবনচক্র সম্পর্কে চিন্তা থেকে সংরক্ষণ করে। ঐটার পাশে; ওপিতে "আমাকে কি ব্যবহারকারীদের জোর করা উচিত ..." জিজ্ঞাসা করা হয়নি তবে "আমি কীভাবে ব্যবহারকারীদের বাধ্য করব" " এবং যদি এটি যথেষ্ট গুরুত্বপূর্ণ হয় তবে এটি একটি সমাধান যা খুব ভালভাবে কাজ করে, কাঠামোগতভাবে সহজ (কেবল এটি একটি ক্লোজার / রান্নেবলের মধ্যে মোড়ানো), এমনকি অন্যান্য ভাষাগুলিতেও বদলিযোগ্য যা ল্যাম্বডাস / প্রোকস / ক্লোজার রয়েছে। ঠিক আছে, আমি বিচারের জন্য এটি এসই গণতন্ত্রের কাছে ছেড়ে দেব; ওপি ইতিমধ্যে যাইহোক সিদ্ধান্ত নিয়েছে। ;)
আনোই

14
আবার, @ jpmc26, আমি যে কোনও একক ব্যবহারের ক্ষেত্রে এই পদ্ধতির সঠিক কিনা তা নিয়ে আলোচনায় আমি তেমন আগ্রহী নই। ওপি জিজ্ঞাসা করে যে এই জাতীয় জিনিসটি কীভাবে প্রয়োগ করা যায় এবং এই উত্তরটি কীভাবে এই জাতীয় জিনিসটি প্রয়োগ করতে হয় তা বলে । এটি প্রথম স্থানে করা উপযুক্ত কিনা তা আমাদের সিদ্ধান্ত নেওয়া উচিত নয়। আমার দেখানো কৌশলটি একটি সরঞ্জাম, আরও কিছু নয়, কম কিছু নয়, এবং সরঞ্জামগুলির ব্যাগ-অফ-সরঞ্জাম থাকতে দরকারী, আমি বিশ্বাস করি।
AnoE

11
এটি ইমো সঠিক উত্তর, এটি মূলত মাঝের প্যাটার্নটি
জেকে

11

আপনি কমান্ড প্যাটার্নটি ব্যবহার করার চেষ্টা করতে পারেন ।

class MyServiceManager {

    public void execute(MyServiceTask tasks...) {
        // set up everyting
        MyService service = this.acquireService();
        // execute the submitted tasks
        foreach (Task task : tasks)
            task.executeWith(service);
        // cleanup yourself
        service.releaseResources();
    }

}

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

একটি ধরা কিন্তু, এখন পর্যন্ত। কলার এখনও এটি করতে পারে:

MyServiceTask t1 = // some task
manager.execute(t1);
MyServiceTask t2 = // some task
manager.execute(t2);

এটি যখন উদ্ভূত হয় তবে আপনি এই সমস্যাটি সমাধান করতে পারেন। যখন কার্য সম্পাদনের সমস্যা হয় এবং আপনি যখন খুঁজে পান যে কিছু কলার এটি করেন, কেবল তাদের সঠিক উপায়টি দেখান এবং সমস্যাটি সমাধান করুন:

MyServiceTask t1 = // some task
MyServiceTask t2 = // some task
manager.execute(t1, t2);

অন্যান্য কাজের উপর নির্ভরশীল কর্মগুলির প্রতিশ্রুতি বাস্তবায়ন করে আপনি এই স্বেচ্ছাসেবক জটিল করে তুলতে পারেন, তবে স্টাফ প্রকাশ করা আরও জটিল হয়ে যায়। এটি কেবল একটি সূচনা পয়েন্ট।

এসিঙ্ক

মতামত হিসাবে ইশারা করা হয়েছে, উপরোক্ত সত্যই অ্যাসিনক্রোনাস অনুরোধ সঙ্গে কাজ করে না। এটাই সঠিক. কিন্তু এই সহজে ব্যবহারের সঙ্গে জাভা 8 সমাধান করা যেতে পারে CompleteableFuture , বিশেষ করে CompleteableFuture#supplyAsyncপৃথক ফিউচার তৈরি এবং CompleteableFuture#allOfসম্পদ মুক্তির perfom একবার সব কাজগুলো শেষ করেছে। বিকল্পভাবে, কোনও ব্যক্তি সর্বদা থ্রেডস বা এক্সিকিউটার সার্ভিসগুলি ফিউচার / প্রতিশ্রুতিগুলির নিজস্ব বাস্তবায়ন রোল করতে ব্যবহার করতে পারেন।


1
আমি যদি এটিকে খারাপ বলে মনে করি তবে নেতিবাচক লোকেরা যদি কোনও মন্তব্য করেন তবে আমি এটির প্রশংসা করব, যাতে আমি সরাসরি এই উদ্বেগগুলি সমাধান করতে পারি বা কমপক্ষে ভবিষ্যতের জন্য অন্য একটি দৃষ্টিভঙ্গি পাই। ধন্যবাদ!
পলিনগনো

+1 upvote। এটি একটি পদ্ধতির হতে পারে, তবে পরিষেবাটি অ্যাসিঙ্ক এবং পরবর্তী পরিষেবাটি জিজ্ঞাসা করার আগে ভোক্তার প্রথম ফলাফল পাওয়া দরকার।
hasanghaforian

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

3

আপনি যদি পারেন তবে ব্যবহারকারীকে সংস্থান তৈরি করতে দেবেন না। ব্যবহারকারীকে আপনার পদ্ধতিতে একটি দর্শনার্থী বস্তুটি পাস করতে দিন, যা উত্স তৈরি করবে, এটি দর্শকের অবজেক্টের পদ্ধতিতে প্রেরণ করবে এবং তারপরে মুক্তি পাবে।


আপনার জবাবের জন্য আপনাকে ধন্যবাদ, তবে আমাকে ক্ষমা করবেন, আপনি কি বোঝাতে চেয়েছেন যে গ্রাহকের কাছে সংস্থান স্থাপন করা আরও ভাল এবং সে যখন সেবার জন্য জিজ্ঞাসা করবে তখন এটি আবার পাওয়া উচিত? তারপরে সমস্যাটি থেকে যাবে: গ্রাহকরা এই সংস্থানগুলি ছেড়ে দিতে ভুলে যেতে পারেন।
hasanghaforian

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

1

আমার ধারণাটি পলিনোমের মতো ছিল।

আপনার ক্লাসে "do_something ()" পদ্ধতি থাকতে পারে একটি বেসরকারী কমান্ড তালিকায় কমান্ড যুক্ত করতে পারেন। তারপরে, একটি "কমিট ()" পদ্ধতি থাকুন যা আসলে কাজ করে এবং "রিলিজ ()" বলে।

সুতরাং, যদি ব্যবহারকারী কখনও প্রতিশ্রুতি () না বলে, কাজটি কখনই সম্পন্ন হয় না। তারা যদি করে তবে সম্পদগুলি মুক্ত হয়।

public class Foo
{
  private ArrayList<ICommand> _commands;

  public Foo doSomething(int arg) { _commands.Add(new DoSomethingCommand(arg)); return this; }
  public Foo doSomethingElse() { _commands.Add(new DoSomethingElseCommand()); return this; }

  public void commit() { 
     for(ICommand c : _commands) c.doWork();
     release();
     _commands.clear();
  }

}

এরপরে আপনি এটি foo.doSomething.doSomethineElse ()। কমিট () এর মতো ব্যবহার করতে পারেন;


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

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

-1

উল্লিখিতগুলির আরও একটি বিকল্প হ'ল "স্মার্ট রেফারেন্স" এর ব্যবহারটি আপনার এনক্যাপসুলেটেড রিসোর্সগুলি এমনভাবে পরিচালনা করতে পারে যা আবর্জনা সংগ্রাহককে ম্যানুয়ালি সম্পদ মুক্ত না করে স্বয়ংক্রিয়ভাবে পরিষ্কার করতে সক্ষম করে। তাদের কার্যকারিতা অবশ্যই আপনার প্রয়োগের উপর নির্ভর করে। এই দুর্দান্ত ব্লগ পোস্টে এই বিষয়টিতে আরও পড়ুন: https://commune.oracle.com/blogs/enicholas/2006/05/04/ বোঝাবুঝি


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

-4

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

@Override
public void finalize() {
    this.release();
}

আমি জাভার সাথে খুব বেশি পরিচিত নই, তবে আমি মনে করি যে এটিই সেই উদ্দেশ্যে যা চূড়ান্ত করতে হবে ()।

http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#finalize ()


7
স্টিফেন তার উত্তরে বলেছিলেন যে কারণে এই সমস্যার একটি খারাপ সমাধান -If you rely on finalizers to tidy up, you run into the problem that it can take a very long time for the tidy-up to happen. The finalizer will only be run after the GC decides that the object is no longer reachable. That may not happen until the JVM does a full collection.
দেনিথ

4
এবং তারপরেও ফাইনালাইজারটি বাস্তবে চালাতে পারে না ...
উঠেছে

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

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