ড্যাজার- প্রতিটি ক্রিয়াকলাপ / খণ্ডের জন্য আমাদের প্রতিটি উপাদান এবং মডিউল তৈরি করা উচিত?


85

আমি কিছু সময়ের জন্য ডাগার 2 নিয়ে কাজ করছি। এবং আমি প্রতিটি ক্রিয়াকলাপ / খণ্ডের জন্য নিজস্ব উপাদান / মডিউল তৈরি করতে বিভ্রান্ত হয়ে পড়েছি। দয়া করে আমাকে এটি পরিষ্কার করতে সহায়তা করুন:

উদাহরণস্বরূপ, আমাদের একটি অ্যাপ রয়েছে এবং অ্যাপটিতে প্রায় 50 টি স্ক্রিন রয়েছে। আমরা ডিভিয়ের জন্য এমভিপি প্যাটার্ন এবং ড্যাগার 2 অনুসরণ করে কোডটি প্রয়োগ করব। মনে করুন যে আমাদের 50 টি ক্রিয়াকলাপ এবং 50 জন উপস্থাপক রয়েছে।

আমার মতে, সাধারণত আমাদের কোডটি এভাবে সাজানো উচিত:

  1. একটি অ্যাপকোম্পোনেন্ট এবং অ্যাপমোডুল তৈরি করুন যা অ্যাপ্লিকেশনটি খোলা থাকাকালীন ব্যবহৃত সমস্ত সামগ্রী সরবরাহ করবে।

    @Module
    public class AppModule {
    
        private final MyApplicationClass application;
    
        public AppModule(MyApplicationClass application) {
            this.application = application;
        }
    
        @Provides
        @Singleton
        Context provideApplicationContext() {
            return this.application;
        }
    
        //... and many other providers 
    
    }
    
    @Singleton
    @Component( modules = { AppModule.class } )
    public interface AppComponent {
    
        Context getAppContext();
    
        Activity1Component plus(Activity1Module module);
        Activity2Component plus(Activity2Module module);
    
        //... plus 48 methods for 48 other activities. Suppose that we don't have any other Scope (like UserScope after user login, ....)
    
    }
    
  2. অ্যাক্টিভিটিস্কোপ তৈরি করুন:

    @Scope
    @Documented
    @Retention(value=RUNTIME)
    public @interface ActivityScope {
    }
    
  3. প্রতিটি ক্রিয়াকলাপের জন্য উপাদান এবং মডিউল তৈরি করুন। সাধারণত আমি তাদের ক্রিয়াকলাপ শ্রেণীর মধ্যে স্ট্যাটিক ক্লাস হিসাবে রাখি:

    @Module
    public class Activity1Module {
    
        public LoginModule() {
        }
        @Provides
        @ActivityScope
        Activity1Presenter provideActivity1Presenter(Context context, /*...some other params*/){
            return new Activity1PresenterImpl(context, /*...some other params*/);
        }
    
    }
    
    @ActivityScope
    @Subcomponent( modules = { Activity1Module.class } )
    public interface Activity1Component {
        void inject(Activity1 activity); // inject Presenter to the Activity
    }
    
    // .... Same with 49 remaining modules and components.
    

আমি কীভাবে এটি বাস্তবায়ন করব তা দেখানোর জন্য সেগুলি কেবল খুব সাধারণ উদাহরণ।

