আপনি কিভাবে একটি নির্মাণকারী পচন করতে পারেন?


21

আসুন বলুন যে আমার একটি শত্রু শ্রেণি রয়েছে, এবং নির্মাতা এর মতো দেখতে পাবেন:

public Enemy(String name, float width, float height, Vector2 position, 
             float speed, int maxHp, int attackDamage, int defense... etc.){}

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

আমি কীভাবে পরিষ্কারভাবে কোডিং করব তা শেখার চেষ্টা করছি। যদি এটি কোনও পার্থক্য করে তবে আমি জাভা / সি ++ / সি # তে কাজ করি। সঠিক দিকের যে কোনও পয়েন্ট প্রশংসা করা হয়।


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

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


উত্তর:


58

সমাধানটি হ'ল প্যারামিটারগুলি সংমিশ্রিত প্রকারে বান্ডিল করা। প্রস্থ এবং উচ্চতা ধারণাগতভাবে সম্পর্কিত - তারা শত্রুর মাত্রা নির্দিষ্ট করে এবং সাধারণত একসাথে প্রয়োজন হবে। এগুলি কোনও Dimensionsপ্রকারের সাথে প্রতিস্থাপন করা যেতে পারে , বা সম্ভবত এমন কোনও Rectangleধরণ রয়েছে যা অবস্থানও অন্তর্ভুক্ত করে। অন্যদিকে, এটি দলবদ্ধভাবে positionএবং speedকোনও MovementDataধরণের আরও বোধগম্য হতে পারে , বিশেষত যদি ত্বরণ পরে ছবিতে প্রবেশ করে। প্রসঙ্গ থেকে আমি অনুমান maxHp, attackDamage, defense, ইত্যাদি একসাথে একটি অন্তর্গত Statsপ্রকার। সুতরাং, একটি সংশোধিত স্বাক্ষরটি দেখতে এরকম কিছু দেখতে পাবে:

public Enemy(String name, Dimensions dimensions, MovementData movementData, Stats stats)

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


21
আমি আরও যোগ করব যে এতগুলি মান থাকা সিঙ্গল দায়বদ্ধতার নীতি লঙ্ঘনকে নির্দেশ করে। এবং নির্দিষ্ট বস্তুগুলিতে মানগুলিকে গ্রুপিং করা সেই দায়িত্বগুলি পৃথক করার প্রথম পদক্ষেপ।
ইউফোরিক

2
আমি মনে করি না যে মানগুলির তালিকাটি একটি এসআরপি সমস্যা; তাদের বেশিরভাগই সম্ভবত বেস শ্রেণি নির্মাতাদের উদ্দেশ্যে। শ্রেণিবদ্ধ প্রতিটি শ্রেণীর একক দায়িত্ব থাকতে পারে। Enemyকেবলমাত্র এমন শ্রেণি যা লক্ষ্যবস্তু করে Playerতবে তাদের সাধারণ বেস শ্রেণির Combatantজন্য লড়াইয়ের পরিসংখ্যান প্রয়োজন।
এমসাল্টার্স

@ এসএমএলটারগুলি এটি অগত্যা কোনও এসআরপি সমস্যা নির্দেশ করে না, তবে তা পারে। যদি তাকে পর্যাপ্ত নম্বর-ক্রাঞ্চিংয়ের প্রয়োজন হয়, তখন এই ফাংশনগুলি শত্রু শ্রেণিতে প্রবেশ করতে পারে যখন সেগুলি স্থির / ফ্রি ফাংশন হওয়া উচিত (যদি তিনি ব্যবহার করেন Dimensions/ MovementDataসাধারণ পুরানো ডেটা ধারক হিসাবে ব্যবহার করেন) বা পদ্ধতিগুলি (যদি সে সেগুলি বিমূর্ত তথ্যে রূপান্তরিত করে) ধরনের / বস্তু)। উদাহরণস্বরূপ, যদি তিনি ইতিমধ্যে কোনও Vector2প্রকার তৈরি না করে থাকেন তবে তিনি ভেক্টর গণিতটি শেষ করতে পারেন Enemy
ডোভাল

