অবজেক্ট ওরিয়েন্টেড ভাষায়, কখন বস্তুগুলি নিজেরাই অপারেশন করে এবং কখন বস্তুগুলিতে অপারেশন করা উচিত?


11

ধরুন এখানে কোনও Pageশ্রেণি রয়েছে, যা কোনও পৃষ্ঠা রেন্ডারারের নির্দেশের একটি সেট উপস্থাপন করে। এবং ধরুন এখানে এমন কোনও Rendererশ্রেণি রয়েছে যা কীভাবে পর্দায় কোনও পৃষ্ঠা রেন্ডার করতে জানে। কোডটি দুটি ভিন্ন উপায়ে গঠন করা সম্ভব:

/*
 * 1) Page Uses Renderer internally,
 * or receives it explicitly
 */
$page->renderMe(); 
$page->renderMe($renderer); 

/*
 * 2) Page is passed to Renderer
 */
$renderer->renderPage($page);

প্রতিটি পদ্ধতির উপকারিতা এবং কনসগুলি কী কী? কখন ভালো হবে? অন্য কখন ভাল হবে?


পটভূমি

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

$pdf = new TCPDF();
$html = "some text";
$pdf->writeHTML($html);

বলুন আমি পৃষ্ঠার উপস্থাপনা তৈরি করতে চাই। আমি এমন একটি টেমপ্লেট তৈরি করতে পারি যা পিডিএফ পৃষ্ঠার স্নিপেটকে এমনভাবে রেন্ডার করার জন্য নির্দেশনা রাখে:

/*
 * A representation of the PDF page snippet:
 * a template directing how to render a specific PDF page snippet
 */
class PageSnippet
{    
    function runTemplate(TCPDF $pdf, array $data = null): void
    {
        $pdf->writeHTML($data['html']);
    }
}

/* To be used like so */
$pdf = new TCPDF();
$data['html'] = "some text";
$snippet = new PageSnippet();
$snippet->runTemplate($pdf, $data);

1) এখানে লক্ষ করুন যা আমার প্রথম কোড উদাহরণ হিসাবে $snippet নিজেই চলে । এছাড়া জানেন এবং সাথে পরিচিত হওয়া প্রয়োজন $pdf, এবং যে কোনো সঙ্গে $dataএটির জন্য কাজ করতে।

তবে, আমি এর PdfRendererমতো ক্লাস তৈরি করতে পারি :

class PdfRenderer
{
    /**@var TCPDF */
    protected $pdf;

    function __construct(TCPDF $pdf)
    {
        $this->pdf = $pdf;
    }

    function runTemplate(PageSnippet $template, array $data = null): void
    {
        $template->runTemplate($this->pdf, $data);
    }
}

এবং তারপরে আমার কোড এতে পরিণত হয়:

$renderer = new PdfRenderer(new TCPDF());
$renderer->runTemplate(new PageSnippet(), array('html' => 'some text'));

2) এখানে এটি $rendererগ্রহণের জন্য এটির জন্য প্রয়োজনীয় PageSnippetএবং যে কোনও $dataপ্রয়োজনীয়। এটি আমার দ্বিতীয় কোড উদাহরণের মতো।

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


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

7
@ ডেভিডআরনো আপনার স্থানগুলিকে ব্যবহার করুন ! :)
candied_orange

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

@ এরিক Eidদত, আপনি কি আপনার উত্তরটি মুছে ফেলতে পারছেন দয়া করে যেমন আমি এটি খুব ভাল "আউট অপশন" উত্তর হিসাবে অনুভব করি।
ডেভিড আরনো

1
সলাইড নীতিগুলি বাদ দিয়ে আপনি জিআরএসপি , বিশেষত বিশেষজ্ঞের পক্ষ থেকে একবার দেখে নিতে পারেন । প্রশ্নটি এই দায়িত্বটি পালনের জন্য আপনার কাছে তথ্য রয়েছে যা?
ওনিসিমাসউবাউন্ড

উত্তর:


13

এই ওপর সম্পূর্ণভাবে নির্ভর করে আপনি কি মনে করেন OO যেমন পণ্য হয়

ওওপি = সলিডের জন্য, অপারেশনটি ক্লাসের একক দায়িত্বের অংশ হলে এটি ক্লাসের অংশ হওয়া উচিত।

