3

つまり、基本的に私は手続き型コーディングからOOPへと飛躍しています。私はOOPの原則を実装しようとしていますが、実際にはオブジェクトを使用して手続き型スタイルを記述しているだけで、しつこい感じがします。

つまり、パイプ/椅子/プリンターなどのリストがあるとすると、それらはすべて、単一のテーブルデータベースに製品としてリストされています。タイプに応じてリスト全体とアイテムを表示するWebアプリを構築する必要があります。OOPとそのパラダイムの「正しい」使用に重点が置かれています。

次のようにするだけで何か問題がありますか?

     CLass Show
     {

      public function showALL(){
      $prep = "SELECT * FROM myProducts";
      $q = $this->db-> prepare($prep);     
      $q->execute();
      while ($row = $q->fetch()) 
          {
            echo "bla bla bla some arranged display".$row['something']       
          }
      }

そして単に

$sth = new show();
$sth->showAll();

また、次のようなより具体的な表示方法を実装します。

showSpecificProduct($ id)->($ idは、ユーザーがリンクの1つをクリックすると言うと、$ _ GETを介して渡され、基本的には次のような個別のproduct.phpファイルが作成されます。

include('show.class.php');
$sth = new show();
$sth->showSpecificProduct($id);

showSpecificProduct()は、選択クエリと表示用のHTMLの出力の両方を実行します。

簡単に言うと、私はそれについて大丈夫ですか、それともクラスとオブジェクトを使用して手続き型コーディングを行っているだけですか。また、私が間違っている場合にそれを解決するためのアイデア/ヒントなどはありますか?

4

5 に答える 5

2

より適切なのは、リポジトリ パターンを実装することです。インターフェースの例は次のとおりです。

interface ProductRepository
{
    public function find($id);

    public function fetchAll();
}

次に、このインターフェースの具体的な実装を作成します

class DbProductRepository implements ProductRepsoitory
{
    private $db;

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

    public function find($id)
    {
        // prepare execute SQL statement
        // Fetch result
        // return result
    }

    public function fetchAll()
    {
        // etc
    }
}

echo一般に、メソッドまたは関数から直接取得することはお勧めできません。メソッドが適切なオブジェクト/配列/何でも返し、それらの結果を消費するようにします。

于 2011-09-22T23:19:52.317 に答える
2

@Phil と @Drew によって説明されたモデル プラクティスと同様に、ビジネス、データ、およびビュー レイヤーを分離することをお勧めします。

実装で拡張する必要がある非常に単純なバージョンを含めましたが、アイデアは、Db 選択を出力から分離し、コントローラーで 2 つをほぼ「結合」することです。

class ProductController
{
    public $view;

    public function __construct() {
        $this->view = new View;
    }

    public function indexAction() {
        $model = new DbProductRepository;
        $products = $model->fetchAll();

        $this->view->products = $products;
        $this->view->render('index', 'product');
    }
}

class View
{
    protected $_variables = array();        

    public function __get($name) {
        return isset($this->_variables['get']) ? $this->_variables['get'] : null;
    }

    public function __set($name, $value) {
        $this->_variables[$name] = $value;
    }

    public function render($action, $controller) {
        require_once '/path/to/views/' . $controller . '/' . $action . '.php';
    }
}

// in /path/to/views/product/index.php
foreach ($this->products as $product) {
    echo "Product ID {$product['id']} - {$product['name']} - {$product['cost']}<br />\n";
}
于 2011-09-22T23:36:17.673 に答える
1

上記で説明しているシナリオは、MVCの良い候補のようです。

あなたの場合、厳密にデータにアクセスするためのクラスを作成し (製品カテゴリまたは特定の製品の選択を行う)、別のファイル (ビュー) に出力を取得して表示させます。

次のようになります。

class Product_Model {
    public function find($prodId) { ... }
    public function fetchAll($category = '') { ... }
    public function search($string) { ... }
}

次に、別の場所で次のことができます。

$products = new Product_Model();
$list = $products->fetchAll(37); // get all from category 37

// in true MVC, you would have a view that you would assign the list to
// $view->list = $list;

foreach($ilst as $product) {
    echo "Product ID {$product['id']} - {$product['name']} - {$product['cost']}<br />\n";
}

MVC の基本原則は、データ ソース (データベースなど) からのデータを表す単純なオブジェクトであるモデル クラスを使用することです。データベースからデータ オブジェクトへ、またはデータ オブジェクトからデータをマップするマッパーがある場合があります。次に、コントローラーはモデル クラスからデータを取得し、その情報をビューに送信します。ビューで実際のプレゼンテーションが処理されます。コントローラーにビュー ロジック (html/javascript) を含めることは望ましくありません。コントローラーからデータを直接操作することも同じです。

于 2011-09-22T23:21:53.703 に答える
1

まず、クラスのオートローディングを調べます。この方法では、使用する各クラスを含める必要はありません。それを使用するだけで、オートローダーが含める適切なファイルを見つけてくれます。

http://php.net/manual/en/language.oop5.autoload.php

各クラスは単一の責任を持つ必要があります。データベースに接続し、一部のユーザー データを変更する単一のクラスはありません。代わりに、ユーザー クラスに渡すデータベース クラスがあり、ユーザー クラスはデータベース クラスを使用してデータベースにアクセスします。また、各関数は単一の責任を持つ必要があります。関数名に「and」を入れたいという衝動に駆られるべきではありません。

あるオブジェクトが別のオブジェクトのプロパティを認識することは望ましくありません。これにより、あるクラスに変更を加えると、別のクラスに変更を加える必要が生じ、最終的には変更が難しくなります。プロパティは、オブジェクトによる内部使用のためのものでなければなりません。

クラスを書き始める前に、まずそれをどのように使いたいかを考えるべきです (テスト駆動開発を参照してください)。使用中にコードをどのように表示したいですか?

$user = new User($db_object);
$user->load($id);
$user->setName($new_name);
$user->save();

どのように使用できるようにしたいかがわかったので、正しい方法でコーディングするのははるかに簡単です。

機会があれば、アジャイルの原則を研究してください。

于 2011-09-22T23:30:01.197 に答える
0

OOP は、実際の概念オブジェクトに対応するソフトウェア オブジェクトを持つことを目的としているため、通常、クラス名は名詞にする必要があります。クラス メンバー関数は通常、動詞、つまり、オブジェクトに対して実行できるアクションです。

あなたの例では、 show は奇妙なクラス名です。これを行うより一般的な方法は、show() または list() と呼ばれるメンバー関数を持つ ProductViewer のようなクラスを使用することです。また、特定の製品タイプのカスタム ビューなどの特殊な機能を取得する方法として、サブクラスを使用することもできます。

于 2011-09-22T23:22:51.687 に答える