পতাকা চেক করার প্রয়োজনীয়তা অপসারণ করার জন্য কি কোনও নকশার প্যাটার্ন রয়েছে?


28

আমি ডাটাবেসে কিছু স্ট্রিং পেইলড সঞ্চয় করতে চলেছি। আমার দুটি বৈশ্বিক কনফিগারেশন রয়েছে:

  • এনক্রিপশন
  • সঙ্কোচন

এগুলি কনফিগারেশন ব্যবহার করে এমনভাবে সক্ষম বা অক্ষম করা যায় যেগুলির মধ্যে কেবলমাত্র একটি সক্ষম, উভয়ই সক্ষম বা উভয়ই অক্ষম are

আমার বর্তমান বাস্তবায়ন হ'ল:

if (encryptionEnable && !compressEnable) {
    encrypt(data);
} else if (!encryptionEnable && compressEnable) {
    compress(data);
} else if (encryptionEnable && compressEnable) {
    encrypt(compress(data));
} else {
  data;
}

আমি ডেকরেটর প্যাটার্ন সম্পর্কে ভাবছি। এটি কি সঠিক পছন্দ, বা সম্ভবত আরও ভাল বিকল্প আছে?


5
আপনার বর্তমানে যা আছে তাতে দোষ কি? এই কার্যকারিতা জন্য প্রয়োজনীয়তা পরিবর্তন হতে পারে? আইই, নতুন ifবিবৃতি দেওয়ার সম্ভাবনা আছে ?
ড্যারেন ইয়ং

না, আমি কোডটি উন্নত করার জন্য অন্য কোনও সমাধান খুঁজছি।
দামিথ গানেগোদা

46
আপনি এই পিছনের দিকে যাচ্ছে। প্যাটার্নটি ফিট করার জন্য আপনি কোনও প্যাটার্ন খুঁজে পান না code আপনার প্রয়োজনীয়তার সাথে মানিয়ে নিতে আপনি কোডটি লিখেন, তারপরে code চ্ছিকভাবে আপনার কোডটি বর্ণনার জন্য একটি প্যাটার্ন ব্যবহার করুন।
মনিকার সাথে লাইটনেস রেস

1
নোট আপনি যদি মনে করেন যে আপনার প্রশ্নের প্রকৃতপক্ষে অনুরূপ এই এক , তারপরে একটি প্রশ্নকর্তা যেমন আপনি "ওভাররাইড" একটি অপশন আছে সাম্প্রতিক পুনরায় খোলা এবং singlehandedly ঘনিষ্ঠ এটা যেমন হিসাবে। আমি আমার নিজের কিছু প্রশ্নে এটি করেছি এবং এটি একটি কবজির মতো কাজ করে। এখানে আমি এটি কীভাবে করেছি, 3 টি সহজ পদক্ষেপ - আমার "নির্দেশাবলীর" সাথে একমাত্র পার্থক্য হ'ল যেহেতু আপনার কাছে 3K এরও কম রেপ রয়েছে, তাই "নকল" বিকল্পটি পেতে আপনাকে পতাকা সংলাপ দিয়ে যেতে হবে
জান্নাত

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

উত্তর:


15

কোড ডিজাইন করার সময় আপনার কাছে দুটি উপায় থাকে।

  1. কেবল এটি সম্পন্ন করুন, এক্ষেত্রে কোনও সমাধান আপনার পক্ষে কার্যকর হবে
  2. পেডেন্টিক হোন এবং এমন একটি সমাধান ডিজাইন করুন যা ভাষার ভাবগুণকে তার মতাদর্শকে কাজে লাগায় (এই ক্ষেত্রে ওও ভাষাগুলি - সিদ্ধান্ত প্রদানের জন্য বহুরূপীকরণের ব্যবহার)

