এমভিসিতে কীভাবে কোনও মডেল গঠন করা উচিত? [বন্ধ]


551

আমি কেবল এমভিসি কাঠামোর উপর উপলব্ধি পেয়েছি এবং প্রায়শই আমি ভাবছি মডেলটিতে কত কোড হওয়া উচিত। আমার কাছে ডেটা অ্যাক্সেস ক্লাসের ঝোঁক রয়েছে যার এই পদ্ধতিগুলি রয়েছে:

public function CheckUsername($connection, $username)
{
    try
    {
        $data = array();
        $data['Username'] = $username;

        //// SQL
        $sql = "SELECT Username FROM" . $this->usersTableName . " WHERE Username = :Username";

        //// Execute statement
        return $this->ExecuteObject($connection, $sql, $data);
    }
    catch(Exception $e)
    {
        throw $e;
    }
}

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

মডেল অবজেক্টের উপরের কোডের পাশাপাশি সমস্ত ডাটাবেস ম্যাপ করা বৈশিষ্ট্য থাকা উচিত বা সেই কোডটি আলাদা করা ঠিক আছে যা ডাটাবেস কাজ করে?

আমি কি চার স্তর রেখে শেষ করব?


133
আপনি কেবল আবার এড়াতে ব্যতিক্রমগুলি কেন ধরছেন?
বেইলি পার্কার

9
@ ইলিয়াস ভ্যান ওটেজেম: আপনি বিষয়টিটি মিস করেছেন। এই ক্ষেত্রে তাদের ধরা অর্থহীন।
করলি হরভাথ

4
@ ইলিয়াস ভ্যান ওটেজেম: হাহ? যদি এটি রিথ্রোর সাথে কাজ করে, তার অর্থ একটি উচ্চ স্তরটি ব্যতিক্রমটিকে ধরা দেয়। তবে যদি এটির একটি থাকে, তবে এটি সেই অর্থহীন পুনর্বিবেচনা ছাড়াই এটি ধরে ফেলতে পারে ... (যদি আপনি এখনও এটি না পান তবে দয়া করে একটি ছোট পরীক্ষার কোডটি উপহাস করুন)
করলি হরভাথ

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

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

উত্তর:


903

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

যে জিনিসটি আমি পরিষ্কার করতে হবে তা হ'ল: মডেলটি একটি স্তর

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

একটি মডেল কি নয়:

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

এটি কোনও অবজেক্ট-রিলেশনাল ম্যাপিং টেকনিক (ওআরএম) বা ডাটাবেস টেবিলগুলির বিমূর্ততা নয়। যে কেউ আপনাকে অন্যথায় বলে সে সম্ভবত অন্য একটি ব্র্যান্ড-নতুন ওআরএম বা একটি পুরো কাঠামো 'বিক্রয়' করার চেষ্টা করছে ।

একটি মডেল কি:

সঠিক MVC অভিযোজন মধ্যে, এম সব ডোমেন ব্যবসা লজিক রয়েছে এবং মডেল লেয়ার হয় বেশিরভাগ স্ট্রাকচার তিন ধরনের থেকে তৈরি:

  • ডোমেন অবজেক্টস

    একটি ডোমেন অবজেক্ট হ'ল যুক্তিযুক্ত ডোমেন তথ্যের একটি যৌক্তিক ধারক; এটি সাধারণত সমস্যা ডোমেন স্পেসে একটি যৌক্তিক সত্তাকে উপস্থাপন করে। সাধারণত ব্যবসায়িক যুক্তি হিসাবে পরিচিত ।

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

  • ডেটা ম্যাপার্স

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

  • সেবা

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

    এসিএল বাস্তবায়ন প্রশ্নে এই বিষয়ের সাথে সম্পর্কিত উত্তর রয়েছে - এটি কার্যকর হতে পারে।

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

  • এটি একক দায়িত্বের নীতিটি প্রয়োগ করতে সহায়তা করে (এসআরপি)
  • যুক্তি পরিবর্তিত হলে অতিরিক্ত 'উইগল রুম' সরবরাহ করে
  • নিয়ামকটিকে যতটা সম্ভব সহজ রাখে
  • আপনার যদি কোনও বাহ্যিক এপিআই দরকার হয় তবে একটি পরিষ্কার ব্লুপ্রিন্ট দেয়

 