ওও = ভার্চুয়াল প্রেরণ / পলিমারফিজমের জন্য, ক্রিয়াকলাপে প্রেরণ করা উচিত হলে অপারেশনটি বস্তুর অংশ হওয়া উচিত, অর্থাত্ যদি এটি একটি ইন্টারফেসের মাধ্যমে ডাকা হয়।

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

ওও = "আমি সাবলীল ইন্টারফেস পছন্দ করি" এর জন্য, প্রশ্নটি হ'ল কোন রূপটি আরও স্বাভাবিকভাবে পড়ে।

ওও = মডেলিং রিয়েল-ওয়ার্ল্ড সত্তার জন্য, কোন আসল-বিশ্ব সত্তা এই ক্রিয়াকলাপটি সম্পাদন করে?


এই সমস্ত দৃষ্টিকোণ সাধারণত বিচ্ছিন্নভাবে ভুল। তবে কখনও কখনও এর মধ্যে এক বা একাধিক দৃষ্টিভঙ্গি কোনও ডিজাইনের সিদ্ধান্তে পৌঁছাতে সহায়ক হয়।

যেমন পলিমারফিজম দৃষ্টিকোণ ব্যবহার করে: আপনার যদি বিভিন্ন রেন্ডারিং কৌশল থাকে (যেমন বিভিন্ন আউটপুট ফর্ম্যাট, বা বিভিন্ন রেন্ডারিং ইঞ্জিন), তবে $renderer->render($page)প্রচুর অর্থবোধ করে। তবে আপনার যদি বিভিন্ন পৃষ্ঠা ধরণের থাকে যা আলাদাভাবে রেন্ডার করা উচিত, $page->render()তবে আরও ভাল better যদি আউটপুট পৃষ্ঠার প্রকার এবং রেন্ডারিং কৌশল উভয়ের উপর নির্ভর করে তবে আপনি দর্শনার্থীর প্যাটার্নের মাধ্যমে ডাবল প্রেরণ করতে পারেন।

ভুলে যাবেন না যে অনেক ভাষায়, ফাংশনগুলি পদ্ধতি হতে পারে না। একটি সাধারণ ফাংশন যেমন render($page)প্রায়শই একটি নিখুঁত সূক্ষ্ম (এবং আশ্চর্যজনকভাবে সহজ) সমাধান।


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

@ ক্যান্ডিওড অ্যারেঞ্জ এটি একটি ভাল বিষয়, তবে আমি আপনার যুক্তিটি এসআরপি-র অধীনে বুক করবো: এটি কীভাবে রেন্ডার করা হবে তা সিদ্ধান্ত নেওয়ার জন্য এটি পৃষ্ঠার মূলধন-আর দায়বদ্ধতা হবে, সম্ভবত কিছু প্রকার পলিমারফিক রেন্ডারিং কৌশল ব্যবহার করে।
আমন

আমি বুঝতে পারি যে $rendererকীভাবে রেন্ডার করতে হবে তা স্থির করতে চলেছি। যখন সবার সাথে $pageআলাপ হয় তখন যা $rendererরেন্ডার করা হয়। কিভাবে না। $pageকোন ধারণা কিভাবে হয়েছে। আমাকে এসআরপি সমস্যায় ফেলে?
candied_orange

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

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

2

অ্যালান কেয়ের মতে , বস্তুগুলি স্বয়ংসম্পূর্ণ, "প্রাপ্তবয়স্ক" এবং দায়িত্বশীল জীব। প্রাপ্তবয়স্করা জিনিসগুলি করে, সেগুলি চালিত হয় না। এটি হ'ল, আর্থিক লেনদেন নিজেকে সংরক্ষণের জন্য দায়বদ্ধ , পৃষ্ঠা নিজেই রেন্ডারিং ইত্যাদির জন্য দায়ী More আরও সংক্ষিপ্তভাবে বলতে গেলে ওওপিতে এনক্যাপসুলেশনই সবচেয়ে বড় বিষয়। বিশেষ করে, এটা বিখ্যাত Tell মাধ্যমে টেপা নীতি জিজ্ঞাসা করবেন না এবং জনসাধারণের নিন্দন (যে @CandiedOrange সব সময় :) উল্লেখ লেগেছে) getters এবং setters

অনুশীলনে এটি ফলাফল হিসাবে ডাটাবেস সুবিধা, রেন্ডারিং সুবিধা ইত্যাদির মতো তাদের কাজ করার জন্য সমস্ত প্রয়োজনীয় সংস্থান রাখে objects

