মিউটেশন পদ্ধতির জন্য পৃথক ইন্টারফেস


11

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

আমি একটি ইন্টারফেস Fooহিসাবে হিসাবে সংজ্ঞায়িত করা আছে

public interface Foo {

    int getX();

    int getY();

    int getZ();
}

এবং একটি বাস্তবায়ন হিসাবে

public final class DefaultFoo implements Foo {

    public DefaultFoo(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getZ() {
        return z;
    }

    private final int x;
    private final int y;
    private final int z;
}

আমার কাছে একটি ইন্টারফেস রয়েছে MutableFooযা মিলে মিউটরদের সরবরাহ করে

/**
 * This class extends Foo, because a 'write-only' instance should not
 * be possible and a bit counter-intuitive.
 */
public interface MutableFoo extends Foo {

    void setX(int newX);

    void setY(int newY);

    void setZ(int newZ);
}

এটির বেশ কয়েকটি বাস্তবায়ন MutableFooবিদ্যমান থাকতে পারে (আমি এখনও এগুলি প্রয়োগ করি নি)। তার মধ্যে একটি

public final class DefaultMutableFoo implements MutableFoo {

    /**
     * A DefaultMutableFoo is not conceptually constructed 
     * without all values being set.
     */
    public DefaultMutableFoo(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public int getX() {
        return x;
    }

    public void setX(int newX) {
        this.x = newX;
    }

    public int getY() {
        return y;
    }

    public void setY(int newY) {
        this.y = newY;
    }

    public int getZ() {
        return z;
    }

    public void setZ(int newZ) {
        this.z = newZ;
    }

    private int x;
    private int y;
    private int z;
}

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

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

/**
 * The EffectiveStats can never be modified independently of either the baseStats
 * or trained stats. As such, this StatSet must never provide mutators.
 */
public StatSet calculateEffectiveStats() {
    int effectiveHitpoints =
        baseStats.getHitpoints() + (trainedStats.getHitpoints() / 4);
    int effectiveAttack = 
        baseStats.getAttack() + (trainedStats.getAttack() / 4);
    int effectiveDefense = 
        baseStats.getDefense() + (trainedStats.getDefense() / 4);

    return StatSetFactory.createImmutableStatSet(effectiveHitpoints, effectiveAttack, effectiveDefense);
}

প্রশিক্ষিত স্ট্যাটাস প্রতিটি যুদ্ধের পরে বাড়ানো হয়

public void grantExperience() {
    int hitpointsReward = 0;
    int attackReward = 0;
    int defenseReward = 0;

    final StatSet enemyStats = enemy.getEffectiveStats();
    final StatSet currentStats = player.getEffectiveStats();
    if (enemyStats.getHitpoints() >= currentStats.getHitpoints()) {
        hitpointsReward++;
    }
    if (enemyStats.getAttack() >= currentStats.getAttack()) {
        attackReward++;
    }
    if (enemyStats.getDefense() >= currentStats.getDefense()) {
        defenseReward++;
    }

    final MutableStatSet trainedStats = player.getTrainedStats();
    trainedStats.increaseHitpoints(hitpointsReward);
    trainedStats.increaseAttack(attackReward);
    trainedStats.increaseDefense(defenseReward);
}

তবে যুদ্ধের পরে এগুলি বাড়ানো হয়নি। নির্দিষ্ট আইটেম ব্যবহার করা, নির্দিষ্ট কৌশল প্রয়োগ করা, রণক্ষেত্রের চৌকস ব্যবহার সবই বিভিন্ন অভিজ্ঞতা প্রদান করতে পারে।

এখন আমার প্রশ্নের জন্য:

  1. অ্যাক্সেসর এবং মিউটরদের পৃথক ইন্টারফেসে বিভক্ত ইন্টারফেসের কোনও নাম আছে?
  2. এগুলিকে এভাবে ভাগ করে নেওয়া যদি তারা ব্যবহার করার মতো সমান সম্ভাবনা থাকে তবে আমার পরিবর্তে অন্য কোনও গ্রহণযোগ্য প্যাটার্ন ব্যবহার করা উচিত (উদাহরণস্বরূপ Foo foo = FooFactory.createImmutableFoo();যা প্রত্যাবর্তন করতে পারে DefaultFooবা প্রত্যাবর্তনের DefaultMutableFooকারণে লুকিয়ে রয়েছে )?createImmutableFooFoo
  3. এই প্যাটার্নটি ব্যবহার করার জন্য অবিলম্বে কোন প্রত্যাশাযোগ্য ডাউনসাইড রয়েছে, ইন্টারফেসের ক্রমবিকাশের জটিলতার জন্য সংরক্ষণ করুন?

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

EffectiveStatSetআমরা কোনওভাবে কার্যকারিতা প্রসারিত করছি না এর জন্য একটি নতুন শ্রেণি তৈরি করা তেমন অর্থবোধ করে না। আমরা বাস্তবায়ন পরিবর্তন করতে এবং EffectiveStatSetদুটি পৃথক করে একটি সংমিশ্রণ তৈরি করতে পারতাম StatSets, তবে আমি মনে করি এটি সঠিক সমাধান নয়;

public class EffectiveStatSet implements StatSet {

    public EffectiveStatSet(StatSet baseStats, StatSet trainedStats) {
        // ...
    }

    public int getHitpoints() {
        return baseStats.getHitpoints() + (trainedStats.getHitpoints() / 4);
    }
}


1
আমি মনে করি সমস্যাটি হ'ল আপনার অবজেক্টটি পরিবর্তনযোগ্য তবে আপনি যদি এটির আমার 'স্থাবর' ইন্টারফেসটি অ্যাক্সেস করেন তবে। প্লেয়ারের সাথে একটি পরিবর্তনীয় বস্তু থাকা ভাল rain ট্রেনস্ট্যাটস ()
ইভান

@gnat আপনার কি কোনও রেফারেন্স রয়েছে যেখানে আমি সে সম্পর্কে আরও জানতে পারি? সম্পাদিত প্রশ্নের ভিত্তিতে, আমি নিশ্চিত না যে আমি কীভাবে বা কোথায় এটি প্রয়োগ করতে পারি।
জিমাস

@ গ্যাनेट: আপনার লিঙ্কগুলি (এবং এটির দ্বিতীয়-ডিগ্রি এবং তৃতীয়-ডিগ্রি লিঙ্কগুলি) খুব দরকারী তবে জ্ঞানের আকর্ষণীয় বাক্যাংশগুলি খুব একটা সহায়ক নয়। এটি কেবল ভুল বোঝাবুঝি এবং তুচ্ছতাকে আকর্ষণ করে।
রোবং

উত্তর:


6

আমার কাছে মনে হচ্ছে আপনার কাছে সমস্যার সমাধানের সমাধান রয়েছে।

অ্যাক্সেসর এবং মিউটরদের পৃথক ইন্টারফেসে বিভক্ত ইন্টারফেসের কোনও নাম আছে?

এটি কিছুটা উস্কানিমূলক হতে পারে, তবে আসলে আমি এটিকে "ওভারডিজাইনিং জিনিস" বা "অতিমাত্রায় জটিল জিনিস" বলব। একই শ্রেণীর একটি পরিবর্তনীয় এবং অপরিবর্তনীয় বৈকল্পিক প্রস্তাব দিয়ে আপনি একই সমস্যার জন্য দুটি কার্যকরী সমতুল্য সমাধান সরবরাহ করেন যা পারফরম্যান্স আচরণ, এপিআই এবং পার্শ্ব প্রতিক্রিয়াগুলির বিরুদ্ধে সুরক্ষার মতো অ-কার্যক্ষম দিকগুলিতে পৃথক। আমি অনুমান করি যে এর কারণ আপনি কোনটিকে পছন্দ করবেন এমন সিদ্ধান্ত নিতে ভয় পান বা আপনি সি # তে সি ++ এর "কনস্ট" বৈশিষ্ট্যটি প্রয়োগ করার চেষ্টা করছেন। আমি অনুমান করি যে সমস্ত ক্ষেত্রে 99% এর ক্ষেত্রে বড় পার্থক্য হবে না যদি ব্যবহারকারী পরিবর্তনীয় বা অপরিবর্তনীয় রূপটি বেছে নেয়, তবে সে তার সমস্যাগুলি উভয় ক্ষেত্রেই সমাধান করতে পারে other সুতরাং "ব্যবহৃত একটি শ্রেণীর সদৃশতা"

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

এগুলিকে এভাবে ভাগ করে দিচ্ছে যদি তারা ব্যবহারের সমান সম্ভাবনা থাকে বা অন্যরকম, আরও স্বীকৃত প্যাটার্ন থাকে তবে 'সঠিক' পন্থাটি

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

এই প্যাটার্নটি ব্যবহার করার জন্য অবিলম্বে কোন প্রত্যাশাযোগ্য ডাউনসাইড রয়েছে, ইন্টারফেসের ক্রমবিকাশের জটিলতার জন্য সংরক্ষণ করুন?

অতিরিক্ত জটিল নকশাগুলি সফ্টওয়্যারটিকে পরীক্ষা করা শক্ত, বজায় রাখা শক্ত, আরও শক্তিশালী হয়ে উঠেছে।


1
আমার মনে হয় আপনার অর্থ "কেআইএসএস
এটিকে

2

অ্যাক্সেসর এবং মিউটরদের পৃথক ইন্টারফেসে বিভক্ত ইন্টারফেসের কোনও নাম আছে?

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

আপনি কি এমন কোনও ব্যবসায়ের ব্যবহারের ক্ষেত্রে বলতে পারেন যেখানে দুটি পৃথক ইন্টারফেস আমাদের উপকার প্রদান করে বা এই প্রশ্নটি কোন একাডেমিক সমস্যা (ওয়াইএজিএনআই)?

আমি একটি পরিবর্তনীয় কার্টের সাথে শপিংয়ের কথা ভাবতে পারি (আপনি আরও নিবন্ধগুলি রাখতে পারেন) এটি এমন অর্ডার হয়ে উঠতে পারে যেখানে নিবন্ধগুলি নোটটি গ্রাহককে আর পরিবর্তন করতে পারে। অর্ডার-স্থিতি এখনও পরিবর্তনযোগ্য।

আমি যে প্রয়োগগুলি দেখেছি সেগুলি ইন্টারফেসগুলি পৃথক করে না