কোনও মডেলের সাথে কীভাবে যোগাযোগ করবেন?

পূর্বশর্ত: ঘড়ি বক্তৃতা 'গ্লোবাল রাজ্য এবং Singletons " এবং " জিনিসের জন্য তাকান না! " ক্লিন কোড আলোচনা থেকে।

পরিষেবা দৃষ্টান্ত অ্যাক্সেস অর্জন

উভয় জন্য দেখুন এবং কন্ট্রোলার দৃষ্টান্ত (আপনি কি বলতে পেরেছিলাম: "UI 'তে স্তর") তে অ্যাক্সেস এই পরিষেবাগুলি, দুই সাধারণ পন্থা আছে হবে:

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

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

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

মডেল রাজ্যের পরিবর্তন

এখন আপনি নিয়ন্ত্রণকারীদের মধ্যে মডেল স্তর অ্যাক্সেস করতে পারেন, আপনার এগুলিকে আসলে ব্যবহার শুরু করা দরকার:

public function postLogin(Request $request)
{
    $email = $request->get('email');
    $identity = $this->identification->findIdentityByEmailAddress($email);
    $this->identification->loginWithPassword(
        $identity,
        $request->get('password')
    );
}

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

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

ব্যবহারকারীকে রাষ্ট্র-পরিবর্তন দেখাচ্ছে।

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

public function postLogin()
{
    $path = '/login';
    if ($this->identification->isUserLoggedIn()) {
        $path = '/dashboard';
    }
    return new RedirectResponse($path); 
}

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

উপস্থাপনা স্তরটি এখানে আসলে বর্ণিত হিসাবে যথেষ্ট বিস্তৃত হতে পারে: পিএইচপি-তে এমভিসি ভিউগুলি বোঝা

তবে আমি কেবল একটি REST এপিআই তৈরি করছি!

অবশ্যই, এমন পরিস্থিতি রয়েছে যখন এটি ওভারকিল হয়।

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

এমভিসি বিচ্ছেদ

এর অর্থ হ'ল, যখন আপনার উপস্থাপনা স্তরের যুক্তি অস্তিত্বের কাছাকাছি থাকে, তখন ব্যবহারিক পদ্ধতির মাধ্যমে এগুলিকে একক স্তর হিসাবে রাখা হয়। এটি মডেল স্তরের কিছু দিকও যথেষ্ট সরল করতে পারে।

এই পদ্ধতির ব্যবহার করে লগইন উদাহরণ (একটি এপিআই এর জন্য) এইভাবে লেখা যেতে পারে:

public function postLogin(Request $request)
{
    $email = $request->get('email');
    $data = [
        'status' => 'ok',
    ];
    try {
        $identity = $this->identification->findIdentityByEmailAddress($email);
        $token = $this->identification->loginWithPassword(
            $identity,
            $request->get('password')
        );
    } catch (FailedIdentification $exception) {
        $data = [
            'status' => 'error',
            'message' => 'Login failed!',
        ]
    }

    return new JsonResponse($data);
}

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

 

কিভাবে তৈরি করবেন মডেল?

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

একটি পরিষেবা পদ্ধতির উদাহরণ:

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

