ব্যক্তিগত ডেটা অ্যাক্সেস করার জন্য কোনও ব্যক্তিগত পদ্ধতি কখন সর্বজনীন রুট নিতে হবে?


11

ব্যক্তিগত ডেটা অ্যাক্সেস করার জন্য কোনও ব্যক্তিগত পদ্ধতি কখন সর্বজনীন রুট নিতে হবে? উদাহরণস্বরূপ, আমার যদি এই অপরিবর্তনীয় 'গুণক' শ্রেণি থাকে (কিছুটা স্বীকৃত, আমি জানি):

class Multiplier {
public:
    Multiplier(int a, int b) : a(a), b(b) { }
    int getA() const { return a; }
    int getB() const { return b; }
    int getProduct() const { /* ??? */ }
private:
    int a, b;
};

আমি দুটি উপায় প্রয়োগ করতে পারি getProduct:

    int getProduct() const { return a * b; }

অথবা

    int getProduct() const { return getA() * getB(); }

কারণ উদ্দেশ্য এখান থেকে মান ব্যবহার করা aঅর্থাৎ পেতে a ব্যবহার getA()বাস্তবায়ন getProduct()আমাকে ক্লিনার বলে মনে হয়। আমি aএটিকে পরিবর্তন না করে ব্যবহার করা এড়াতে পছন্দ করব। আমার উদ্বেগটি হ'ল আমি প্রায়শই কোডটি এইভাবে লেখা দেখি না, আমার অভিজ্ঞতার a * bচেয়ে আরও সাধারণ বাস্তবায়ন হবে getA() * getB()

যখন ব্যক্তিগত কিছু সরাসরি সরাসরি অ্যাক্সেস করতে পারে তখন কি সর্বজনীন উপায় ব্যবহার করা উচিত?

উত্তর:


7

এটা তোলে প্রকৃত অর্থ নির্ভর করে a, bএবং getProduct

প্রাপ্তদের উদ্দেশ্য হ'ল বস্তুর ইন্টারফেস একই রাখার সময় আসল বাস্তবায়ন পরিবর্তন করতে সক্ষম হওয়া। উদাহরণস্বরূপ, যদি একদিন getAহয়ে যায় return a + 1;, পরিবর্তনটি স্থানীয় হিসাবে স্থানান্তরিত হয়।

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

যদি এটি getProductব্যবহার করার aএবং bসরাসরি ব্যবহারের জন্য সঠিক ধারণা দেয় তবে সেগুলি ব্যবহার করুন। অন্যথায়, রক্ষণাবেক্ষণ সংক্রান্ত সমস্যাগুলি পরে প্রতিরোধ করতে গেটারগুলি ব্যবহার করুন।

উদাহরণস্বরূপ যেখানে কেউ গেটার ব্যবহার করবে:

class Product {
public:
    Product(ProductId id) : {
        price = Money.fromCents(
            data.findProductById(id).price,
            environment.currentCurrency
        )
    }

    Money getPrice() {
        return price;
    }

    Money getPriceWithRebate() {
        return getPrice().applyRebate(rebate); // ← Using a getter instead of a field.
    }
private:
    Money price;
}

এই মুহুর্তের জন্য, গিটারটিতে কোনও ব্যবসায়িক যুক্তি নেই, তবে এটি বাদ দেওয়া হয় না যে অবজেক্টটি আরম্ভ করার সময় ডাটাবেসের কাজটি এড়াতে কনস্ট্রাক্টরের যুক্তিটি গেটরে স্থানান্তরিত হবে:

class Product {
public:
    Product(ProductId id) : id(id) { }

    Money getPrice() {
        return Money.fromCents(
            data.findProductById(id).price,
            environment.currentCurrency
        )
    }

    Money getPriceWithRebate() {
        return getPrice().applyRebate(rebate);
    }
private:
    const ProductId id;
}