  • জাভাতে কোনও ইন্টারফেস রিডইনলিস্ট নেই

পঠনযোগ্য সংস্করণটি "WritableInterface" ব্যবহার করে এবং একটি লিখন পদ্ধতিটি ইউস করা থাকলে একটি ব্যতিক্রম ছুঁড়ে দেয়


প্রাথমিক ব্যবহারের কেসটি ব্যাখ্যা করতে আমি ওপিকে পরিবর্তন করেছি।
জিমাস

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

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

1

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

এখানে কয়েকটি শব্দ লক্ষ্য করুন: "কেবলমাত্র পঠনযোগ্য-চুক্তি" এবং "সংগ্রহ"।

কেবলমাত্র পঠনযোগ্য-চুক্তির অর্থ শ্রেণি Aক্লাসটিকে Bকেবল পঠনযোগ্য অ্যাক্সেস দেয় তবে তা বোঝায় না যে অন্তর্নিহিত সংগ্রহ অবজেক্টটি আসলে অপরিবর্তনীয়। অপরিবর্তনীয় এর অর্থ হ'ল ভবিষ্যতে এটি কখনই পরিবর্তিত হবে না, কোনও এজেন্টের ব্যাপারেই নয়। কেবল পঠনযোগ্য-চুক্তি কেবল বলেছে যে প্রাপককে এটি পরিবর্তন করার অনুমতি নেই; অন্য কাউকে (বিশেষত শ্রেণি A) এটিকে পরিবর্তন করার অনুমতি দেওয়া হয়েছে।

কোনও বস্তুকে অপরিবর্তনীয় করে তুলতে, এটি অবশ্যই সত্যিকারের অপরিবর্তনীয় - এটি এজেন্টের অনুরোধ না করে এর ডেটা পরিবর্তন করার প্রচেষ্টা অস্বীকার করতে হবে।

প্যাটার্নটি সম্ভবত অবজেক্টগুলিতে পর্যবেক্ষণ করা হয় যা ডেটা সংগ্রহের প্রতিনিধিত্ব করে - তালিকা, সিকোয়েন্স, ফাইল (স্ট্রিম), ইত্যাদি etc.


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


এখানে আমার পদ্ধতির (অপরিবর্তনের উপর ভিত্তি করে নয়)।