public function loginWithPassword(Identity $identity, string $password): string
{
    if ($identity->matchPassword($password) === false) {
        $this->logWrongPasswordNotice($identity, [
            'email' => $identity->getEmailAddress(),
            'key' => $password, // this is the wrong password
        ]);

        throw new PasswordMismatch;
    }

    $identity->setPassword($password);
    $this->updateIdentityOnUse($identity);
    $cookie = $this->createCookieIdentity($identity);

    $this->logger->info('login successful', [
        'input' => [
            'email' => $identity->getEmailAddress(),
        ],
        'user' => [
            'account' => $identity->getAccountId(),
            'identity' => $identity->getId(),
        ],
    ]);

    return $cookie->getToken();
}

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

private function changeIdentityStatus(Entity\Identity $identity, int $status)
{
    $identity->setStatus($status);
    $identity->setLastUsed(time());
    $mapper = $this->mapperFactory->create(Mapper\Identity::class);
    $mapper->store($identity);
}

ম্যাপার তৈরি করার উপায়

অধ্যবসায়ের একটি বিমূর্ততা বাস্তবায়নের জন্য, সবচেয়ে নমনীয় পন্থায় কাস্টম ডেটা ম্যাপার তৈরি করা হয় ।

ম্যাপার চিত্র

থেকে: পিওএএএ বই

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

কিছু অতিরিক্ত মন্তব্য:

  1. ডাটাবেস টেবিল এবং মডেল

    কখনও কখনও বৃহত্তর প্রকল্পগুলিতে ডাটাবেস টেবিল, ডোমেন অবজেক্ট এবং ম্যাপারের মধ্যে সরাসরি 1: 1: 1 সম্পর্ক থাকে তবে এটি আপনার প্রত্যাশার চেয়ে কম সাধারণ হতে পারে:

    • একটি একক ডোমেন অবজেক্ট দ্বারা ব্যবহৃত তথ্য বিভিন্ন টেবিল থেকে ম্যাপ করা যেতে পারে, যখন অবজেক্টের নিজেই ডাটাবেসে কোনও অধ্যবসায় নেই।

      উদাহরণ: আপনি যদি একটি মাসিক প্রতিবেদন তৈরি করে থাকেন। এটি বিভিন্ন টেবিলের থেকে তথ্য সংগ্রহ করবে, তবে MonthlyReportডাটাবেসে কোনও যাদুকরী টেবিল নেই ।

    • একটি একক ম্যাপার একাধিক টেবিলকে প্রভাবিত করতে পারে।

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

    • একক ডোমেন অবজেক্টের ডেটা একাধিক টেবিলের মধ্যে সংরক্ষণ করা হয়।

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

    • প্রতিটি ডোমেন অবজেক্টের জন্য একাধিক ম্যাপার থাকতে পারে

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

  2. একটি ভিউ কোনও টেম্পলেট নয়

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

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

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

  3. উত্তরের পুরানো সংস্করণটি কী?

    একমাত্র বড় পরিবর্তনটি হ'ল, পুরানো সংস্করণে যাকে মডেল বলা হয় , এটি আসলে একটি পরিষেবা । বাকি "লাইব্রেরির সাদৃশ্য" বেশ ভাল রাখে।

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

  4. দর্শন এবং নিয়ন্ত্রণকারী দৃষ্টান্তগুলির মধ্যে সম্পর্ক কী ?

    এমভিসি কাঠামো দুটি স্তর নিয়ে গঠিত: ইউআই এবং মডেল। ইউআই স্তরের প্রধান কাঠামো হল ভিউ এবং নিয়ামক।

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

    উদাহরণস্বরূপ, একটি খোলার নিবন্ধ উপস্থাপন করতে, আপনি \Application\Controller\Documentএবং ছিল \Application\View\Document। এটিতে ইউআই স্তরের সমস্ত মূল কার্যকারিতা থাকবে, যখন নিবন্ধগুলি নিয়ে কাজ করার বিষয়টি আসে (অবশ্যই আপনার কিছু এক্সএইচআর উপাদান থাকতে পারে যা নিবন্ধের সাথে সরাসরি সম্পর্কিত নয়)


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

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