পরে, ক্যাচিং যুক্ত করা যেতে পারে (সি # তে, Lazy<T>কোডটি সংক্ষিপ্ত এবং সহজ করে একটি ব্যবহার করবে ; C ++ এর সমতুল্য কিনা তা আমি জানি না):

class Product {
public:
    Product(ProductId id) : id(id) { }

    Money getPrice() {
        if (priceCache == NULL) {
            priceCache = Money.fromCents(
                data.findProductById(id).price,
                environment.currentCurrency
            )

        return priceCache;
    }

    Money getPriceWithRebate() {
        return getPrice().applyRebate(rebate);
    }
private:
    const ProductId id;
    Money priceCache;
}

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

উদাহরণস্বরূপ যেখানে কেউ সম্ভবত ব্যক্তিগত ক্ষেত্র ব্যবহার করবে:

class Product {
public:
    Product(ProductId id) : id(id) { }
    ProductId getId() const { return id; }
    Money getPrice() {
        return Money.fromCents(
            data.findProductById(id).price, // ← Accessing `id` directly.
            environment.currentCurrency
        )
    }
private:
    const ProductId id;
}

প্রাপ্তিটি সোজা: এটি একটি ধ্রুবক (সি # 'এর সমতুল্য readonly) ক্ষেত্রের প্রত্যক্ষ উপস্থাপনা যা ভবিষ্যতে পরিবর্তিত হবে বলে আশা করা যায় না: সম্ভাবনা রয়েছে, আইডি গেটার কখনই গণিত মান হয়ে উঠবে না। সুতরাং এটি সহজ রাখুন এবং সরাসরি ক্ষেত্রটি অ্যাক্সেস করুন।

আরেকটি সুবিধা হ'ল getIdভবিষ্যতে সম্ভাব্যতা সরিয়ে ফেলা হতে পারে যদি মনে হয় এটি বাইরে ব্যবহার করা হয়নি (কোডের আগের অংশের মতো)।


আমি আপনাকে একটি +1 দিতে পারছি না কারণ ব্যক্তিগত ক্ষেত্রগুলি ব্যবহার করার জন্য আপনার উদাহরণটি কোনও আইএমএইচও নয়, মূলত আপনি যে ঘোষণা করেছেন const: আমি ধরে নিয়েছি এর অর্থ কম্পাইলার getIdযেভাবেই কোনও কল ইনলাইন করবে এবং এটি আপনাকে উভয় দিক পরিবর্তন করতে দেয়। (অন্যথায় আমি গেটারগুলি ব্যবহার করার জন্য আপনার কারণগুলির সাথে পুরোপুরি একমত আছি )) এবং যে ভাষাগুলিতে সম্পত্তি সিনট্যাক্স সরবরাহ করে, সেখানে সরাসরি ব্যাকিং ফিল্ডের চেয়ে সম্পত্তিটি ব্যবহার না করার আরও কম কারণ রয়েছে।
মার্ক হুরড

1

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

প্রকৃতপক্ষে যদি প্রকৃত যুক্তি প্রয়োগ করে তবে এটি অবশ্যই আলাদা that এক্ষেত্রে এটি নির্ভর করে আপনি তাদের যুক্তি ব্যবহার করতে হবে কিনা তা নির্ভর করে।


1

আমি বলব যে জনসাধারণের পদ্ধতিগুলি ব্যবহার করা আরও পছন্দনীয়, যদি অন্য কোনও কারণে না হয় তবে ডিআরওয়াই অনুসারে হয়

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


0

একটি শ্রেণীর জন্য এই ছোট, সরলতা জয়ী। আমি কেবল একটি * বি ব্যবহার করব।

আরও জটিল কোনও কিছুর জন্য, আমি getA () * getB () ব্যবহারের বিষয়ে দৃ strongly়তার সাথে বিবেচনা করব যদি আমি স্পষ্টতই "সর্বনিম্ন" ইন্টারফেসটিকে অন্য সমস্ত ফাংশন থেকে সম্পূর্ণ পাবলিক এপিআই-তে আলাদা করতে চাই। সি ++ তে স্ট্রিং :: স্ট্রিংয়ের একটি দুর্দান্ত উদাহরণ হবে। এটির 103 সদস্যের কাজ রয়েছে, তবে এর মধ্যে কেবল 32 টিরই ব্যক্তিগত সদস্যদের অ্যাক্সেস দরকারআপনার যদি জটিল একটি শ্রেণি থাকে তবে সমস্ত "নন-কোর" ফাংশনকে ধারাবাহিকভাবে "কোর এপিআই" দিয়ে যেতে বাধ্যকরণ প্রয়োগকরণকে পরীক্ষা, ডিবাগ এবং রিফ্যাক্টরকে অনেক সহজ করে তুলতে পারে।


1
আপনার যদি জটিল একটি ক্লাস থাকে তবে আপনাকে এটি ঠিক করতে বাধ্য করা উচিত, এটি ব্যান্ড-সহায়তা নয়।
ডেডএমজি

একমত। আমার সম্ভবত 20-30 ফাংশন সহ একটি উদাহরণ বেছে নেওয়া উচিত ছিল।
Ixrec

1
"103 ফাংশন" হ'ল একটি রেড হেরিং। অতিরিক্ত লোড পদ্ধতিগুলি একবারে গণনা করা উচিত, যদি ইন্টারফেসের জটিলতা হয়।
অব্নার শাহর-কাশতান

আমি সম্পূর্ণ একমত। বিভিন্ন ওভারলোডের বিভিন্ন শব্দার্থবিজ্ঞান এবং বিভিন্ন ইন্টারফেস থাকতে পারে।
ডেডএমজি

এমনকি এই "ছোট" উদাহরণের জন্য, getA() * getB()মাঝারি এবং দীর্ঘমেয়াদে আরও ভাল।
মার্ক হুরড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.