sql >> データベース >  >> RDS >> Mysql

計算をコードまたはデータベースに保存しますか?

    評価は悪です

    まず第一に:eval()を使用しないでください 正当な理由がない限り。 そして正当な理由はありません

    最悪の場合、eval() アプリケーションがインジェクション攻撃に対して脆弱になり、また非常に遅くなります。少し調べてみると、evalが大きなノーノーである理由がたくさん明らかになっています。

    計算コードをデータベースに保存しないでください

    そうして、PHPから別の言語に切り替えたい場合でも、データベースにはPHPコードがあります。言語の移行が非常に難しくなります。アプリケーションのできるだけ多くの部分をできるだけ独立させるように常に努力する必要があります。

    この場合、使用する言語をデータベースに緊密に結合します。それは悪い習慣です。

    また、データベースから計算を実行する唯一の可能性は、それらを評価するか(これは悪いです。上記を参照)、文字列操作または正規表現を使用して文字列を分解することです。これにより、不要な作業が発生します。

    それはすべて戦略 に関するものです

    問題を解決するには、必要な計算に応じてコードを実行する必要があります。これは、switch-case-statementsまたはif-statementsのいずれかを使用して実行できます。しかし、それはあまりエレガントな解決策でもありません。将来計算する前に他の操作を実行するか、機能を拡張する必要があると想像してください。すべてのケースまたはifステートメントを更新する必要があります。

    戦略パターン と呼ばれる優れたデザインパターンがあります。 。戦略パターンは、1つのユースケースを異なる方法で処理できる場合に問題を解決します。これは、おそらくあなたが望むものです。

    何かを計算したい(ユースケース)と、それにはさまざまな計算タイプがあります(さまざまな戦略)

    仕組み

    戦略パターンを実装するには、基本的に3つのものが必要です。

    • 戦略を注入するクラス。これは基本的に、戦略タスクのラッパーです。
    • 戦略によって実装されるインターフェース
    • あなたの戦略

    インターフェースは次のようになります:

    <?php
    interface CalculatableInterface {
        
        public function calculate();
    
    }
    

    インターフェイスは、すべての戦略が実際に計算を実行するためのメソッドを提供することを確認します。特別なことは何もありません。

    次に、計算演算子をコンストラクター引数として受け取り、それらをプロパティに格納する基本クラスが必要になる場合があります。

    <?php
    abstract class Calculatable {
    
        protected $valueA;
        protected $valueB;
    
        public function __construct($valueA, $valueB)
        {
            $this->valueA = $valueA;
            $this->valueB = $valueB;
        }
    
    }
    

    今、それは深刻になっています。戦略を実行しています。

    <?php
    class Division extends Calculatable implements CalculatableInterface {
    
        public function calculate()
        {
            return ($this->valueB != 0) ? $this->valueA / $this->valueB : 'NA';
        }
    
    }
    
    class Percentage extends Calculatable implements CalculatableInterface {
    
        public function calculate()
        {
            return ($this->valueB != 0) ? (100 / $this->valueB) * $this->valueA : 'NA';
        }
    
    }
    

    もちろん、これを少しクリーンアップすることもできますが、ここで指摘したいのはクラス宣言です。

    Calculatableを拡張しています コンストラクターを介して算術演算を渡すことができるようにクラスを作成し、CalculatableInterfaceを実装しています。 これは私たちのクラスに次のように伝えます:「ねえ!あなたはcalculateメソッドを提供しなければなりません、私はあなたが望むかどうかは気にしません。

    これがパターンの不可欠な部分である理由は後でわかります。

    したがって、実際の算術演算の実際のコードを含む2つの具象クラスがあります。必要に応じて、表示どおりに簡単に変更できます。操作を追加するには、別のクラスを追加するだけです。

    次に、戦略を注入できるクラスを作成します。後で、このクラスのオブジェクトをインスタンス化して操作します。

    外観は次のとおりです。

    <?php 
    class Calculator {
    
        protected $calculatable;
    
        public function __construct( CalculatableInterface $calculatable )
        {
            $this->calculatable = $calculatable;
        }
    
        public function calculate()
        {
            return $this->calculatable->calculate();
        }
    
    }
    

    ここで最も重要な部分はコンストラクターです。ここで、インターフェイスの入力方法を確認してください。そうすることで、オブジェクトのみを注入できるようにします(依存性注入 )そのクラスがインターフェースを実装している 。ここで具体的なクラスを要求する必要はありません。それがここでの重要なポイントです。

    また、そこには計算方法があります。これは、calculateメソッドを実行するための戦略の単なるラッパーです。

    まとめ

    したがって、Calculatorのオブジェクトを作成する必要があります。 クラスを作成し、戦略クラスの1つのオブジェクト(算術演算のコードを含む)を渡します。

    <?php
    //The corresponding string is stored in your DB
    $calculatable = 'Division';
    
    $calc = new Calculator( new $calculatable(15, 100) );
    echo $calc->calculate();
    

    $calculatableに保存されている文字列を置き換えてみてください Percentageへ パーセンテージを計算するための操作が実行されることがわかります。

    結論

    戦略パターンにより、実行時にのみ具体化される動的タスクを操作するためのクリーンなインターフェイスを作成できました。データベースは、私たちがどのように計算するかを知る必要はなく、実際の計算機も知る必要はありません。確認する必要があるのは、インターフェースに対してコーディングすることだけです。 それは私たちが物事を計算できるようにする方法を提供します。



    1. Javaのすべてのデータベース挿入にPreparedStatementsを使用する必要がありますか?

    2. 照合の不正な組み合わせMySQLエラー

    3. PostgreSQLでピボットテーブルを作成する

    4. MySQLのINTERSECT