3
সংক্ষিপ্ত সংস্করণ - মডেলগুলি হ'ল ডেটা স্ট্রাকচার
এডি বি

9
দেখেন যে তিনি এমভিসি আবিষ্কার করেছেন নিবন্ধটিতে কিছুটা যোগ্যতা থাকতে পারে।
এডি বি

3
... বা এমনকি ফাংশন একটি সেট। এমভিসি-র কোনও ওওপি স্টাইলে প্রয়োগ করা প্রয়োজন হয় না, যদিও এটি বেশিরভাগ ক্ষেত্রে সেভাবেই প্রয়োগ করা হয়। সর্বাধিক গুরুত্বপূর্ণ বিষয় স্তরগুলি পৃথক করা এবং সঠিক ডেটা এবং নিয়ন্ত্রণ প্রবাহ স্থাপন করা
hek2mgl

37

সবকিছু যে ব্যবসা লজিক একটি মডেল জন্যে কিনা এটা একটি ডাটাবেস ক্যোয়ারী, হিসাব, বিশ্রাম কল, ইত্যাদি হয়

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

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

class Database {
   protected $_conn;

   public function __construct($connection) {
       $this->_conn = $connection;
   }

   public function ExecuteObject($sql, $data) {
       // stuff
   }
}

abstract class Model {
   protected $_db;

   public function __construct(Database $db) {
       $this->_db = $db;
   }
}

class User extends Model {
   public function CheckUsername($username) {
       // ...
       $sql = "SELECT Username FROM" . $this->usersTableName . " WHERE ...";
       return $this->_db->ExecuteObject($sql, $data);
   }
}

$db = new Database($conn);
$model = new User($db);
$model->CheckUsername('foo');

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


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

10
-1: এটি সম্পূর্ণ ভুল হতেও দেখা যায়। মডেল কোনও টেবিলের জন্য বিমূর্ততা নয়।
tereško

1
Userশ্রেণী মূলত মডেল প্রসারিত, কিন্তু একটি বস্তু itsn't। ব্যবহারকারীর একটি অবজেক্ট হওয়া উচিত এবং এর মতো বৈশিষ্ট্য থাকতে হবে: আইডি, নাম ... আপনি Userক্লাস নিযুক্ত করছেন একটি সহায়ক।
টমসওয়ায়ার

1
আমি মনে করি আপনি এমভিসি বুঝতে পেরেছেন তবে ওওপ কী তা বুঝতে পারেন না। এই দৃশ্যে, যেমন আমি বলেছি, Userএকটি অবজেক্টের জন্য দাঁড়িয়েছে এবং এর ব্যবহারকারীর বৈশিষ্ট্য থাকতে হবে, পদ্ধতিগুলির মতো নয় CheckUsername, আপনি যদি নতুন Userঅবজেক্ট তৈরি করতে চান তবে আপনার কী করা উচিত ? new User($db)
টমসোয়ায়ার

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

20

ওয়েব- "এমভিসি" তে আপনি যা খুশি তাই করতে পারেন।

মূল ধারণা (1) মডেলটিকে ব্যবসায়ের যুক্তি হিসাবে বর্ণনা করেছে। এটি অ্যাপ্লিকেশনের স্থিতি উপস্থাপন করবে এবং কিছু ডেটা ধারাবাহিকতা প্রয়োগ করবে। এই পদ্ধতির প্রায়শই "ফ্যাট মডেল" হিসাবে বর্ণনা করা হয়।

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

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


8
লিঙ্কটি অবৈধ (404)
কিসলিক

1
এটি ওয়েবআর্কাইভ থেকে কাজ করে: web.archive.org/web/20101229204648/https://stackoverflow.com/…
টিউডর

6

আরো oftenly অ্যাপ্লিকেশন সবচেয়ে ডেটা, প্রদর্শন এবং প্রক্রিয়াকরণের অংশ থাকবে এবং আমরা শুধু অক্ষরে সমস্ত করা M, Vএবং C