সুতরাং আপনার উদাহরণ বিবেচনা করে, আমার ওওপি-সংস্করণটি নীচের মত দেখাচ্ছে:

class Page
{
    private $data;
    private $renderer;

    public function __construct(ICanRender $renderer, $data)
    {
        $this->renderer = $renderer;
        $this->data = $data;
    }

    public function render()
    {
        $this->renderer->render($this->data);
    }
}

আপনি যদি আগ্রহী হন তবে ডেভিড ওয়েস্ট তাঁর বই " অবজেক্ট থিংকিং" এর মূল ওওপি নীতিগুলি সম্পর্কে কথা বলেছেন ।


1
কথায় কথায় বলতে গেলে, yearsতিহাসিক আগ্রহের কারণে 15 বছর আগে, কেউ সফ্টওয়্যার বিকাশের সাথে কিছু করার বিষয়ে কী বলেছে তা কে যত্ন করে?
ডেভিড আরনো

1
" আমি লক্ষ্য করি কোন ব্যক্তি যিনি অবজেক্ট-ওরিয়েন্টেড ধারণাটি আবিষ্কার করেছিলেন তিনি কী কী জিনিস সম্পর্কে বলেছিলেন। " কেন? আপনার যুক্তিগুলিতে "কর্তৃত্বের কাছে আবেদন" ত্রুটিগুলি ব্যবহারে আপনাকে ঝুঁকানো ছাড়াও, কোনও শব্দ উদ্ভাবকের 15 বছরের পরে এই শব্দটির প্রয়োগ সম্পর্কে কী ধারণা বহন করতে পারে?
ডেভিড আরনো

2
@ জাপাডলো: বার্তাটি পৃষ্ঠা থেকে রেন্ডারারের কাছে দেওয়া এবং অন্য কোনও উপায়ে নয় বলে আপনি কোনও যুক্তি উপস্থাপন করেন না। তারা উভয় অবজেক্ট, এবং তাই উভয় প্রাপ্তবয়স্ক, তাই না?
জ্যাকবিবি

1
" কর্তৃত্বের মিথ্যাচারের আবেদন এখানে প্রয়োগ করা যায় না ..." " সুতরাং আপনার ধারণার মধ্যে ওওপিকে উপস্থাপন করা এমন ধারণাগুলির সেটটি আসলে ভুল [কারণ এটি মূল সংজ্ঞাটির একটি বিকৃতি] "। আমি এটি গ্রহণ করি আপনি জানেন না কর্তৃপক্ষের মিথ্যাচারের আবেদন কী? ক্লু: আপনি এখানে একটি ব্যবহার করেছেন। :)
ডেভিড আরনো

1
@ ডেভিড আরনো সুতরাং, কর্তৃপক্ষের কাছে সমস্ত আপিল কি ভুল? আপনি কি "আমার মতামতের আবেদন করবেন?" যখনই কেউ আঙ্কেল ববিবাদের উদ্ধৃতি দিয়ে থাকেন, আপনি কি কর্তৃপক্ষের কাছে আবেদন করার অভিযোগ করবেন? জাপাদিও একটি শ্রদ্ধেয় উত্স প্রদান করেছেন।আপনি দ্বিমত করতে পারেন, বা বিরোধী উত্স উদ্ধৃত করতে পারেন, তবে পুনরাবৃত্তি করে অভিযোগ করেছেন যে কেউ উদ্ধৃতি দিয়েছিলেন তা গঠনমূলক নয়।
ব্যবহারকারীর 499300

2

$page->renderMe();

এখানে আমরা pageনিজেকে রেন্ডারিংয়ের জন্য পুরোপুরি দায়বদ্ধ করছি। এটি কোনও নির্মাণকারীর মাধ্যমে রেন্ডার সরবরাহ করা হতে পারে বা এটির কার্যকারিতা অন্তর্নির্মিত থাকতে পারে।

আমি এখানে প্রথম কেসটিকে (একজন কনস্ট্রাক্টরের মাধ্যমে সরবরাহকারীর মাধ্যমে সরবরাহ করা) উপেক্ষা করব, কারণ এটি প্যারামিটার হিসাবে পাস করার মতো similar পরিবর্তে আমি তৈরি করা কার্যকারিতাটির পক্ষে মতামতগুলি দেখব।