তবে আমার এক বন্ধু আমাকে আরও একটি বাস্তবায়ন দিয়েছে:

  1. PresenterModule তৈরি করুন যা সমস্ত উপস্থাপক সরবরাহ করবে:

    @Module
    public class AppPresenterModule {
    
        @Provides
        Activity1Presenter provideActivity1Presentor(Context context, /*...some other params*/){
            return new Activity1PresenterImpl(context, /*...some other params*/);
        }
    
        @Provides
        Activity2Presenter provideActivity2Presentor(Context context, /*...some other params*/){
            return new Activity2PresenterImpl(context, /*...some other params*/);
        }
    
        //... same with 48 other presenters.
    
    }
    
  2. AppModule এবং AppComp घटक তৈরি করুন:

    @Module
    public class AppModule {
    
        private final MyApplicationClass application;
    
        public AppModule(MyApplicationClass application) {
            this.application = application;
        }
    
        @Provides
        @Singleton
        Context provideApplicationContext() {
            return this.application;
        }
    
        //... and many other provides 
    
    }
    
    @Singleton
    @Component(
            modules = { AppModule.class,  AppPresenterModule.class }
    )
    public interface AppComponent {
    
        Context getAppContext();
    
        public void inject(Activity1 activity);
        public void inject(Activity2 activity);
    
        //... and 48 other methods for 48 other activities. Suppose that we don't have any other Scope (like UserScope after user login, ....)
    
    }
    

তার ব্যাখ্যাটি হ'ল: প্রতিটি ক্রিয়াকলাপের জন্য তাকে উপাদান এবং মডিউল তৈরি করতে হবে না। আমি মনে করি আমার বন্ধুদের ধারণা একেবারেই ভাল নয়, তবে আমি ভুল হলে দয়া করে আমাকে সংশোধন করুন। এখানে কারণগুলি:

  1. প্রচুর স্মৃতি ফাঁস :

    • ব্যবহারকারীটির কেবল 2 টি ক্রিয়াকলাপ খোলা থাকলেও অ্যাপটি 50 টি উপস্থাপক তৈরি করবে।
    • ব্যবহারকারী কোনও কার্যকলাপ বন্ধ করার পরে, তার উপস্থাপক এখনও রয়ে যাবে
  2. যদি আমি একটি ক্রিয়াকলাপের দুটি উদাহরণ তৈরি করতে চাই তবে কী হবে? (তিনি কীভাবে দুটি উপস্থাপক তৈরি করতে পারেন)

  3. অ্যাপ্লিকেশনটি আরম্ভ করতে অনেক সময় লাগবে (কারণ এতে অনেক উপস্থাপক, বস্তু তৈরি করতে হবে ...)

দীর্ঘ পোস্টের জন্য দুঃখিত, তবে দয়া করে আমাকে এবং আমার বন্ধুর জন্য এটি পরিষ্কার করতে আমাকে সহায়তা করুন, আমি তাকে বোঝাতে পারি না। আপনার মন্তব্য খুব প্রশংসা করা হবে।

/ ------------------------------------------------- ---------------------- /

একটি ডেমো করার পরে সম্পাদনা করুন।

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

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

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

  1. এটি উত্সের আর্কিটেকচারের পক্ষে ভাল নয়, যখন তিনি মডিউল / উপাদানগুলিতে সমস্ত উপস্থাপককে ইনটাইট করেন। (এটি ইন্টারফেস বিভাজন নীতি লঙ্ঘন করে , সম্ভবত একক দায়িত্বের পূর্বেও))

  2. যখন আমরা কোনও স্কোপ উপাদান তৈরি করি তখন আমরা জানতে পারি এটি কখন তৈরি এবং কখন এটি ধ্বংস হয়ে যায় যা মেমরি ফাঁস এড়ানোর জন্য একটি বিশাল সুবিধা। সুতরাং, প্রতিটি ক্রিয়াকলাপের জন্য আমাদের একটি @ActivityScope দিয়ে একটি উপাদান তৈরি করা উচিত। আসুন কল্পনা করুন, আমার বন্ধুদের বাস্তবায়নের সাথে, আমরা সরবরাহকারীর পদ্ধতিতে কোনও স্কোপ রাখতে ভুলে গেছি => মেমরি ফাঁস হবে।

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

