আস্তে আস্তে কোডবেস নির্ভরতা ইনজেকশন ধারকটিতে সরান


9

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

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

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

আমি দেখি একমাত্র উপায় হ'ল Injectorআপাতত একক সিলেটের মাধ্যমে বিশ্বব্যাপী একটি / অ্যাপ্লিকেশন প্রসঙ্গ তৈরি করা, যাতে অন্যান্য শ্রেণিগুলি এ থেকে একটি পরিচালিত মটরশুটি পেতে পারে। তবে এটি composition rootঅ্যাপ্লিকেশনটিতে প্রকাশ না করার গুরুত্বপূর্ণ ধারণার বিরোধিতা করে।

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

এই ধীরে ধীরে মাইগ্রেশন অর্জনের উপায় কী হবে?

পিএস প্রশ্নটি নির্ভরতা ইনজেকশনের দিকে ধীরে ধীরে যোগাযোগ করা শিরোনামে একই, তবে এটি আমার প্রশ্নের উত্তর দেয় না।


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

যথেষ্ট ফর্সা। সুতরাং আমার কাছে কিছু ইউটিলিটি ক্লাস রয়েছে যা 30 টি অন্যান্য ক্লাসে ব্যবহৃত হয় (এর মধ্যে একটি ক্লাস বি), তাদের অকেটে অযোগ্য করে তোলে। আমি ক্লাস এটিকে ক্লাস বিয়ের একটি কনস্ট্রাক্টর নির্ভরতা বানাতে ভেবেছিলাম আমাকে সমস্ত কল কনস্ট্রাক্টরের কাছে পরিবর্তন করতে হবে এবং এটিকে পাস করতে হবে। তবে আমি এটি কোথা থেকে পাব?
দামালুয়ার

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

@ দামলুয়ার দিয়ে কারখানা শুরু হবে?
তুলিনস কর্ডোভা

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

উত্তর:


2

দুঃখিত C#, আমার পছন্দের ভাষা, আমি পড়তে পারি Javaতবে সম্ভবত এটি লেখার চেষ্টা করে সিনট্যাক্সটি কসাই করবো ... একই ধারণাগুলি এর মধ্যে C#এবং Javaযদিও প্রয়োগ হয় , সুতরাং আশা করি আপনি কীভাবে ধীরে ধীরে আপনার কোড বেসটিকে আরও বেশি করে নিয়ে যেতে পারছেন সেই পদক্ষেপগুলি এটি দেখায় testable।

প্রদত্ত:

public class MyUI
{
    public void SomeMethod()
    {
        Foo foo = new Foo();
        foo.DoStuff();
    }
}

public class Foo
{

    public void DoStuff()
    {
        Bar bar = new Bar();
        bar.DoSomethingElse();
    }

}

public class Bar
{
    public void DoSomethingElse();
}

আইওসি পাত্রে ব্যবহার না করেই ডিআই ব্যবহার করতে সহজেই রিফ্যাক্টর করা যেতে পারে - এবং আপনি সম্ভবত এটি বেশ কয়েকটি পদক্ষেপে ভেঙে ফেলতে পারেন:

(সম্ভাব্য) প্রথম পদক্ষেপ - নির্ভরতা গ্রহণ করুন কিন্তু কলিং (ইউআই) কোডে কোনও পরিবর্তন হয়নি:

public class MyUI
{
    public void SomeMethod()
    {
        Foo foo = new Foo();
        foo.DoStuff();
    }
}

public class Foo
{

    private IBar _iBar;

    // Leaving this constructor for step one, 
    // so that calling code can stay as is without impact
    public Foo()
    {
        _iBar = new Bar();
    }

    // simply because we now have a constructor that take's in the implementation of the IBar dependency, 
    // Foo can be much more easily tested.
    public Foo(IBar iBar)
    {
        _iBar = iBar;
    }

    public void DoStuff()
    {
        _iBar.DoSomethingElse();
    }

}

public interface IBar
{
    void DoSomethingElse();
}

public class Bar
{
    public void DoSomethingElse();
}

রিফ্যাক্টর 2 (বা আইওসি পাত্রে প্রয়োগ করার সাথে সাথে কলিং কোড অবিলম্বে পরিবর্তন করা হলে প্রথম চুল্লি):

public class MyUI
{
    public void SomeMethod()
    {
        Foo foo = null // use your IOC container to resolve the dependency
        foo.DoStuff();
    }
}

public class Foo
{

    private IBar _iBar;

    // note we have now dropped the "default constructor" - this is now a breaking change as far as the UI is concerned.
    // You can either do this all at once (do only step 2) or in a gradual manner (step 1, then step 2)

    // Only entry into class - requires passing in of class dependencies (IBar)
    public Foo(IBar iBar)
    {
        _iBar = iBar;
    }

    public void DoStuff()
    {
        _iBar.DoSomethingElse();
    }

}

দ্বিতীয় ধাপটি প্রযুক্তিগতভাবে নিজেই সম্পন্ন হতে পারে - তবে (সম্ভাব্য) আরও অনেক বেশি কাজ হতে পারে - আপনি ডিআই-তে যে কার্যকারিতাটি "নতুনভাবে আপ করছেন" তার উপর নির্ভরশীল।

পদক্ষেপ 1 -> পদক্ষেপ 2 রুটের সাথে যাওয়ার কথা বিবেচনা করুন - আপনি এর জন্য Fooস্বতন্ত্র ইউনিট পরীক্ষা করতে সক্ষম হবেন Bar। যেখানে পদক্ষেপ 1 এর রিফ্যাক্টরের আগে এটি উভয় শ্রেণির প্রকৃত বাস্তবায়ন ব্যবহার না করে সহজেই সম্পন্ন করা যায়নি। পদক্ষেপ 1 -> পদক্ষেপ 2 (তাত্ক্ষণিকভাবে পদক্ষেপ 2 তত্ক্ষণাত্) করার সাথে সাথে সময়ের সাথে সাথে আরও ছোট পরিবর্তন হতে পারে এবং ফলস্বরূপ আপনার রিফ্যাক্টরটি আরও ভালভাবে কাজ করতে পারে তা নিশ্চিত করার জন্য আপনার কাছে ইতিমধ্যে আপনার পরীক্ষার জোতা শুরু হবে।


0

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

https://www.youtube.com/watch?v=Jccq_Ti8Lck (পিএইচপি, দুঃখিত!)

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

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