আমি দুজনের প্রথমটির দিকে মনোনিবেশ করতে যাচ্ছি না, কারণ সত্যই বলার কিছু নেই। আপনি যদি এটি কেবল এটির কাজ পেতে চান, আপনি কোডটি যেমন রেখে দিতে পারেন।

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

আপনি নিম্নলিখিত প্রক্রিয়াটি খুঁজছেন হতে পারে:

ওও কোড ডিজাইন করার সময়, কোডগুলিতে থাকা বেশিরভাগ এসগুলিতে ifসেখানে থাকতে হবে না। স্বাভাবিকভাবেই, আপনি যদি দুটি স্কেলারের প্রকারের তুলনা করতে চান, যেমন intএস বা floatএস, আপনার একটি হওয়ার সম্ভাবনা রয়েছে ifতবে আপনি যদি কনফিগারেশনের উপর ভিত্তি করে পদ্ধতিগুলি পরিবর্তন করতে চান তবে আপনি যা চান তা অর্জন করতে পলিমারফিজম ব্যবহার করতে পারেন, সিদ্ধান্তগুলি সরিয়ে নিন ( ifগুলি) আপনার ব্যবসায়ের যুক্তি থেকে এমন কোনও জায়গায়, যেখানে বস্তুগুলি তাত্ক্ষণিকভাবে তৈরি হয় - কারখানায়

এখন পর্যন্ত, আপনার প্রক্রিয়াটি 4 টি পৃথক পাথের মধ্য দিয়ে যেতে পারে:

  1. dataএনক্রিপ্ট করা বা সংকুচিত হয় না (কিছুই কল করুন না, ফিরে আসুন data)
  2. dataসংকুচিত (কল compress(data)এবং এটি ফিরে)
  3. dataএনক্রিপ্ট করা হয়েছে (কল করে encrypt(data)এটি ফিরিয়ে দিন)
  4. dataসংকুচিত এবং এনক্রিপ্ট করা হয়েছে (কল করুন encrypt(compress(data))এবং এটি রিটার্ন করুন)

কেবল 4 টি পথ দেখে আপনি একটি সমস্যা দেখতে পান।

আপনার কাছে একটি প্রক্রিয়া রয়েছে যা কল করে 3 (তাত্ত্বিকভাবে 4, যদি আপনি কোনওটিকে এক হিসাবে কল না করে গণনা করেন) বিভিন্ন পদ্ধতি যা ডেটা ম্যানিপুলেট করে এবং তারপরে এটি ফিরিয়ে দেয়। পদ্ধতিগুলির বিভিন্ন নাম রয়েছে , বিভিন্ন তথাকথিত পাবলিক এপিআই (পদ্ধতিগুলি তাদের আচরণের সাথে যোগাযোগ করার উপায়)।

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

এটি কোন কংক্রিটের ভাষা নয়। এটি একটি জেনেরিক পন্থা, যে কোনও কীওয়ার্ডের প্রতিনিধিত্ব করার জন্য এটি যে কোনও ধরণের হতে পারে, সি # এর মতো ভাষায় আপনি এটিকে জেনেরিক ( <T>) দিয়ে প্রতিস্থাপন করতে পারেন ।

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

class Compression
{
    Compress(data : any) : any { ... }
}

class Encryption
{
    Encrypt(data : any) : any { ... }
}