আরও পড়তে পছন্দ করুন: ডাগার 2 এ কোন উপাদানটির জীবনচক্রটি (অবজেক্ট গ্রাফ) নির্ধারণ করে? ডাগার 2 কার্যকলাপের সুযোগ, আমার কতগুলি মডিউল / উপাদানগুলির প্রয়োজন?

এবং আরও একটি দ্রষ্টব্য: আপনি যদি দেখতে চান যে কখন বস্তুটি ধ্বংস হয়ে যায়, আপনি সেই পদ্ধতিগুলিকে একসাথে কল করতে পারেন এবং জিসি তত্ক্ষণাত্ চলবে:

    System.runFinalization();
    System.gc();

আপনি যদি এই পদ্ধতিগুলির মধ্যে একটি ব্যবহার করেন তবে জিসি পরে চালানো হবে এবং আপনি ভুল ফলাফল পেতে পারেন।

উত্তর:


85

প্রত্যেকের জন্য পৃথক মডিউল ঘোষণা Activityকরা মোটেই ভাল ধারণা নয়। প্রতিটি জন্য পৃথক উপাদান ঘোষণা Activityআরও খারাপ। এর পিছনে যুক্তি খুব সহজ - আপনার সত্যিকারের এই সমস্ত মডিউল / উপাদানগুলির প্রয়োজন নেই (যেমন আপনি ইতিমধ্যে নিজেরাই দেখেছেন)।

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

  1. এটি আপনাকে কেবল একটি সুযোগে ( @Singletonবা একটি কাস্টম হিসাবে) সীমাবদ্ধ করে
  2. আপনি কেবলমাত্র ইনজেকশনের অবজেক্টগুলিকে "অ্যাপ্লিকেশন সিঙ্গেলন" তৈরি করতে সীমাবদ্ধ রেখেছেন, তাই স্কোপিংয়ে ভুল বা স্কোপযুক্ত বস্তুর ভুল ব্যবহার সহজেই বিশ্বব্যাপী মেমরি ফাঁসের কারণ হতে পারে
  3. Servicesখুব ইনজেকশন করার জন্য আপনি ডাগার 2 ব্যবহার করতে চাইবেন তবে এর Servicesচেয়ে বিভিন্ন বস্তুর প্রয়োজন হতে পারে Activities(যেমন Servicesউপস্থাপকের দরকার নেই FragmentManager, নেই ইত্যাদি)। একটি একক উপাদান ব্যবহার করে আপনি বিভিন্ন উপাদানগুলির জন্য বিভিন্ন অবজেক্টের গ্রাফগুলি সংজ্ঞায়নের নমনীয়তাটি আলগা করেন।

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

আমি নিম্নলিখিত পদ্ধতির ব্যবহার:

  1. একক "অ্যাপ্লিকেশন" উপাদান যা "গ্লোবাল" অবজেক্ট সরবরাহ করে (উদাহরণস্বরূপ এমন বস্তু যা বিশ্বব্যাপী রাষ্ট্র ধারণ করে যা অ্যাপ্লিকেশনের সমস্ত উপাদানগুলির মধ্যে ভাগ করা থাকে)। ইনস্ট্যান্ট ইন Application
  2. "অ্যাপ্লিকেশন" উপাদানটির "কন্ট্রোলার" উপ-উপাদান যা সমস্ত ব্যবহারকারীর মুখোমুখি "কন্ট্রোলার" দ্বারা প্রয়োজনীয় জিনিসগুলি সরবরাহ করে (আমার আর্কিটেকচারে এগুলি Activitiesএবং Fragments)। প্রতিটি ইনস্ট্যান্টেশন Activityএবং Fragment
  3. "অ্যাপ্লিকেশন" উপাদানটির "পরিষেবা" উপ-উপাদান যা সমস্তের জন্য প্রয়োজনীয় অবজেক্ট সরবরাহ করে Services। প্রতিটি মধ্যে ইনস্ট্যান্টিয়েটেড Service

