ডায়ামিক_কাস্ট ব্যবহার এড়াতে সঠিক নকশা?


9

কিছু গবেষণা করার পরে আমি প্রায়শই মুখোমুখি হওয়া সমস্যার সমাধান করার সহজ উদাহরণ খুঁজে পাচ্ছি না।

আসুন আমি বলি যে আমি একটি ছোট অ্যাপ্লিকেশন তৈরি করতে চাই যেখানে আমি Squareগুলি, Circleগুলি এবং অন্যান্য আকার তৈরি করতে পারি , তাদের একটি স্ক্রিনে প্রদর্শন করতে পারি, তাদের বৈশিষ্ট্যগুলি নির্বাচনের পরে সংশোধন করতে পারি এবং তারপরে তার সমস্ত ঘেরগুলি গণনা করি।

আমি মডেল ক্লাসটি এইভাবে করতাম:

class AbstractShape
{
public :
    typedef enum{
        SQUARE = 0,
        CIRCLE,
    } SHAPE_TYPE;

    AbstractShape(SHAPE_TYPE type):m_type(type){}
    virtual ~AbstractShape();

    virtual float computePerimeter() const = 0;

    SHAPE_TYPE getType() const{return m_type;}
protected :
    const SHAPE_TYPE  m_type;
};

class Square : public AbstractShape
{
public:
    Square():AbstractShape(SQUARE){}
    ~Square();

    void setWidth(float w){m_width = w;}
    float getWidth() const{return m_width;}

    float computePerimeter() const{
        return m_width*4;
    }

private :
    float m_width;
};

class Circle : public AbstractShape
{
public:
    Circle():AbstractShape(CIRCLE){}
    ~Circle();

    void setRadius(float w){m_radius = w;}
    float getRadius() const{return m_radius;}

    float computePerimeter() const{
        return 2*M_PI*m_radius;
    }

private :
    float m_radius;
};

(কল্পনা করুন যে আমার আকারের আরও ক্লাস রয়েছে: ত্রিভুজ, হেক্সাগন, প্রতিবারের সাথে তাদের প্রোপারার ভেরিয়েবল এবং সম্পর্কিত গেটর এবং সেটার। আমি যে সমস্যার মুখোমুখি হয়েছিলাম তার 8 টি সাবক্লাস ছিল তবে উদাহরণের জন্য আমি 2 এ থামলাম)

আমার কাছে এখন একটি ShapeManager, তাত্ক্ষণিকভাবে এবং একটি অ্যারেতে সমস্ত আকার সংরক্ষণ করে:

class ShapeManager
{
public:
    ShapeManager();
    ~ShapeManager();

    void addShape(AbstractShape* shape){
        m_shapes.push_back(shape);
    }

    float computeShapePerimeter(int shapeIndex){
        return m_shapes[shapeIndex]->computePerimeter();
    }


private :
    std::vector<AbstractShape*> m_shapes;
};

সবশেষে, প্রতিটি ধরণের আকারের জন্য প্রতিটি প্যারামিটার পরিবর্তন করতে আমার স্পিনবক্সগুলির সাথে একটি ভিউ রয়েছে। উদাহরণস্বরূপ, আমি যখন স্ক্রিনে একটি বর্গক্ষেত্রটি নির্বাচন করি তখন প্যারামিটার উইজেটটি কেবলমাত্র Squareসম্পর্কিত সম্পর্কযুক্ত প্যারামিটারগুলি (ধন্যবাদ ধন্যবাদ AbstractShape::getType()) প্রদর্শন করে এবং স্কোয়ারের প্রস্থ পরিবর্তন করার প্রস্তাব দেয়। এটি করার জন্য আমার একটি ফাংশন প্রয়োজন যা আমাকে প্রস্থটি সংশোধন করার অনুমতি দেয় ShapeManagerএবং আমি এটি এইভাবে করি:

void ShapeManager::changeSquareWidth(int shapeIndex, float width){
   Square* square = dynamic_cast<Square*>(m_shapes[shapeIndex]);
   assert(square);
   square->setWidth(width);
}