একটি এন্টারপ্রাইজ বিশ্বে, এমনকি এই নির্দিষ্ট ক্লাসগুলি ইন্টারফেস দ্বারা প্রতিস্থাপনের খুব সম্ভবত সম্ভাব্য, যেমন classকীওয়ার্ডটি প্রতিস্থাপন করা হবে interface(আপনি যদি সি #, জাভা এবং / বা পিএইচপি এর মতো ভাষার সাথে লেনদেন করেন) বা classকীওয়ার্ডটি থাকত তবে Compressএবং Encryptপদ্ধতিগুলি খাঁটি ভার্চুয়াল হিসাবে সংজ্ঞায়িত করা হবে , আপনি সি ++ এ কোড করা উচিত।

একটি অ্যাডাপ্টার তৈরি করতে, আমরা একটি সাধারণ ইন্টারফেস সংজ্ঞায়িত করি।

interface DataProcessing
{
    Process(data : any) : any;
}

তারপরে ইন্টারফেসটিকে কার্যকর করতে আমাদের বাস্তবায়ন করতে হবে।

// when neither encryption nor compression is enabled
class DoNothingAdapter : DataProcessing
{
    public Process(data : any) : any
    {
        return data;
    }
}

// when only compression is enabled
class CompressionAdapter : DataProcessing
{
    private compression : Compression;

    public Process(data : any) : any
    {
        return this.compression.Compress(data);
    }
}

// when only encryption is enabled
class EncryptionAdapter : DataProcessing
{
    private encryption : Encryption;

    public Process(data : any) : any
    {
        return this.encryption.Encrypt(data);
    }
}

// when both, compression and encryption are enabled
class CompressionEncryptionAdapter : DataProcessing
{
    private compression : Compression;
    private encryption : Encryption;

    public Process(data : any) : any
    {
        return this.encryption.Encrypt(
            this.compression.Compress(data)
        );
    }
}

এটি করে আপনি 4 টি ক্লাস দিয়ে শেষ করেছেন, প্রত্যেকে একেবারে আলাদা কিছু করছে তবে তাদের প্রত্যেকেরই একই পাবলিক এপিআই সরবরাহ করছে। Processপদ্ধতি।

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

class DataService
{
    private dataProcessing : DataProcessing;

    public DataService(dataProcessing : DataProcessing)
    {
        this.dataProcessing = dataProcessing;
    }
}

প্রক্রিয়া নিজেই তখন এর মতো সহজ হতে পারে:

public ComplicatedProcess(data : any) : any
{
    data = this.dataProcessing.Process(data);

    // ... perhaps work with the data

    return data;
}

আর শর্তসাপেক্ষ নেই। শ্রেণীর DataServiceকোনও ধারণা নেই যখন ডেটাটি dataProcessingমেম্বারের কাছে পাস করা হয় তখন ডেটা দিয়ে কী করা হবে , এবং এটি সত্যই এটি সম্পর্কে চিন্তা করে না, এটি তার দায়িত্ব নয়।

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

সুতরাং এইভাবে এটি করা ifআমার কোডে আর কখনও হবে না ?

না। আপনার ব্যবসায়ের যুক্তিতে শর্তসাপেক্ষ হওয়ার সম্ভাবনা কম তবে এগুলি এখনও কোথাও থাকতে হবে। জায়গাটি আপনার কারখানা।

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

এই সমস্ত ক্লাস, ইন্টারফেস ইত্যাদির প্রয়োজন কি?

এটি আমাদের ভিক্ষার দিকে ফিরিয়ে আনে।

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

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

আপনি এটি সম্পন্ন এবং দ্রুত পেতে চান, তাহলে আপনি দখল করতে পারেন Ixrec এর সমাধান , যারা অন্তত নিষ্কাশন পরিচালিত else ifএবং elseব্লক, যা, আমার মতে, এমনকি একটি বাচ্চা একটি প্লেইন চেয়ে খারাপ if

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

আমি ব্যক্তিগতভাবে ই-কম প্রোগ্রামিং বেশি পছন্দ করি এবং কোডের 5 লাইন ধরে দীর্ঘ সমাধানের আরও অনেক বেশি প্রশংসা করব। কোডটি ডিজাইনিং করার জন্য আমি যেভাবে অভ্যস্ত এবং এটি পড়তে খুব স্বাচ্ছন্দ্যবোধ করি।


আপডেট 2: আমার সমাধানের প্রথম সংস্করণ সম্পর্কে বন্য আলোচনা হয়েছে। বেশিরভাগ ক্ষেত্রেই আমার দ্বারা আলোচিত আলোচনা, যার জন্য আমি ক্ষমাপ্রার্থী।

আমি উত্তরটি এমনভাবে সম্পাদনা করার সিদ্ধান্ত নিয়েছি যে সমাধানটি দেখার এক উপায় তবে এটি একমাত্র নয়। আমি সাজসজ্জার অংশটিও সরিয়েছি, যেখানে আমি তার পরিবর্তে মুখোমুখি বোঝাচ্ছি, যা শেষ পর্যন্ত আমি পুরোপুরি ছেড়ে চলে যাওয়ার সিদ্ধান্ত নিয়েছিলাম, কারণ অ্যাডাপ্টারের একটি মুখের ভিন্নতা vari


28
আমি ডাউনভিট করি নি তবে যুক্তিটি মূল কোডটি 8 লাইনে করা কিছু করার জন্য নতুন ক্লাস / ইন্টারফেসের হাস্যকর পরিমাণ হতে পারে (এবং অন্য উত্তরটি 5 এ করেছিল)। আমার মতে এটির দ্বারা সম্পাদিত একমাত্র জিনিসটি কোডের জন্য শেখার বক্ররেখা বৃদ্ধি করছে।
মৌরিসি

6
@ মৌরিসি ওপি যা বলেছিল তা হ'ল সাধারণ নকশার ধরণগুলি ব্যবহার করে তার সমস্যার সমাধান খোঁজার চেষ্টা করা হয়েছে, যদি এই জাতীয় সমাধান বিদ্যমান থাকে। আমার সমাধান কি তার বা ইক্স্রেকের কোডের চেয়ে দীর্ঘ? এটাই. আমি এটা স্বীকার করি। আমার সমাধান কি ডিজাইন নিদর্শনগুলি ব্যবহার করে তার সমস্যার সমাধান করে এবং এইভাবে তার প্রশ্নের উত্তর দেয় এবং কার্যকরভাবে প্রক্রিয়া থেকে সমস্ত প্রয়োজনীয় আইএফগুলি সরিয়ে দেয়? এটা করে. Ixrec এর না।
অ্যান্ডি

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

12
আমার মনে হয় এখানে আমার দুটি সমস্যা রয়েছে। প্রথমটি হল যে Compressionএবং Encryptionইন্টারফেসগুলি একেবারে অতিমাত্রায় মনে হয়। আমি নিশ্চিত না আপনি যদি পরামর্শ দিচ্ছেন যে সেগুলি কোনওভাবে সজ্জা প্রক্রিয়াতে প্রয়োজনীয়, বা নিছক বোঝাচ্ছেন যে তারা উত্তোলিত ধারণার প্রতিনিধিত্ব করে। দ্বিতীয় সমস্যাটি হ'ল একটি শ্রেণির মতো তৈরি করা CompressionEncryptionDecoratorওপির শর্তসাপেক্ষ হিসাবে একই ধরণের মিশ্র বিস্ফোরণ ঘটায়। আমি প্রস্তাবিত কোডটিতে সাজসজ্জার প্যাটার্নটি যথেষ্ট পরিস্কারভাবে দেখতে পাচ্ছি না।
cbojar

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

120

আপনার বর্তমান কোডটির সাথে আমি দেখতে পাচ্ছি একমাত্র সমস্যা হ'ল সংযোজনীয় বিস্ফোরণের ঝুঁকি হ'ল আপনি আরও সেটিংস যুক্ত করলে এ কোডটি আরও এভাবে কাঠামোগত করে সহজেই প্রশমিত করা যায়:

if(compressEnable){
  data = compress(data);
}
if(encryptionEnable) {
  data = encrypt(data);
}
return data;

আমি এমন কোনও "নকশার ধরণ" বা "আইডিয়ম" সম্পর্কে অবগত নই যা এর উদাহরণ হিসাবে বিবেচিত হতে পারে।


18
@ দামিথগেনগোদা নোপ, আপনি আমার কোডটি মনোযোগ সহকারে পড়লে আপনি দেখতে পাবেন যে এটি একই ক্ষেত্রে একই কাজ করে। এজন্য elseবিবৃতি দেওয়ার ক্ষেত্রে আমার দুজনের মধ্যে কোনও মিল নেই এবং কেন আমি dataপ্রত্যেকবারের জন্য বরাদ্দ করছি । উভয় পতাকা যদি সত্য হয়, তবে সংক্ষেপিত () সম্পাদন হবে, তারপরে এনক্রিপ্ট () আপনার পছন্দ মত সংকোচন () এর ফলাফলের উপর কার্যকর করা হবে।
Ixrec

14
@ ডেভিডপ্যাকার প্রযুক্তিগতভাবে, প্রতিটি প্রোগ্রামিং ভাষায় যদি প্রতিটি বিবৃতি দেয় তবে তা করে। আমি সরলতার জন্য গিয়েছিলাম, যেহেতু এটি এমন সমস্যার মতো দেখাচ্ছিল যেখানে খুব সাধারণ উত্তর উপযুক্ত ছিল। আপনার সমাধানটিও বৈধ, তবে ব্যক্তিগতভাবে আমি যখন এটির জন্য দু'জন বুলিয়ান পতাকা ব্যবহার করার চেয়ে অনেক বেশি ছিলাম তখন এটি সংরক্ষণ করতাম।
Ixrec

15
@ ডেভিডপ্যাকার: সঠিকভাবে সংজ্ঞা দেওয়া হয়নি যে কিছু প্রোগ্রামিং আদর্শের বিষয়ে কোনও লেখক কোনও গাইডলাইনকে কতটা সঠিকভাবে মেনে চলেন। সঠিক "কোডটি যা করার কথা বলেছিল তা করে এবং এটি কি যুক্তিসঙ্গত সময়ে কার্যকর করা হয়েছিল" rect যদি এটি "ভুল উপায়ে" করতে বোঝা যায় তবে ভুল উপায় সঠিক উপায় কারণ সময় অর্থ।
whatsisname

9
@ ডেভিডপ্যাকার: আমি যদি ওপি'র অবস্থানে ছিলাম এবং এই প্রশ্নটি জিজ্ঞাসা করছিলাম, অরবিটের মন্তব্যে লাইটনেস রেস আমার সত্যিকারের প্রয়োজন। "নকশার ধরণগুলি ব্যবহার করে একটি সমাধান সন্ধান করা" ইতিমধ্যে ভুল পাদদেশ থেকে শুরু হচ্ছে।
'18

6
@ ডেভিডপ্যাকার আসলে আপনি যদি প্রশ্নটি আরও ঘনিষ্ঠভাবে পড়েন তবে এটি কোনও প্যাটার্নের জন্য জোর দেয় না। এটিতে লেখা আছে , "আমি ডেকরেটর প্যাটার্ন সম্পর্কে ভাবছি it এটি কি সঠিক পছন্দ, বা সম্ভবত এর চেয়ে ভাল বিকল্প আছে?" । আপনি আমার উদ্ধৃতিতে প্রথম বাক্যটি সম্বোধন করেছিলেন, তবে দ্বিতীয়টি নয়। অন্যান্য লোকেরা এই পদ্ধতিটি নিয়েছিল যে না, এটি সঠিক পছন্দ নয়। এরপরে আপনি দাবি করতে পারবেন না যে কেবল আপনারাই প্রশ্নের উত্তর দিয়েছেন।
জন বেন্টলে

12

আমি অনুমান করি আপনার প্রশ্নটি ব্যবহারিকতার জন্য নয়, সেক্ষেত্রে lxrec এর উত্তর সঠিক, তবে ডিজাইনের ধরণগুলি সম্পর্কে শিখতে হবে।

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

public interface Command {
    public String transform(String s);
}

public class CompressCommand implements Command {
    @Override
    public String transform(String s) {
        String compressedString=null;
        //Compression code here
        return compressedString;
    }
}

public class EncryptCommand implements Command {
    @Override
    public String transform(String s) {
        String EncrytedString=null;
        // Encryption code goes here
        return null;
    }

}

public class Test {
    public static void main(String[] args) {
        List<Command> commands = new ArrayList<Command>();
        commands.add(new CompressCommand());
        commands.add(new EncryptCommand()); 
        String myString="Test String";
        for (Command c: commands){
            myString = c.transform(myString);
        }
        // now myString can be stored in the database
    }
}

আপনি দেখতে পাচ্ছেন যে কমান্ডগুলি / রূপান্তরকে একটি তালিকায় রাখার ফলে অনুক্রমিকভাবে কার্যকর করা সম্ভব হয়। স্পষ্টতই এটি উভয়কেই কার্যকর করে দেবে, বা কেবলমাত্র শর্ত ছাড়াই আপনি তালিকায় কী রেখেছেন তার মধ্যে কেবলমাত্র একটির উপর নির্ভর করে।

স্পষ্টতই শর্তসাপেক্ষাগুলি এক ধরণের কারখানায় শেষ হবে যা কমান্ড তালিকাকে একসাথে রাখে।

@ টেক্সাকারের মন্তব্যের জন্য সম্পাদনা করুন:

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


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

@ থেক্সাস্যাক্রে আমি একটি উদাহরণ যুক্ত করেছি।
তুলাইনস কর্ডোভা

সুতরাং আপনার চেকবক্স ইভেন্ট শ্রোতাদের মধ্যে আপনি "যদি চেকবক্স.টিক থাকে তবে কমান্ড যুক্ত করবেন"? আমার কাছে মনে হচ্ছে আপনি চারপাশে বিবৃতি দিলে আপনি কেবল পতাকাটি পরিবর্তন করছেন ...
থেক্স্যাকার

@ থেক্স্যাক্রে নং, প্রতিটি চেকবক্সের জন্য একজন শ্রোতা। ক্লিক ইভেন্টে ঠিক commands.add(new EncryptCommand()); বা commands.add(new CompressCommand());যথাক্রমে
তুলিনস কর্ডোভা

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

7

আমি মনে করি "নকশার ধরণগুলি" "oo প্যাটার্নগুলি" এর দিকে অবিচ্ছিন্নভাবে প্রস্তুত এবং অনেক সহজ ধারণা সম্পূর্ণরূপে এড়ানো হচ্ছে। আমরা এখানে যে বিষয়ে কথা বলছি তা হ'ল একটি (সাধারণ) ডেটা পাইপলাইন।

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

1. রূপান্তর একটি সেট প্রতিনিধিত্ব করুন।

(def transformations { :encrypt  (fn [data] ... ) 
                       :compress (fn [data] ... )})

এটি একটি মানচিত্র, উদাহরণস্বরূপ একটি সারণী / অভিধান / যা কিছু আছে, কীওয়ার্ড থেকে শুরু করে ফাংশন পর্যন্ত। আর একটি উদাহরণ (স্ট্রিং-এর মূলশব্দ):

(def employees { :A1 "Alice" 
                 :X9 "Bob"})

(employees :A1) ; => "Alice"
(:A1 employees) ; => "Alice"

সুতরাং, লেখা (transformations :encrypt)বা (:encrypt transformations)এনক্রিপ্ট ফাংশন ফিরে আসবে। ( (fn [data] ... )কেবলমাত্র একটি ল্যাম্বডা ফাংশন))