আপনি কীভাবে একই পদ্ধতির প্রয়োগ করতে পারেন তার উদাহরণ নীচে দেওয়া হল।


জুলাই 2017 সম্পাদনা করুন

আমি একটি ভিডিও টিউটোরিয়াল প্রকাশ করেছি যা দেখায় কীভাবে অ্যান্ড্রয়েড অ্যাপ্লিকেশনে ডাগর নির্ভরতা ইনজেকশন কোডটি গঠন করতে হবে: পেশাদার টিউটোরিয়ালের জন্য অ্যান্ড্রয়েড ডাগর


ফেব্রুয়ারী 2018 সম্পাদনা করুন

আমি অ্যান্ড্রয়েডে নির্ভরতা ইনজেকশন সম্পর্কে একটি সম্পূর্ণ কোর্স প্রকাশ করেছি ।

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

আপনি যদি এই কোর্সটি গ্রহণ করেন তবে আপনি বুঝতে পারবেন কেন প্রতিটি ক্রিয়াকলাপ / খণ্ডের জন্য মডিউল / উপাদানগুলির পৃথক সংজ্ঞা থাকার ধারণাটি মূলত সবচেয়ে মৌলিক উপায়ে ত্রুটিযুক্ত।

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


আবেদনের সুযোগ:

@ApplicationScope
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {

    // Each subcomponent can depend on more than one module
    ControllerComponent newControllerComponent(ControllerModule module);
    ServiceComponent newServiceComponent(ServiceModule module);

}


@Module
public class ApplicationModule {

    private final Application mApplication;

    public ApplicationModule(Application application) {
        mApplication = application;
    }

    @Provides
    @ApplicationScope
    Application applicationContext() {
        return mApplication;
    }

    @Provides
    @ApplicationScope
    SharedPreferences sharedPreferences() {
        return mApplication.getSharedPreferences(Constants.PREFERENCES_FILE, Context.MODE_PRIVATE);
    }

    @Provides
    @ApplicationScope
    SettingsManager settingsManager(SharedPreferences sharedPreferences) {
        return new SettingsManager(sharedPreferences);
    }
}

নিয়ামক সুযোগ:

@ControllerScope
@Subcomponent(modules = {ControllerModule.class})
public interface ControllerComponent {

    void inject(CustomActivity customActivity); // add more activities if needed

    void inject(CustomFragment customFragment); // add more fragments if needed

    void inject(CustomDialogFragment customDialogFragment); // add more dialogs if needed

}



@Module
public class ControllerModule {

    private Activity mActivity;
    private FragmentManager mFragmentManager;

    public ControllerModule(Activity activity, FragmentManager fragmentManager) {
        mActivity = activity;
        mFragmentManager = fragmentManager;
    }

    @Provides
    @ControllerScope
    Context context() {
        return mActivity;
    }

    @Provides
    @ControllerScope
    Activity activity() {
        return mActivity;
    }

    @Provides
    @ControllerScope
    DialogsManager dialogsManager(FragmentManager fragmentManager) {
        return new DialogsManager(fragmentManager);
    }

    // @Provides for presenters can be declared here, or in a standalone PresentersModule (which is better)
}

এবং তারপরে Activity:

public class CustomActivity extends AppCompatActivity {

    @Inject DialogsManager mDialogsManager;

    private ControllerComponent mControllerComponent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getControllerComponent().inject(this);

    }

    private ControllerComponent getControllerComponent() {
        if (mControllerComponent == null) {

            mControllerComponent = ((MyApplication)getApplication()).getApplicationComponent()
                    .newControllerComponent(new ControllerModule(this, getSupportFragmentManager()));
        }

        return mControllerComponent;
    }
}

নির্ভরতা ইনজেকশন সম্পর্কিত অতিরিক্ত তথ্য:

ড্যাগার 2 স্কোপস ডেমাইসফাইড

অ্যান্ড্রয়েডে নির্ভরতা ইনজেকশন