আমার কাছে থাকা প্রতিটি সাবক্লাস ভেরিয়েবলের জন্য আমাকে ব্যবহার dynamic_castএবং গিটার / সেটার দম্পতি বাস্তবায়নের জন্য কী আরও ভাল নকশা ShapeManagerরয়েছে? আমি ইতিমধ্যে টেমপ্লেট ব্যবহার করার চেষ্টা করেছি কিন্তু ব্যর্থ হয়েছি ।


সমস্যা আমি সম্মুখীন করছি আকার সঙ্গে কিন্তু সত্যিই নয় বিভিন্ন Jobগুলি : (প্রাক্তন একটি 3D প্রিন্টার জন্য PrintPatternInZoneJob, TakePhotoOfZoneইত্যাদি) সঙ্গে AbstractJobতাদের বেস শ্রেণী হিসেবে। ভার্চুয়াল পদ্ধতিটি execute()এবং না getPerimeter()আমাকে কেবলমাত্র কংক্রিটের ব্যবহারের প্রয়োজন হ'ল কোনও কাজের প্রয়োজনীয় নির্দিষ্ট তথ্য পূরণ করা :

  • PrintPatternInZone মুদ্রণের জন্য পয়েন্টগুলির তালিকা, জোনটির অবস্থান, তাপমাত্রার মতো কিছু মুদ্রণ পরামিতি প্রয়োজন needs

  • TakePhotoOfZone কোন জোনটি ফটো তোলা দরকার, যেখানে ছবিটি সংরক্ষণ করা হবে সেই পথ, মাত্রা ইত্যাদি

আমি যখন তখন কল করব execute(), তখন জবসরা তাদের করা কর্মটি অনুধাবন করার জন্য তাদের নির্দিষ্ট তথ্য ব্যবহার করবে।

যখনই আমি এই তথ্যগুলি পূরণ করি বা প্রদর্শন করি (তখন যদি একটি TakePhotoOfZone Jobনির্বাচিত হয়, একটি উইজেট অঞ্চল, পথ এবং মাত্রা পরামিতি প্রদর্শন করবে এবং সংশোধন করবে ) তখনই আমাকে জবের কংক্রিট ধরণের ব্যবহার করার প্রয়োজন হয়

Jobগুলি তারপর একটি তালিকা পুরা হয় Jobগুলি যা প্রথম চাকরি নিতে, এটা executes (কল করে AbstractJob::execute()), পরবর্তী তালিকা শেষ না হওয়া পর্যন্ত এবং উপর, চলে যায়। (এই কারণেই আমি উত্তরাধিকার ব্যবহার করি)।

বিভিন্ন ধরণের প্যারামিটার সংরক্ষণ করতে আমি এটি ব্যবহার করি JsonObject:

  • সুবিধাগুলি: যে কোনও কাজের জন্য একই কাঠামো, পরামিতিগুলি সেট করা বা পড়ার সময় কোনও গতিশীল_কাস্ট নয়

  • সমস্যা: পয়েন্টারগুলি সঞ্চয় করতে পারে না ( Patternবা Zone)

আপনি কি তথ্য সংরক্ষণের আরও ভাল উপায় আছে?

তারপরে যখন আমাকে সেই ধরণের নির্দিষ্ট পরামিতিগুলি সংশোধন করতে হবে তখন আপনি কীভাবেJob এটি ব্যবহারের কংক্রিট প্রকারটি সংরক্ষণ করবেন ? JobManagerশুধুমাত্র একটি তালিকা আছে AbstractJob*


5
আপনার শেপ ম্যানেজারটি Godশ্বরের শ্রেণিতে পরিণত হবে বলে মনে হচ্ছে, কারণ এটিতে মূলত সমস্ত ধরণের আকারের জন্য সমস্ত সেটটার পদ্ধতি থাকবে।
এমারসন কার্ডোসো