  1. একটি ডিটিও (ডেটা ট্রান্সফার অবজেক্ট) সংজ্ঞায়িত করুন, এটি মান টিউপল হিসাবেও পরিচিত।
    • এই DTO তিনটি ক্ষেত্র উপস্থিত থাকবে: hitpoints, attack, defense
    • কেবল ক্ষেত্রগুলি: পাবলিক, যে কেউ লিখতে পারে, কোনও সুরক্ষা দেয় না।
    • তবে, ডিটিও অবশ্যই একটি নিক্ষেপযোগ্য অবজেক্ট হতে হবে: যদি ক্লাসে Aকোনও ডিটিও পাস করার প্রয়োজন হয় তবে Bএটি এর একটি অনুলিপি তৈরি করে তার পরিবর্তে অনুলিপিটি পাস করবে। সুতরাং, Bডিটিও যেটি পছন্দ করে তা ব্যবহার করতে পারেন (এটি লিখতে), ডিটিওর উপর প্রভাব ফেলে না A
  2. grantExperienceফাংশন দুটি ভেঙ্গে হবে:
    • calculateNewStats
    • increaseStats
  3. calculateNewStats দুটি ডিটিওর ইনপুট গ্রহণ করবে, একজন প্লেয়ারের পরিসংখ্যান এবং অন্যটি শত্রু পরিসংখ্যান উপস্থাপন করে এবং গণনা সম্পাদন করবে।
    • ইনপুটটির জন্য, কলার আপনার প্রয়োজন অনুসারে বেস, প্রশিক্ষিত বা কার্যকর পরিসংখ্যানগুলির মধ্যে বেছে নেওয়া উচিত।
    • এর ফলে নতুন DTO যেখানে প্রতিটি ক্ষেত্র (হতে হবে hitpoints, attack, defense) দোকানে পরিমাণ বৃদ্ধি করা যে ক্ষমতা জন্য।
    • নতুন "ইনক্রিমেন্টের পরিমাণ" ডিটিও সেই মানগুলির জন্য উপরের সীমা (আরোপিত সর্বাধিক ক্যাপ) সম্পর্কে উদ্বেগ প্রকাশ করে না।
  4. increaseStats প্লেয়ারের একটি পদ্ধতি (ডিটিওতে নয়) এটি একটি "ইনক্রিমেন্টের পরিমাণ" ডিটিও নেয় এবং ডিটিওতে সেই বর্ধিতকরণ প্রয়োগ করে যা প্লেয়ারের মালিকানাধীন এবং খেলোয়াড়ের প্রশিক্ষণযোগ্য ডিটিওর প্রতিনিধিত্ব করে।
    • যদি এই পরিসংখ্যানগুলির জন্য প্রযোজ্য সর্বাধিক মান থাকে তবে সেগুলি এখানে প্রয়োগ করা হয়।

যদি calculateNewStatsঅন্য কোনও খেলোয়াড় বা শত্রু তথ্যের উপর নির্ভর না করে দেখা যায় (দুটি ইনপুট ডিটিওর মান ছাড়াই) এই পদ্ধতিটি সম্ভাব্যভাবে প্রকল্পের যে কোনও জায়গায় অবস্থিত হতে পারে।

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


1

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

// Mutates mutableFoo
mutableFoo.setX(...)
// Creates a new updated immutableFoo, existing immutableFoo is unchanged
newFoo = immutableFoo.setX(...)

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

// Stats are mutable, mutates self.stats
self.stats.setX(...)

আপনার থাকতে হবে:

// Stats are immutable, mutates self, setX() returns new updated stats
self.stats = self.stats.setX(...)

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

এর অর্থ আপনার সিস্টেমে থাকা অন্যান্য অবজেক্টস স্ট্যাটাস অবজেক্টের রেফারেন্সের উপর নির্ভর করতে পারে না - প্লেয়ারের স্ট্যাটাস আপডেট হওয়ার পরে প্লেয়ারের যে স্ট্যাটাস অবজেক্ট থাকে তা সে রকমের স্ট্যাটাস অবজেক্ট হবে না।

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


1

বাহ ... এটি সত্যিই আমাকে ফিরিয়ে নিয়ে যায়। আমি একই ধারণা কয়েকবার চেষ্টা করেছিলাম। আমি এটি ছেড়ে দিতে খুব জেদী ছিলাম কারণ আমি ভেবেছিলাম এখানে আরও ভাল কিছু শিখতে হবে। আমি অন্যদেরও কোড এ চেষ্টা করে দেখেছি। সর্বাধিক বাস্তবায়নের আমি আপনার মত কেবল-পাঠ্য ইন্টারফেসগুলি নামক মনে আছে আপনার FooViewerবা ReadOnlyFooএবং তা লিখতে কেবল ইন্টারফেসকে FooEditorবা WriteableFooবা জাভা আমি মনে করি আমি দেখেছি FooMutatorএকবার। আমি নিশ্চিত নই যে এইভাবে কাজ করার জন্য কোনও অফিসিয়াল বা এমনকি সাধারণ শব্দভাণ্ডার রয়েছে।

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

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

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

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

আপনি যে রচনাটির উল্লেখ করেছেন তাতে আমি আরও চিন্তাভাবনা করব। আমি কৌতূহলী যে আপনি কেন এটি খারাপ ধারণা হবে মনে করেন। আমি বলে আশা করা যেত EffectiveStatsরচনা এবং অপরিবর্তনীয় Statsএবং কিছু মত StatModifiersযা আরো কিছু সেট রচনা করবে StatModifierগুলি যে প্রতিনিধিত্ব যাই হোক না কেন (কিছু বর্ধিতকরণ এলাকা, ক্লান্তি অস্থায়ী প্রভাব, আইটেম, অবস্থান) পরিসংখ্যান সংশোধন পারে কিন্তু আপনার EffectiveStatsকারণ বুঝতে প্রয়োজন হত না StatModifiersহায় এই বিষয়গুলি কী ছিল এবং কোন পরিসংখ্যানগুলিতে তাদের কী প্রভাব ফেলবে এবং কী ধরনের হবে তা পরিচালনা করুন। দ্যStatModifierবিভিন্ন জিনিসগুলির জন্য একটি ইন্টারফেস হতে পারে এবং "আমি কি জোনে আছি", "ওষুধ কখন বন্ধ হয়ে যায়" ইত্যাদি ইত্যাদির মতো জিনিসগুলি জানতে পারে ... তবে অন্য কোনও বস্তুকেও এ জাতীয় জিনিস জানাতে হবে না। এখনই এটি কোন স্ট্যাটাসে এবং কীভাবে সংশোধিত হয়েছে তা কেবল বলা দরকার। আরও ভাল StatModifierকেবল Statsঅন্যটির উপর ভিত্তি করে নতুন পরিবর্তনযোগ্য উত্পাদনের কোনও পদ্ধতি প্রকাশ Statsকরতে পারে যা ভিন্ন হবে কারণ এটি যথাযথভাবে পরিবর্তিত হয়েছিল। তারপরে আপনি এর মতো কিছু করতে পারেন currentStats = statModifier2.modify(statModifier1.modify(baseStats))এবং সমস্ত Statsঅপরিবর্তনীয় হতে পারে। আমি এমনকি কোডটিও দেইনি, আমি সম্ভবত সমস্ত সংশোধনকারীদের লুপ করব এবং প্রতিটি পূর্ববর্তী সংশোধকগুলির ফলাফলটিতে প্রয়োগ করব baseStats

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