4
আপনার মতামত ভাগ করে নেওয়ার জন্য @ বাসিলি ধন্যবাদ ঠিক এটিই আমি এটি ব্যবহার করব এবং বর্তমানে কৌশল অনুসরণ করব। কোনও এমভিপি প্যাটার্নের ক্ষেত্রে, উল্লেখিতরা ControllerModuleএকটি নতুন তৈরি করবে Presenterএবং তারপরে উপস্থাপকটি ইনজেকশনের মাধ্যমে Activityবা Fragment। এর পক্ষে বা এর বিপরীতে কোন দৃ opinion় মতামত?
ওয়াহিব উল হক

@ ভ্যাসিলি, আমি আপনার পুরো নিবন্ধটি পড়েছি এবং আমি দেখতে পেয়েছি যে আপনি সম্ভবত ব্যবস্থায় ইন্টারেক্টর এবং উপস্থাপকদের বিবেচনা করেন নি । কন্ট্রোলারমডুল কি ইন্টারেক্টর এবং উপস্থাপকদের সমস্ত নির্ভরতা সরবরাহ করে ? আমি যদি কিছু মিস করি তবে দয়া করে একটি ছোট ইঙ্গিত দিন।
iamcrypticcoder

@ মাহবুব.কুয়েট, যদি আমি বুঝতে পারি যে আপনি "ইন্টারেক্টর" এবং "উপস্থাপক" দ্বারা কী উল্লেখ করছেন, ControllerComponentসেগুলি ইনজেকশন করা উচিত। আপনি সেগুলি তারে রেখেছেন ControllerModule, বা অতিরিক্ত মডিউলটি পরিচয় করিয়ে দিন তা আপনার উপর নির্ভর করে । বাস্তব অ্যাপ্লিকেশনগুলিতে আমি সমস্ত উপাদানকে একক মডিউলে রাখার পরিবর্তে উপাদানগুলির প্রতি মাল্টি-মডিউল ব্যবহার করার পরামর্শ দিই। এখানে উদাহরণস্বরূপ ApplicationComponent, তবে কন্ট্রোলার একই হবে: github.com/techyourchance/idocare-android/tree/master/app/src/…
ভাসিলি

4
@ মিঃ হাইড, সাধারণভাবে হ্যাঁ, তবে তারপরে আপনাকে অবশ্যই ApplicationComponentসমস্ত ControllerComponentব্যবহার নির্ভরতাগুলিতে স্পষ্টভাবে ঘোষণা করতে হবে। এছাড়াও উত্পন্ন কোডের পদ্ধতি গণনাটি আরও বেশি হবে। নির্ভরশীল উপাদানগুলি ব্যবহার করার জন্য আমি এখনও কোনও ভাল কারণ খুঁজে পাইনি।
ভাসিলি

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

15

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

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

addedittask
taskdetail
tasks

প্রতিটি প্যাকেজের অভ্যন্তরে একটি মডিউল, উপাদান, উপস্থাপক ইত্যাদি থাকে উদাহরণস্বরূপ, ভিতরে taskdetailনীচের ক্লাসগুলি রয়েছে:

TaskDetailActivity.java
TaskDetailComponent.java
TaskDetailContract.java
TaskDetailFragment.java
TaskDetailPresenter.java
TaskDetailPresenterModule.java

এই পদ্ধতিতে সংগঠিত করার সুবিধা (একটি উপাদান বা মডিউলে সমস্ত ক্রিয়াকলাপকে গ্রুপিং করার পরিবর্তে) আপনি জাভা অ্যাক্সেসিবিলিটি মডিফায়ারগুলির সুবিধা নিতে পারেন এবং কার্যকর জাভা আইটেম 13 টি পূরণ করতে পারেন other অন্য কথায়, কার্যত শ্রেণিবদ্ধ শ্রেণি একই হবে প্যাকেজ এবং আপনি সুবিধা গ্রহণ করতে পারেন protectedএবং package-private অভিগম্যতা সংশোধনকারীদের আপনার ক্লাস অনিচ্ছাকৃত ব্যবহারগুলির প্রতিরোধ।