আপনি কি "প্রপার্টি ব্যাগ" ডিজাইন বিবেচনা করেছেন? যেমন একটি এনাম বা স্ট্রিং changeValue(int shapeIndex, PropertyKey propkey, double numericalValue)কোথায় PropertyKeyথাকতে পারে এবং "প্রস্থ" (এটি নির্দেশ করে যে সেটারে কল প্রস্থের মান আপডেট করবে) অনুমোদিত মানগুলির মধ্যে একটি।
রওয়ং

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

আমি সম্পত্তি ব্যাগের নকশা বিবেচনা করেছি (যদিও আমি এর নামটি জানতাম না) তবে একটি জেএসএন অবজেক্ট ধারক সহ with এটি নিশ্চিতভাবে কাজ করতে পারে তবে আমি ভেবেছিলাম এটি একটি মার্জিত নকশা নয় এবং এর চেয়ে আরও ভাল বিকল্পের উপস্থিতি থাকতে পারে। কেন এটি ওও বিরোধী ধরণ হিসাবে বিবেচিত হয়?
এলেভেন

উদাহরণস্বরূপ, যদি আমি এটি পরে ব্যবহারের জন্য কোনও পয়েন্টার সঞ্চয় করতে চাই তবে আমি কীভাবে করব?
এলেভেন

উত্তর:


10

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

সমস্যাটি

আপনার উদাহরণে, AbstractShapeশ্রেণীর একটি getType()পদ্ধতি রয়েছে যা মূলত কংক্রিটের ধরণটি সনাক্ত করে। এটি সাধারণত এমন একটি চিহ্ন যা আপনার কাছে ভাল বিমূর্ততা নেই। বিমূর্ত করার পুরো বিন্দু, সর্বোপরি, কংক্রিটের ধরণের বিশদ সম্পর্কে যত্ন নিতে হবে না।

এছাড়াও, আপনি যদি এটির সাথে পরিচিত না হন তবে আপনার খোলা / বন্ধ নীতিটি পড়তে হবে। এটি প্রায়শই একটি আকারের উদাহরণ দিয়ে ব্যাখ্যা করা হয়, যাতে আপনি ঠিক ঘরে বসে থাকবেন।

দরকারী বিমূর্ততা

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

এটি সেই জায়গা যেখানে বিমূর্ততা বোঝায়। এই মডিউলটি কংক্রিট আকারগুলির সাথে নিজেকে উদ্বেগ দেয় না, এটি AbstractShapeকেবলমাত্র নির্ভর করে । একই কারণে, এটি getType()পদ্ধতির প্রয়োজন নেই - সুতরাং আপনার এটি থেকে মুক্তি পাওয়া উচিত।

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

কংক্রিটের ব্যবহার হ্রাস করা হচ্ছে

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

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

সুতরাং আপনি একটি বিমূর্তাকে সংজ্ঞায়িত করেন ShapeEditViewযার জন্য আপনি RectangleEditViewএবং CircleEditViewবাস্তবায়নগুলি যা প্রস্থ / উচ্চতা বা ব্যাসার্ধের জন্য প্রকৃত পাঠ্য বাক্স ধারণ করে।

প্রথম পদক্ষেপে আপনি RectangleEditViewযখনই তৈরি করেন তখন একটি তৈরি করতে পারেন Rectangleএবং তারপরে এটিতে রেখে দিতে পারেন std::map<AbstractShape*, AbstractShapeView*>। আপনি যদি ভিউগুলি যেমন প্রয়োজন তেমনই তৈরি করেন তবে তার পরিবর্তে আপনি নিম্নলিখিতটি করতে পারেন:

std::map<AbstractShape*, std::function<AbstractShapeView*()>> viewFactories;
// ...
auto rect = new Rectangle();
// ...
auto viewFactory = [rect]() { return new RectangleEditView(rect); }
viewFactories[rect] = viewFactory;

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

সঠিক বিকল্প নির্বাচন করা

খুব সাধারণ অ্যাপ্লিকেশনগুলিতে, আপনি দেখতে পাবেন যে একটি নোংরা (ingালাই) সমাধান কেবল আপনাকে আপনার বাক্সের জন্য সবচেয়ে বেশি ধাক্কা দেয়।

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