২. কীওয়ার্ডের ক্রম হিসাবে বিকল্পগুলি পান:

(defn do-processing [options data] ;function definition
  ...)

(do-processing [:encrypt :compress] data) ;call to function

3. সরবরাহিত বিকল্পগুলি ব্যবহার করে সমস্ত রূপান্তর ফিল্টার করুন।

(let [ transformations-to-run (map transformations options)] ... )

উদাহরণ:

(map employees [:A1]) ; => ["Alice"]
(map employees [:A1 :X9]) ; => ["Alice", "Bob"]

৪. একটিতে ফাংশন একত্রিত করুন:

(apply comp transformations-to-run)

উদাহরণ:

(comp f g h) ;=> f(g(h()))
(apply comp [f g h]) ;=> f(g(h()))

৫. এবং তারপরে একসাথে:

(def transformations { :encrypt  (fn [data] ... ) 
                       :compress (fn [data] ... )})

(defn do-processing [options data]
  (let [transformations-to-run (map transformations options)
        selected-transformations (apply comp transformations-to-run)] 
    (selected-transformations data)))

(do-processing [:encrypt :compress])

কেবলমাত্র যদি আমরা একটি নতুন ফাংশন যুক্ত করতে চাই, "ডিবাগ-প্রিন্ট" বলুন তবেই পরিবর্তিত হয়:

(def transformations { :encrypt  (fn [data] ... ) 
                       :compress (fn [data] ... )
                       :debug-print (fn [data] ...) }) ;<--- here to add as option

(defn do-processing [options data]
  (let [transformations-to-run (map transformations options)
        selected-transformations (apply comp transformations-to-run)] 
    (selected-transformations data)))

(do-processing [:encrypt :compress :debug-print]) ;<-- here to use it
(do-processing [:compress :debug-print]) ;or like this
(do-processing [:encrypt]) ;or like this

একরকমভাবে বা অন্য কোনওভাবে বিবৃতি যদি বিবরণী ব্যবহার না করে প্রয়োজনীয় ক্রিয়াকলাপগুলি অন্তর্ভুক্ত করা হয় তবে কেবল ফাংশনগুলি কীভাবে অন্তর্ভুক্ত করা যায়?
thexacre

সারিটি funcs-to-run-here (map options funcs)ফিল্টারিং করছে, এভাবে প্রয়োগ করার জন্য একটি কার্যকারিতা সেট করে। হয়তো আমার উত্তরটি আপডেট করা উচিত এবং আরও কিছুটা বিশদে যাওয়া উচিত।
নিক্লাসজে

5

[মূলত, আমার উত্তরটি উপরের @ ইমরেক্সের উত্তরের একটি ফলো-অন । ]

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

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

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