4
এটিও আমার পছন্দসই পদ্ধতি। আমি ক্রিয়াকলাপ / টুকরোগুলিগুলিতে অ্যাক্সেস থাকা জিনিসগুলি পছন্দ করি না যাদের তারা মনে করেনি।
জোওও সউসা

3

প্রথম বিকল্পটি প্রতিটি ক্রিয়াকলাপের জন্য একটি সাবস্কোপযুক্ত উপাদান তৈরি করে, যেখানে ক্রিয়াকলাপ সাবস্কোপড উপাদান তৈরি করতে সক্ষম হয় যা কেবলমাত্র সেই নির্দিষ্ট ক্রিয়াকলাপের জন্য নির্ভরতা (উপস্থাপক) সরবরাহ করে।

দ্বিতীয় বিকল্পটি একটি একক @Singletonউপাদান তৈরি করে যা উপস্থাপকদেরকে অনির্ধারিত নির্ভরতা হিসাবে সরবরাহ করতে সক্ষম হয়, যার অর্থ আপনি যখন সেগুলি অ্যাক্সেস করবেন তখন আপনি প্রতিবার উপস্থাপকের একটি নতুন উদাহরণ তৈরি করবেন। (না, আপনি অনুরোধ না করা পর্যন্ত এটি কোনও নতুন উদাহরণ তৈরি করে না)।


প্রযুক্তিগতভাবে, উভয়ই অ্যাপ্রোচ অন্যটির চেয়ে খারাপ নয়। প্রথম পদ্ধতির বৈশিষ্ট্য অনুসারে উপস্থাপককে আলাদা করে না, তবে স্তর দ্বারা।

আমি উভয় ব্যবহার করেছি, তারা উভয়ই কাজ করে এবং উভয়ই উপলব্ধি করে।

প্রথম সমাধানের একমাত্র অসুবিধা (যদি আপনি এর @Component(dependencies={...}পরিবর্তে ব্যবহার করছেন @Subcomponent) তা হ'ল আপনাকে নিশ্চিত করতে হবে যে এটি ক্রিয়াকলাপ নয় যা অভ্যন্তরীণভাবে তার নিজস্ব মডিউল তৈরি করে, কারণ আপনি মকডের সাহায্যে মডিউল পদ্ধতি প্রয়োগগুলি প্রতিস্থাপন করতে পারবেন না। তারপরে আবার, আপনি যদি ক্ষেত্রের ইনজেকশনের পরিবর্তে কনস্ট্রাক্টর ইঞ্জেকশন ব্যবহার করেন, আপনি কেবল নির্মাতাকে দিয়ে সরাসরি ক্লাস তৈরি করতে পারেন, সরাসরি এটি বিদ্রূপ করে।


1

Provider<"your component's name">মেমরি ফাঁস এবং অজস্র উপাদানগুলি তৈরি করতে এড়াতে সাধারণ উপাদানগুলির প্রয়োগের পরিবর্তে ব্যবহার করুন । সুতরাং আপনি যখন () পদ্ধতিটি কল করবেন তখন আপনার উপাদানগুলি অলস দ্বারা তৈরি করা হবে কারণ আপনি উপাদানটির কোনও উদাহরণ সরবরাহ করেন না তবে পরিবর্তে কেবল সরবরাহকারী হন। এইভাবে আপনার উপস্থাপক প্রয়োগ করা হবে যদি সরবরাহকারীর .get () কল করা হয়। সরবরাহকারী সম্পর্কে এখানে পড়ুন এবং এটি প্রয়োগ করুন। ( অফিসিয়াল ডগার ডকুমেন্টেশন )


এবং অন্যান্য দুর্দান্ত উপায় হ'ল মাল্টিবাইন্ডিং ব্যবহার করা। এটি অনুসারে আপনার উপস্থাপকদের মানচিত্রে বাঁধাই করা উচিত এবং যখন আপনার প্রয়োজন হবে সরবরাহকারীদের মাধ্যমে তাদের তৈরি করা উচিত। ( এখানে মাল্টিবাইন্ডিং সম্পর্কে ডক্স রয়েছে )


-5

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

সাধারণত আমরা এই মত করব

public class MainActivity extends AppCompatActivity {


Presenter1 mPresenter1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mPresenter1 = new Presenter1(); // you instantiate mPresentation1 in onCreate, imagine if there are 5, 10, 20... of objects for you to instantiate.
}

}

