আমার কনস্ট্রাক্টরের পরিবর্তে কারখানার পদ্ধতি ব্যবহার করা উচিত ছিল। আমি কি এটি পরিবর্তন করতে এবং এখনও পিছনে সামঞ্জস্যপূর্ণ হতে পারি?


15

সমস্যাটি

ধরা যাক, আমার কাছে একটি ক্লাস রয়েছে DataSourceযা একটি ReadDataপদ্ধতি থেকে ডেটা পড়ার জন্য একটি পদ্ধতি (এবং অন্যরাও হতে পারে তবে কিছু সরল রাখুন) .mdb:

var source = new DataSource("myFile.mdb");
var data = source.ReadData();

কয়েক বছর পরে, আমি সিদ্ধান্ত নিয়েছি যে ডেটা উত্স হিসাবে ফাইলগুলি .xmlছাড়াও আমি ফাইলগুলিকে সমর্থন করতে সক্ষম হতে চাই .mdb। "রিডিং ডেটা" প্রয়োগের জন্য .xmlএবং .mdbফাইলগুলি একেবারেই আলাদা is এইভাবে, যদি আমি সিস্টেমটি স্ক্র্যাচ থেকে ডিজাইন করি তবে আমি এটির মতো এটি সংজ্ঞায়িত করব:

abstract class DataSource {
    abstract Data ReadData();
    static DataSource OpenDataSource(string fileName) {
        // return MdbDataSource or XmlDataSource, as appropriate
    }
}

class MdbDataSource : DataSource {
    override Data ReadData() { /* implementation 1 */ }
}

class XmlDataSource : DataSource {
    override Data ReadData() { /* implementation 2 */ }
}

দুর্দান্ত, কারখানার পদ্ধতি নিদর্শনটির একটি নিখুঁত বাস্তবায়ন। দুর্ভাগ্যক্রমে, DataSourceএকটি লাইব্রেরিতে অবস্থিত এবং কোডটির রিফ্যাক্টরিং এর ফলে বিদ্যমান সমস্ত কল ভেঙে যায়

var source = new DataSource("myFile.mdb");

বিভিন্ন ক্লায়েন্ট গ্রন্থাগার ব্যবহার করে। আফসোস আমার, কেন আমি প্রথমে কারখানার পদ্ধতি ব্যবহার করিনি?


সলিউশন

এই সমাধানগুলি আমি নিয়ে আসতে পারি:

  1. ডেটাসোর্স কনস্ট্রাক্টরকে একটি উপ-টাইপ ( MdbDataSourceবা XmlDataSource) ফেরত করুন । এটি আমার সমস্ত সমস্যার সমাধান করবে। দুর্ভাগ্যক্রমে, সি # এটি সমর্থন করে না।

  2. বিভিন্ন নাম ব্যবহার করুন:

    abstract class DataSourceBase { ... }    // corresponds to DataSource in the example above
    
    class DataSource : DataSourceBase {      // corresponds to MdbDataSource in the example above
        [Obsolete("New code should use DataSourceBase.OpenDataSource instead")]
        DataSource(string fileName) { ... }
        ...
    }
    
    class XmlDataSource : DataSourceBase { ... }

    এটা কি আমি ব্যবহার যেহেতু এটি (অর্থাৎ কলের কোড পিছন সামঞ্জস্যপূর্ণ রাখে শেষ পর্যন্ত এর new DataSource("myFile.mdb")এখনও কাজে)। খসড়া: নামগুলি যেমন হওয়া উচিত তেমনি বর্ণনামূলক নয়।

  3. DataSourceআসল বাস্তবায়নের জন্য একটি "মোড়ক" তৈরি করুন :

    class DataSource {
        private DataSourceImpl impl;
    
        DataSource(string fileName) {
            impl = ... ? new MdbDataSourceImpl(fileName) : new XmlDataSourceImpl(fileName);
        }
    
        Data ReadData() {
            return impl.ReadData();
        }
    
        abstract private class DataSourceImpl { ... }
        private class MdbDataSourceImpl : DataSourceImpl { ... }
        private class XmlDataSourceImpl : DataSourceImpl { ... }
    }

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

আমি যে কোনও মার্জিত সমাধান মিস করেছি তা কি?