24

আপনি বিল্ডার প্যাটার্নটি একবার দেখে নিতে পারেন । লিঙ্কটি থেকে (বিকল্পের তুলনায় প্যাটার্নের উদাহরণ সহ):

[দ্য] বিল্ডার প্যাটার্নগুলি এমন একটি ক্লাস ডিজাইন করার সময় একটি ভাল পছন্দ যাঁর নির্মাতারা বা স্ট্যাটিক কারখানার হাতে গোনা কয়েকটা প্যারামিটার থাকে, বিশেষত যদি সেই পরামিতিগুলির বেশিরভাগই alচ্ছিক হয়। Cliতিহ্যবাহী টেলিস্কোপিং কনস্ট্রাক্টর প্যাটার্নের তুলনায় বিল্ডারদের সাথে ক্লায়েন্ট কোডটি পড়া এবং লেখার পক্ষে আরও সহজ এবং বিল্ডাররা জাভাবীনের চেয়ে অনেক বেশি নিরাপদ।


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

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

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

1
@ মার্ক 16 লিঙ্কে উল্লিখিত হিসাবে, > বিল্ডার প্যাটার্নটি অ্যাডা এবং পাইথন হিসাবে পাওয়া simচ্ছিক পরামিতিগুলির নামকরণ করে। আপনি উল্লেখ করেছেন যে আপনি প্রশ্নের ক্ষেত্রেও সি # ব্যবহার করেন এবং সেই ভাষাটি নাম / alচ্ছিক আর্গুমেন্টগুলিকে সমর্থন করে (সি # 4.0 হিসাবে), যাতে এটি অন্য বিকল্প হতে পারে।
বব

5

কিছু মান পূর্বনির্ধারিত সাবক্ল্যাস ব্যবহার করা বাঞ্ছনীয় নয়। কেবলমাত্র সাবক্লাসে যখন কোনও নতুন ধরণের শত্রুর বিভিন্ন আচরণ বা নতুন বৈশিষ্ট্য থাকে।

কারখানা প্যাটার্ন সাধারণত সঠিক ব্যবহার ক্লাস শেষ বিমূর্ত করতে ব্যবহৃত হয়, কিন্তু এটি অবজেক্ট তৈরির জন্য একটি টেমপ্লেট দিতে ব্যবহৃত করা যেতে পারে:

class EnemyFactory {

    // each of these methods is essentially a template for a kind of enemy

    Enemy enemyA(String name, ...) {
        return new Enemy(name, ..., presetValue, ...);
    }

    Enemy enemyB(String name, ...) {
        return new Enemy(name, ..., otherValue, ...);
    }

    Enemy enemyC(String name, ...) {
        return new EnemySubclass(name, ..., otherValue, ...);
    }

    ...
}

EnemyFactory factory = new EnemyFactory();
Enemy a = factory.enemyA("fred", ...);
Enemy b = factory.enemyB("willy", ...);

0

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

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

আপনি কোন ভাষাটি ব্যবহার করতে চান তার উপর নির্ভর করে কিছু আপনার নির্মাণকারীর ইনপুট প্যারামিটারের জন্য ডিফল্ট মান সেট করতে পারে:

Enemy(float height = 42, float width = 42);

0

ররি হান্টারের উত্তরে (জাভাতে) যুক্ত করার একটি কোড উদাহরণ:

public class Enemy{
   private String name;
   private float width;
   ...

   public static class Builder{
       private Enemy instance;

       public Builder(){
           this.instance = new Enemy();
       }


       public Builder withName(String name){
           instance.name = name;
           return this;
       }

       ...

       public Enemy build(){
           return instance;
       }
   }
}

এখন, আপনি এ জাতীয় শত্রুর নতুন দৃষ্টান্ত তৈরি করতে পারেন:

Enemy myEnemy = new Enemy.Builder().withName("John").withX(x).build();

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