প্রো এটি হ'ল এটি খুব উচ্চ স্তরের এনক্যাপসুলেশনের অনুমতি দেয়। পৃষ্ঠার সরাসরি তার অভ্যন্তরীণ অবস্থা সম্পর্কে কিছুই প্রকাশ করা দরকার। এটি কেবল নিজের উপস্থাপনের মাধ্যমে এটি প্রকাশ করে।

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

$page->renderMe($renderer);

এখানে, আমরা এখনও একটি পৃষ্ঠা নিজেকে রেন্ডার করতে সক্ষম হতে চাই তবে আমরা এটি একটি সহায়ক সাহায্যকারী সরবরাহ করে যা প্রকৃত রেন্ডারিং করতে পারে। দুটি পরিস্থিতি এখানে উত্থাপিত হতে পারে:

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

$renderer->renderPage($page);

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

এছাড়াও, আমরা একটি নতুন সমস্যা তৈরি করেছি: রেন্ডারার এখন পৃষ্ঠা ক্লাসে দৃ tight়ভাবে মিলিত হয়েছে। যখন আমরা একটি পৃষ্ঠায় কিছু আলাদা রেন্ডার করতে চাই তখন কী হয়?

কোনটি সেরা? এদের মাঝে কেউ ই না. তাদের সবার ত্রুটি আছে।


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

2

এই প্রশ্নের উত্তরটি দ্ব্যর্থহীন। এটিই $renderer->renderPage($page);সঠিক বাস্তবায়ন। আমরা কীভাবে এই উপসংহারে পৌঁছেছি তা বুঝতে, আমাদের এনক্যাপসুলেশন বুঝতে হবে।

পেজ কী? এটি এমন কোনও প্রদর্শনের প্রতিনিধিত্ব যা কেউ গ্রাস করবে। যে "কেউ" মানুষ বা বট হতে পারে। নোট করুন যে এটি Pageএকটি উপস্থাপনা, এবং প্রদর্শন নিজেই নয়। প্রতিনিধিত্ব না করে একটি উপস্থাপনা উপস্থিত আছে? একটি পৃষ্ঠা কি উপস্থাপনা ছাড়াই কিছু? উত্তর হ্যাঁ, প্রতিনিধিত্ব না করে একটি প্রতিনিধিত্ব থাকতে পারে। প্রতিনিধিত্ব করা একটি পরবর্তী পর্যায়ে।

একটি পৃষ্ঠা ছাড়া কোনও রেন্ডারার কী? কোনও রেডেন্ডার কোনও পৃষ্ঠা ছাড়াই রেন্ডার করতে পারে? না। সুতরাং কোনও রেন্ডারার ইন্টারফেসের renderPage($page);পদ্ধতির দরকার নেই ।

এর সাথে কী হয়েছে $page->renderMe($renderer);?

এটি renderMe($renderer)এখনও অভ্যন্তরীণ কল করতে হবে যে সত্য $renderer->renderPage($page);। এটি ডিমেটারের আইন লঙ্ঘন করে যা জানিয়েছে

প্রতিটি ইউনিটের অন্যান্য ইউনিট সম্পর্কে কেবল সীমিত জ্ঞান থাকা উচিত

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


উত্তর উত্তর

যদি আমি আপনার প্রশ্নটি সঠিক পেয়েছি তবে PageSnippetক্লাসটি কেবলমাত্র একটি পৃষ্ঠার স্নিপেটের সাথে সম্পর্কিত।

class PageSnippet
{    
    /** string */
    private $html;

    function __construct($data = ['html' => '']): void
    {
        $this->html = $data['html'];
    }

   public function getHtml()
   {
       return $this->html;
   }
}

PdfRenderer রেন্ডারিং সম্পর্কিত।

class PdfRenderer
{
    /**@var TCPDF */
    protected $pdf;

    function __construct(TCPDF $pdf = new TCPDF())
    {
        $this->pdf = $pdf;
    }

    function runTemplate(string $html): void
    {
        $this->pdf->writeHTML($html);
    }
}

ক্লায়েন্টের ব্যবহার

$renderer = new PdfRenderer();
$snippet = new PageSnippet(['html' => '<html />']);
$renderer->runTemplate($snippet->getHtml());