5
আপনি কি আরও # বিস্তারিতভাবে আপনার সমস্যাটি # 3 দিয়ে ব্যাখ্যা করতে পারবেন? এটা আমার কাছে মার্জিত বলে মনে হচ্ছে। (বা পিছনের সামঞ্জস্য বজায় রাখার মতো আপনি যতটা মার্জিত হন))
পিডিআর

আমি এপিআই প্রকাশের একটি ইন্টারফেস সংজ্ঞায়িত করব এবং তারপরে কারখানাটি ইন্টারফেস প্রয়োগকারী শ্রেণীর সাথে সম্পর্কিত দৃষ্টান্ত তৈরি করে ফ্যাক্টরিটি তৈরি করে আপনার পুরানো কোড এবং নতুনগুলির চারপাশে মোড়ক তৈরি করে বিদ্যমান পদ্ধতিটি পুনরায় ব্যবহার করব।
থমাস

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

2
@ হেইনজি: আমি বিকল্পটি ৩ পছন্দ করি standard এটি স্ট্যান্ডার্ড "মুখের" ধরণ pattern আপনার বাস্তবায়নের জন্য প্রতিটি ডেটা উত্স পদ্ধতি প্রয়োগ করার দরকার আছে কিনা তা পরীক্ষা করা উচিত , বা কেবল কিছু just সম্ভবত এখনও কিছু জেনেরিক কোড রয়েছে যা "ডাটাসোর্স" এ থাকে?
ডক ব্রাউন 15

এটি লজ্জার বিষয় যা newশ্রেণি অবজেক্টের কোনও পদ্ধতি নয় (যাতে আপনি ক্লাস নিজেই সাবক্লাস করতে পারেন - একটি প্রযুক্তি যা মেটাক্লাস নামে পরিচিত - এবং newআসলে কী কী নিয়ন্ত্রণ করে) তবে এটি কীভাবে সি # (বা জাভা, বা সি ++) কাজ করে না।
ডোনাল ফেলো

উত্তর:


12

আমি আপনার দ্বিতীয় বিকল্পটির পরিবর্তনের জন্য যাব যা আপনাকে পুরানো, খুব জেনেরিক, নামটি পর্যায়ক্রমে অনুমতি দেয় DataSource:

abstract class AbstractDataSource { ... } // corresponds to the abstract DataSource in the ideal solution

class XmlDataSource : AbstractDataSource { ... }
class MdbDataSource : AbstractDataSource { ... } // contains all the code of the existing DataSource class

[Obsolete("New code should use AbstractDataSource instead")]
class DataSource : MdbDataSource { // an 'empty shell' to keep old code working.
    DataSource(string fileName) { ... }
}

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


1
+1, আমি যখন প্রশ্নটি পড়ি তখন ঠিক আমার মনে কী আসছিল coming যদিও আমি অপের বিকল্প 3 পছন্দ করি।
ডক ব্রাউন

নতুন ক্লাসটিকে একটি নতুন নেমস্পেসে রাখলে বেস শ্রেণীর সর্বাধিক সুস্পষ্ট নাম থাকতে পারে। তবে আমি নিশ্চিত নই যে এটি একটি ভাল ধারণা।
এসভিচ

বেস শ্রেণীর "বেস" প্রত্যয় থাকা উচিত। ক্লাস ডেটাসোর্সবেস
স্টিফেন

6

সেরা সমাধানটি আপনার বিকল্প # 3 এর কাছাকাছি কিছু হবে। DataSourceবেশিরভাগটি এখন যেমন রয়েছে তেমন রাখুন , এবং কেবল পাঠক অংশটিকে তার নিজস্ব ক্লাসে বের করুন।

class DataSource {
    private Reader reader;

    DataSource(string fileName) {
        reader = ... ? new MdbReader(fileName) : new XmlReader(fileName);
    }

    Data ReadData() {
        return reader.next();
    }

    abstract private class Reader { ... }
    private class MdbReader : Reader { ... }
    private class XmlReader : Reader { ... }
}

এইভাবে, আপনি সদৃশ কোড এড়িয়ে চলুন এবং আরও বর্ধনের জন্য উন্মুক্ত।


+1, দুর্দান্ত বিকল্প। আমি এখনও বিকল্প 2 পছন্দ করি, যদিও এটি আমাকে এক্সএমএলডাটা সোর্স-নির্দিষ্ট কার্যকারিতাটি স্পষ্টভাবে তাত্ক্ষণিকভাবে অ্যাক্সেস করার অনুমতি দেয় XmlDataSource
হেইনজি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.