মডেল ( M) -> অ্যাপ্লিকেশনের স্থিতিযুক্ত বৈশিষ্ট্যগুলি রয়েছে এবং এটি সম্পর্কে Vএবং কোনও কিছুই জানতে পারে না C

দেখুন ( V) -> অ্যাপ্লিকেশনটির জন্য বিন্যাস প্রদর্শন করছে এবং এটির উপর কীভাবে ডাইজেস্ট মডেলটি হবে তা সম্পর্কে জানেন এবং তা বিরক্ত করেন না C

কন্ট্রোলার ( C) ----> আবেদন অংশ প্রক্রিয়াকরণের এবং M এবং ভী মধ্যে তারের হিসাবে কাজ করে এবং এটি উভয় উপর নির্ভর করে M, Vঅসদৃশ Mএবং V

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


0

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

প্রতিটি টেবিলের নিজস্ব শ্রেণি থাকতে পারে এবং এর নির্দিষ্ট পদ্ধতি থাকতে পারে তবে প্রকৃতপক্ষে ডেটা পেতে এটি ডাটাবেস শ্রেণিকে এটি পরিচালনা করতে দেয়:

ফাইল Database.php

class Database {
    private static $connection;
    private static $current_query;
    ...

    public static function query($sql) {
        if (!self::$connection){
            self::open_connection();
        }
        self::$current_query = $sql;
        $result = mysql_query($sql,self::$connection);

        if (!$result){
            self::close_connection();
            // throw custom error
            // The query failed for some reason. here is query :: self::$current_query
            $error = new Error(2,"There is an Error in the query.\n<b>Query:</b>\n{$sql}\n");
            $error->handleError();
        }
        return $result;
    }
 ....

    public static function find_by_sql($sql){
        if (!is_string($sql))
            return false;

        $result_set = self::query($sql);
        $obj_arr = array();
        while ($row = self::fetch_array($result_set))
        {
            $obj_arr[] = self::instantiate($row);
        }
        return $obj_arr;
    }
}

টেবিল অবজেক্ট ক্লাস

class DomainPeer extends Database {

    public static function getDomainInfoList() {
        $sql = 'SELECT ';
        $sql .='d.`id`,';
        $sql .='d.`name`,';
        $sql .='d.`shortName`,';
        $sql .='d.`created_at`,';
        $sql .='d.`updated_at`,';
        $sql .='count(q.id) as queries ';
        $sql .='FROM `domains` d ';
        $sql .='LEFT JOIN queries q on q.domainId = d.id ';
        $sql .='GROUP BY d.id';
        return self::find_by_sql($sql);
    }

    ....
}

আমি আশা করি এই উদাহরণটি আপনাকে একটি ভাল কাঠামো তৈরি করতে সহায়তা করে।


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

আমি দেখেছি আমার উত্তর সম্পাদনার পরে কম এবং কম বোঝায় এবং সময় যত যায়। তবে এটি এখানেই থাকা উচিত
আইবু

2
Databaseউদাহরণস্বরূপ একটি বর্গ নয়। এটি ফাংশনগুলির জন্য কেবল একটি মোড়ক। এছাড়াও, কীভাবে আপনি কোনও অবজেক্ট ছাড়াই "টেবিল অবজেক্ট ক্লাস" রাখতে পারেন?
tereško

2
@ তেরেখো আমি আপনার অনেকগুলি পোস্ট পড়েছি এবং সেগুলি দুর্দান্ত। তবে, আমি কোথাও অধ্যয়নের জন্য কোনও পূর্ণ কাঠামো খুঁজে পাচ্ছি না। আপনি কি এমন একজনকে জানেন যে "এটি সঠিকভাবে কাজ করে"? বা কমপক্ষে একটি যা এটি আপনার এবং এখানে এসও তে অন্য কিছুকে পছন্দ করে বলে? ধন্যবাদ।
জননি

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