কয়েকটি বিষয় বিবেচনা করুন:

  • এটির খারাপ অনুশীলনটি $dataএকটি সহযোগী অ্যারে হিসাবে ঘুরে বেড়াতে । এটি একটি শ্রেণীর উদাহরণ হতে হবে।
  • পৃষ্ঠার বিন্যাসটি অ্যারের htmlসম্পত্তির অভ্যন্তরে অন্তর্ভুক্ত রয়েছে $dataতা আপনার ডোমেনের জন্য সুনির্দিষ্ট বিবরণ এবং PageSnippetএই বিবরণটি সম্পর্কে অবগত।

তবে, পৃষ্ঠাগুলি ছাড়াও, যদি আপনার ছবি, নিবন্ধ এবং ট্রিপটিচ থাকে? আপনার স্কিমে, একজন রেন্ডারারের তাদের সকলের সম্পর্কে জানতে হবে। এটা অনেক ফাঁস। চিন্তার জন্য শুধু খাবার।
user949300

@ user949300: ভাল যদি রেন্ডারারের ছবিগুলি রেন্ডার করতে সক্ষম হয় তবে অবশ্যই তাদের সম্পর্কে জানা দরকার।
জ্যাকবিবি

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

2
আপনাকে যে কোনও ক্ষেত্রে এসআরপি ভাঙতে / রুদ্ধ করতে হবে, কিন্তু যদি রেন্ডারারের অনেকগুলি বিভিন্ন জিনিস কীভাবে রেন্ডার করতে হয় তা জানতে প্রয়োজন, এটি সত্যই "অনেকগুলি দায়বদ্ধতা", এবং যদি সম্ভব হয় তবে এড়ানো উচিত।
user949300

1
আমি আপনার উত্তরটি পছন্দ করি তবে আমি এই ভাবতে প্ররোচিত হয়েছি যে Page$ রেন্ডারারের বিষয়ে অবহিত হওয়া অসম্ভব। আমি আমার প্রশ্নে কিছু কোড যুক্ত করেছি, PageSnippetক্লাস দেখুন। এটি কার্যকরভাবে একটি পৃষ্ঠা, তবে এটি কোনও প্রকারের রেফারেন্স না দিয়ে থাকতে পারে না $pdf, যা আসলে এই ক্ষেত্রে তৃতীয় পক্ষের পিডিএফ রেন্ডারার। .. তবে, আমি মনে করি যদিও আমি এমন একটি PageSnippetশ্রেণি তৈরি করতে পারি যা কেবল পিডিএফটিতে পাঠ্য নির্দেশাবলীর একটি অ্যারে রাখে এবং অন্য কোনও শ্রেণি সেই নির্দেশাবলী ব্যাখ্যা করতে পারে have এই ভাবে আমি ইনজেকশনের এড়াতে পারেন $pdfমধ্যে PageSnippet, অতিরিক্ত জটিলতা খরচে
ডেনিস

1

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

আপনার রাজ্যে Page"পৃষ্ঠা সরবরাহকারীর কাছে নির্দেশাবলীর একটি সেট" রয়েছে। আমি এরকম কিছু কল্পনা করি:

renderer.renderLine(x, y, w, h, Color.Black)
renderer.renderText(a, b, Font.Helvetica, Color.Black, "bla bla...")
etc...

সুতরাং এটি হবে $page->renderMe($renderer), যেহেতু পৃষ্ঠাটির রেন্ডারারের একটি রেফারেন্স প্রয়োজন

তবে বিকল্পভাবে রেন্ডারিং নির্দেশাবলী সরাসরি কলগুলির চেয়ে ডেটা স্ট্রাকচার হিসাবেও প্রকাশ করা যেতে পারে, যেমন।

[
  Line(x, y, w, h, Color.Black), 
  Text(a, b, Font.Helvetica, Color.Black, "bla bla...")
]

এক্ষেত্রে প্রকৃত রেন্ডারার পৃষ্ঠা থেকে এই ডেটা কাঠামোটি অর্জন করবে এবং সংশ্লিষ্ট রেন্ডারিং নির্দেশাবলী কার্যকর করে এটি প্রক্রিয়া করবে। যেমন একটি পদ্ধতির সাথে নির্ভরতাগুলি বিপরীত হবে - পৃষ্ঠাটি রেন্ডারারের সম্পর্কে জানার দরকার নেই, তবে রেন্ডারারের একটি পৃষ্ঠা সরবরাহ করা উচিত যা এটি পরে রেন্ডার করতে পারে। সুতরাং বিকল্প দুটি:$renderer->renderPage($page);

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