আকারগুলিতে পরিচালনা করে এমন অনেক যুক্তি থাকলে সাধারণত সমস্তভাবেই অর্থ প্রদান করা হয় এবং সঠিকভাবে আকারটি আপনার আবেদনের বিশদ is


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

আপনি পৃথক তালিকা রাখা চাই না, তাহলে আপনি একটি viewFactory চেয়ে বরং একটি viewSelector ব্যবহার করতে পারেন: [rect, rectView]() { rectView.bind(rect); return rectView; }। যাইহোক, অবশ্যই এটি উপস্থাপনা মডিউলে করা উচিত, উদাহরণস্বরূপ একটি রেক্টাঙ্গেলক্রিটেড এভেন্টহ্যান্ডলারে।
দ্বিগুণ

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

2

একটি উপায় হ'ল নির্দিষ্ট ধরণের কাস্টিং এড়ানোর জন্য জিনিসগুলিকে আরও সাধারণ করা ।

আপনি বেস শ্রেণিতে " মাত্রা " ভাসমান বৈশিষ্ট্যের একটি বেসিক গেটর / সেটার বাস্তবায়ন করতে পারেন , যা সম্পত্তি নামের জন্য আ নির্দিষ্ট কীয়ের উপর ভিত্তি করে মানচিত্রে একটি মান সেট করে। নীচে উদাহরণ:

class AbstractShape
{
public :
    typedef enum{
        SQUARE = 0,
        CIRCLE,
    } SHAPE_TYPE;

    AbstractShape(SHAPE_TYPE type):m_type(type){}
    virtual ~AbstractShape();

    virtual float computePerimeter() const = 0;

    void setDimension(const std::string& name, float v){ m_dimensions[name] = v; }
    float getDimension() const{ return m_dimensions[name]; }

    SHAPE_TYPE getType() const{return m_type;}

protected :
    const SHAPE_TYPE  m_type;
    std::map<std::string, float> m_dimensions;
};

তারপরে, আপনার পরিচালক শ্রেণিতে আপনাকে নীচের মতো কেবল একটি ফাংশন প্রয়োগ করতে হবে:

void ShapeManager::changeShapeDimension(const int shapeIndex, const std::string& dimension, float value){
   m_shapes[shapeIndex]->setDimension(name, value);
}

ভিউয়ের মধ্যে ব্যবহারের উদাহরণ:

ShapeManager shapeManager;

shapeManager.addShape(new Circle());
shapeManager.changeShapeDimension(0, "RADIUS", 5.678f);
float circlePerimeter = shapeManager.computeShapePerimeter(0);

shapeManager.addShape(new Square());
shapeManager.changeShapeDimension(1, "WIDTH", 2.345f);
float squarePerimeter = shapeManager.computeShapePerimeter(1);

আরেকটি পরামর্শ:

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

  • একটি স্কোয়ার এবং একটি স্কয়ারএডিটভিউ ইনস্ট্যান্ট করুন;
  • স্কয়ার উদাহরণটি স্কয়ারএডিটভিউ অবজেক্টে পাস করুন;
  • (alচ্ছিক) শেপম্যানেজারের পরিবর্তে আপনার মূল দৃষ্টিভঙ্গিতে আপনি এখনও আকারগুলির একটি তালিকা রাখতে পারেন;
  • স্কয়ারএডিটভিউয়ের মধ্যে আপনি একটি স্কোয়ারের রেফারেন্স রাখেন; এটি অবজেক্টগুলি সম্পাদনার জন্য castালাইয়ের প্রয়োজনীয়তা দূর করবে।

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

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

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

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

1
... আপনি ইতিমধ্যে এই সমস্যায় পড়েছেন। কোনও পরিচালকের পক্ষে কোনও আকারের মাত্রা পরিবর্তনের বিষয়টি কেন পৃথিবীতে বোঝা যাবে? কোনও পরিচালক কেন কোনও আকারের ঘের গণনা করবেন? আপনি যদি তা বুঝতে না পেরেছেন তবে আমি "অন্য একটি পরামর্শ" পছন্দ করি।
ডঙ্ক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.