আপনি পরিবর্তে এটি করুন

public class MainActivity extends AppCompatActivity {

@Inject
Presenter1 mPresenter1; // the Dagger module take cares of instantiation for your

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    injectThisActivity();
}

private void injectThisActivity() {
    MainApplication.get(this)
            .getMainComponent()
            .inject(this);
}}

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

সম্পর্কে আপনার প্রশ্নের হিসাবে:

1- মেমরি ফুটো:

না, আপনি যে @Singletonসরবরাহকারীর সরবরাহ করছেন তাতে কোনও টীকাকরণ না রাখলে নয়। যখনই আপনি @Injectলক্ষ্য শ্রেণিতে কোনও কাজ করেন ড্যাজারটি কেবলমাত্র সেই অবজেক্ট তৈরি করবে ` এটি আপনার দৃশ্যে অন্যান্য উপস্থাপক তৈরি করবে না। লগগুলি তৈরি হয়েছে কিনা তা আপনি দেখতে ব্যবহার করার চেষ্টা করতে পারেন।

@Module
public class AppPresenterModule {

@Provides
@Singleton // <-- this will persists throughout the application, too many of these is not good
Activity1Presenter provideActivity1Presentor(Context context, ...some other params){
    Log.d("Activity1Presenter", "Activity1Presenter initiated");
    return new Activity1PresenterImpl(context, ...some other params);
}

@Provides // Activity2Presenter will be provided every time you @Inject into the activity
Activity2Presenter provideActivity2Presentor(Context context, ...some other params){
    Log.d("Activity2Presenter", "Activity2Presenter initiated");
    return new Activity2PresenterImpl(context, ...some other params);
}

.... Same with 48 others presenters.

}

2- আপনি দুবার ইনজেক্ট করুন এবং তাদের হ্যাশ কোডটি লগ করুন

//MainActivity.java
@Inject Activity1Presenter mPresentation1
@Inject Activity1Presenter mPresentation2

@Inject Activity2Presenter mPresentation3
@Inject Activity2Presenter mPresentation4
//log will show Presentation2 being initiated twice

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    injectThisActivity();
    Log.d("Activity1Presenter1", mPresentation1.hashCode());
    Log.d("Activity1Presenter2", mPresentation2.hashCode());
    //it will shows that both have same hash, it's a Singleton
    Log.d("Activity2Presenter1", mPresentation3.hashCode());
    Log.d("Activity2Presenter2", mPresentation4.hashCode());
    //it will shows that both have different hash, hence different objects

৩. না, আপনি যখন @Injectঅ্যাপ্লিকেশন টির পরিবর্তে ক্রিয়াকলাপে প্রবেশ করবেন তখন কেবলমাত্র বস্তুগুলি তৈরি করা হবে ।


4
মন্তব্যের জন্য ধন্যবাদ, আপনি যা বলেছেন তা ভুল নয়, তবে আমি মনে করি এটি সেরা উত্তর নয়, দয়া করে আমার সম্পাদনা পোস্টটি দেখুন। সুতরাং, এটি স্বীকৃত হিসাবে চিহ্নিত করতে পারেনি।
মিঃ মাইক

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