যদি আপনি সিদ্ধান্ত নিতে না পারেন, বা ভবিষ্যতে আপনার দৃষ্টিভঙ্গি পরিবর্তন হতে পারে বলে মনে করেন, আপনি সিদ্ধান্তের পিছনে কোনও কার্যের পিছনে আড়াল করতে পারেন:

renderPage($page, $renderer)

আমি একমাত্র পদ্ধতির সুপারিশ করব না $page->renderMe()কারণ এটি প্রস্তাব দেয় যে কোনও পৃষ্ঠায় কেবলমাত্র একক রেন্ডারার থাকতে পারে। তবে যদি আপনার একটি থাকে ScreenRendererএবং একটি যুক্ত হয় PrintRenderer? একই পৃষ্ঠা দুজনেই রেন্ডার হতে পারে।


EPUB বা এইচটিএমএল প্রসঙ্গে, পৃষ্ঠার ধারণাটি কোনও রেন্ডারার ছাড়া বিদ্যমান নেই।
mouviciel

1
@ মউভিচিয়েল: আমি নিশ্চিত না আপনি কী বোঝাতে চেয়েছেন তা আমি বুঝতে পেরেছি। নিশ্চয়ই আপনি এটির কোনও রেডিয়ার ছাড়াই কোনও HTML পৃষ্ঠা রাখতে পারেন? যেমন গুগল ক্রলারের প্রক্রিয়া পৃষ্ঠাগুলি তাদের রেন্ডারিং ছাড়াই।
জ্যাকবিবি

2
শব্দের পৃষ্ঠার একটি আলাদা ধারণা রয়েছে: যখন একটি এইচটিএমএল পৃষ্ঠা মুদ্রণের জন্য ফর্ম্যাট করা হয় তখন একটি পৃষ্ঠাবদ্ধকরণ প্রক্রিয়ার ফলাফল হতে পারে, যা সম্ভবত @ মউভিচিয়ালের মনে ছিল। যাইহোক, এই প্রশ্নে একটি pageস্পষ্টভাবে রেন্ডারারের জন্য একটি ইনপুট, আউটপুট নয়, এই ধারণায় স্পষ্টভাবে মানায় না।
ডক ব্রাউন

1

কঠিন ডি অংশ বলছেন

"বিমূর্ততা বিশদগুলির উপর নির্ভর করে না Details বিশদ বিমূর্তির উপর নির্ভর করে।"

সুতরাং, পৃষ্ঠা এবং রেন্ডারারের মধ্যে, যা স্থিতিশীল বিমূর্ততা হওয়ার সম্ভাবনা বেশি, পরিবর্তনের সম্ভাবনা কম, সম্ভবত কোনও ইন্টারফেসের প্রতিনিধিত্ব করে? বিপরীতে, "বিস্তারিত" কোনটি?

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

তবে এটি অবশ্যই আপনার নকশার উপর নির্ভর করে। পৃষ্ঠাটি বিমূর্ত হতে পারে, উদাহরণস্বরূপ <article>স্ট্যান্ডার্ড উপ-বিভাগগুলির সাথে এইচটিএমএল ট্যাগের সমতুল্য । এবং আপনার কাছে প্রচুর ভিন্ন ভিন্ন কাস্টম ব্যবসার প্রতিবেদন "উপস্থাপনকারী" রয়েছে। সেক্ষেত্রে রেন্ডারারের পৃষ্ঠার উপর নির্ভর করা উচিত।


0

আমি মনে করি বেশিরভাগ শ্রেণি দুটি বিভাগের যে কোনও একটিতে বিভক্ত হতে পারে:

  • ডেটা সম্বলিত ক্লাসগুলিতে (পরিবর্তনযোগ্য বা অপরিবর্তনীয় কোনও বিষয় নয়)

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

  • ক্লাসগুলি যে পরিষেবাগুলি সরবরাহ করে

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

আপনার উদাহরণ

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

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

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

উদাহরণস্বরূপ, আপনি ক্লাসের উভয় বাস্তবায়ন করতে পারেন তবে বিভিন্ন সেটিংস সহ MobileRendereraStandardRendererRenderer

সুতরাং হিসাবে Pageতথ্য ধারণ করে এবং মূক রাখতে হবে, এক্ষেত্রে পরিষ্কার সমাধান পাস হবে Pageএকটি করতে Renderer:

$renderer->renderPage($page)

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