1

স্কেলে এটি করার একটি উপায় হ'ল:

val handleCompression: AnyRef => AnyRef = data => if (compressEnable) compress(data) else data
val handleEncryption: AnyRef => AnyRef = data => if (encryptionEnable) encrypt(data) else data
val handleData = handleCompression andThen handleEncryption
handleData(data)

উপরের লক্ষ্যগুলি অর্জনের জন্য ডেকোরেটর প্যাটার্ন ব্যবহার করা (স্বতন্ত্র প্রক্রিয়াজাতকরণ যুক্তির বিভাজন এবং তারা কীভাবে একসাথে ওয়্যার করেন) খুব ভার্জিক হবে।

ওও প্রোগ্রামিং দৃষ্টান্তে আপনার এই নকশাগুলির লক্ষ্য অর্জনের জন্য আপনার ডিজাইনের প্যাটার্নের প্রয়োজন হবে, কার্যকরী ভাষা প্রথম শ্রেণির নাগরিক হিসাবে ফাংশন ব্যবহার করে (কোডের 1 এবং 2) এবং কার্যকরী রচনা (লাইন 3) হিসাবে স্থানীয় সমর্থন সরবরাহ করে


কেন এটি অপের পদ্ধতির চেয়ে ভাল (বা আরও খারাপ)? এবং / অথবা ডিকোরিটার প্যাটার্নটি ব্যবহার করার জন্য আপনি ওপি-র ধারণা সম্পর্কে কী ভাবেন?
ক্যাস্পার ভ্যান ডেন বার্গ

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