কোন ক্লাসগুলি বসন্তের দ্বারা স্বীকৃত হওয়া উচিত (কখন নির্ভরতা ইঞ্জেকশনটি ব্যবহার করতে হবে)?


32

আমি কিছুদিনের জন্য বসন্তে নির্ভরতা ইনজেকশন ব্যবহার করে আসছি এবং আমি বুঝতে পারি যে এটি কীভাবে কাজ করে এবং এটি ব্যবহারের কিছু কী কী মতামত রয়েছে। যাইহোক, আমি যখন একটি নতুন ক্লাস তৈরি করি তখন আমি প্রায়শই ভাবছি - এই ক্লাসটি কি স্প্রিং আইওসি কনটেইনার দ্বারা পরিচালিত হওয়া উচিত?

এবং আমি @ অটোভায়ার্ড টিকা, এক্সএমএল কনফিগারেশন, সেটার ইনজেকশন, কনস্ট্রাক্টর ইনজেকশন ইত্যাদির মধ্যে পার্থক্য সম্পর্কে কথা বলতে চাই না My আমার প্রশ্নটি সাধারণ general

ধরা যাক আমাদের একটি রূপান্তরকারী সহ একটি পরিষেবা আছে:

@Service
public class Service {

    @Autowired
    private Repository repository;

    @Autowired
    private Converter converter;

    public List<CarDto> getAllCars() {
        List<Car> cars = repository.findAll();
        return converter.mapToDto(cars);
    }
}

@Component
public class Converter {

    public CarDto mapToDto(List<Car> cars) {
        return new ArrayList<CarDto>(); // do the mapping here
    }
}

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

@Service
public class Service {

    @Autowired
    private Repository repository;

    public List<CarDto> getAllCars() {
        List<Car> cars = repository.findAll();
        Converter converter = new Converter();
        return converter.mapToDto(cars);
    }
}

এখন এটি পরীক্ষা করা আরও অনেক কঠিন। তদুপরি, প্রতিটি রূপান্তর ক্রিয়াকলাপের জন্য নতুন রূপান্তরকারী তৈরি করা হবে, যদিও এটি সর্বদা একই অবস্থায় থাকে, যা ওভারহেডের মতো মনে হয়।

স্প্রিং এমভিসিতে কয়েকটি সুপরিচিত নিদর্শন রয়েছে: সংগ্রহস্থলগুলি ব্যবহার করে পরিষেবা এবং পরিষেবা ব্যবহার করে নিয়ন্ত্রক using তারপরে, যদি रिपোজিটরিটি স্বতঃশক্ত হয় (যা এটি সাধারণত হয়) তবে পরিষেবাটিও স্বায়ত্তশাসিত হতে হবে। এবং এটি বেশ পরিষ্কার। তবে আমরা কখন কমপোন্ট টীকাটি ব্যবহার করব? আপনার যদি কিছু স্থির ব্যবহারের ক্লাস থাকে (যেমন রূপান্তরকারী, ম্যাপার্স) - আপনি সেগুলি স্বতঃসম্পাদন করেন?

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

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

আমি এই বিষয় সম্পর্কে কোনও টিপস জন্য কৃতজ্ঞ হবে!


3
মূলত "1 কখন খুব বেশি এগিয়ে যায়?"
অ্যান্ডি হান্ট

উত্তর:


8

@ এরিকডব্লিউর মন্তব্যের সাথে একমত হোন এবং কেবল মনে রাখতে চান যে আপনি আপনার কোডটি সংক্ষিপ্ত রাখতে প্রারম্ভিক ব্যবহার করতে পারেন:

@Autowired
private Converter converter;

অথবা

private Converter converter = new Converter();

বা, যদি শ্রেণীর সত্যই কোনও রাজ্য না থাকে

private static final Converter CONVERTER = new Converter();

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

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


5

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


2

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

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

আমি আরও ধরে নিয়েছি যে আলাদা আলাদা ডিটিও রূপান্তরকারী ব্যবহার করার কোনও কারণ নেই।


0

টিএল; ডিআর: ডিআই-র জন্য অটোয়ারিংয়ের একটি হাইব্রিড পদ্ধতি এবং ডিআইয়ের জন্য কনস্ট্রাক্টর ফরোয়ার্ডিং আপনার উপস্থাপিত কোডটিকে সহজতর করতে পারে।

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

@Service
public class Service {

    @Autowired
    private Repository repository;

    public List<CarDto> getAllCars(Converter converter) {
        List<Car> cars = repository.findAll();
        return converter.mapToDto(cars);
    }
    public List<CarDto> getAllCars() {
        Converter converter = new Converter();
        return getAllCars(converter);
    }
}

এমনকি রবের উত্তর বন্ধ করে দেওয়া

@Service
public class Service {

    @Autowired
    private Repository repository;

    private final Converter converter = new Converter(); // static if safe for that

    public List<CarDto> getAllCars(Converter converter) {
        List<Car> cars = repository.findAll();
        return converter.mapToDto(cars);
    }
    public List<CarDto> getAllCars() {
        return getAllCars(converter);
    }
}

এটিতে সর্বজনীন ইন্টারফেস পরিবর্তনের প্রয়োজন নাও হতে পারে তবে আমি চাই। তবুও

public List<CarDto> getAllCars(Converter converter) { ... }

কেবল পরীক্ষার উদ্দেশ্যে / এক্সটেনশনের জন্য স্কোপ ডাউন বা সুরক্ষিত বা ব্যক্তিগত করা যেতে পারে।

মূল বিষয় হ'ল ডিআই .চ্ছিক। একটি ডিফল্ট সরবরাহ করা হয়, যা সরাসরি এগিয়ে পদ্ধতিতে ওভাররাইড করা যায়। ক্ষেত্রের সংখ্যা বাড়ার সাথে সাথে এটি দুর্বলতা রয়েছে তবে 1 এর জন্য, সম্ভবত 2 টি ক্ষেত্র, আমি এটি নিম্নলিখিত শর্তে পছন্দ করি:

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

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

@Service
public class Service {

   @Autowired
   private Repository repository;

   public List<CarDto> getAllCars() {
    return repository.findAll().stream.map(c -> c.mapToDto()).collect(Collectors.toList()));
   }
}

-1

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

getCurrentUser ()

isAuthenticated ()

#CenterUserInRole (কর্তৃপক্ষ কর্তৃপক্ষ)

প্রভৃতি

এবং আমি এগুলি কখনই স্বীকৃত করি নি। জেহিস্টার (যা আমি সেরা অনুশীলনের বেশ ভাল বিচারক হিসাবে ব্যবহার করি) তা করে না।


-2

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


3
এই পোস্টটি পড়ার চেয়ে শক্ত (পাঠ্যের প্রাচীর)। আপনি এটিকে আরও ভাল আকারে সম্পাদনা করতে আপত্তি করবেন ?
gnat
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.