Mysql
 sql >> база данни >  >> RDS >> Mysql

Запазване на изчислението в код или база данни?

Eval е зло

Първо:не използвайте eval() освен ако няма основателна причина. И никога няма основателна причина .

в най-лошия случай eval() прави приложението ви уязвимо за атаки с инжектиране, а също така е много бавно. Малко проучване разкрива много причини, поради които eval е голямо не-не.

Не запазвайте кода си за изчисление в базата данни

Ако го направите и искате да преминете от PHP към друг език, пак ще имате PHP код във вашата база данни. Това прави наистина трудно мигрирането на езици. Винаги трябва да се стремите да направите възможно най-много части от приложението си.

В този случай трябва да свържете езика, който използвате, към базата данни. Това е лоша практика.

Също така единствената възможност да изпълните изчисленията си от базата данни би била да ги оцените (което е лошо, вижте по-горе) или да разглобите низа с низови операции или редовен израз, което причинява ненужни усилия.

Всичко е за Стратегия

За да решите проблема си, трябва да изпълните код в зависимост от това кое изчисление ви е необходимо. Това може да стане или с оператори switch-case или if. Но това също не е много елегантно решение. Представете си, че ще трябва да изпълните други операции, преди да изчислите в бъдеще, или да разширите функционалността. Ще трябва да актуализирате всичките си case или if-изявления.

Има хубав модел на дизайн, който се нарича Стратегически модел . Моделът на стратегията решава проблеми, когато един случай на употреба може да се обработва по различен начин, което вероятно е това, което искате.

Искате да изчислите нещо (случай на употреба) и има различни типове изчисления за него (различни стратегии)

Как работи

За да приложите модела на стратегията, вие по принцип се нуждаете от три неща.

  • Клас, в който инжектирате своите стратегии. Това е основно обвивка за вашите стратегически задачи.
  • Интерфейс, който ще бъде внедрен от вашите стратегии
  • Вашите стратегии

Вашият интерфейс може да изглежда така:

<?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 което казва на нашия клас:„Хей! Трябва да предоставите метод за изчисляване, не ме интересува дали искате или не.

Ще видим по-късно защо това е неразделна част от шаблона.

Така че имаме два конкретни класа, които съдържат действителния код за действителната аритметична операция. Ако някога ви се наложи, можете лесно да го промените, както виждате. За да добавите още операции, просто добавете друг клас.

Сега ще създадем клас, където нашите стратегии могат да бъдат инжектирани. По-късно ще създадете инстанция на обект от този клас и ще работите с него.

Ето как изглежда:

<?php 
class Calculator {

    protected $calculatable;

    public function __construct( CalculatableInterface $calculatable )
    {
        $this->calculatable = $calculatable;
    }

    public function calculate()
    {
        return $this->calculatable->calculate();
    }

}

Най-важната част тук е конструкторът. Вижте как въвеждаме и подсказваме нашия интерфейс тук. По този начин се уверяваме, че само обект може да бъде инжектиран (Инжектиране на зависимост ) чийто клас имплементира интерфейса . Тук не е нужно да изискваме конкретен клас. Това е решаващият момент тук.

Там също има метод за изчисляване. Това е просто обвивка за нашата стратегия за изпълнение на нейния метод за изчисляване.

Отваряме го

Така че сега просто трябва да създадем обект на нашия Calculator клас и предадете обект на един от нашите стратегически класове (които съдържат кода за аритметичните операции).

<?php
//The corresponding string is stored in your DB
$calculatable = 'Division';

$calc = new Calculator( new $calculatable(15, 100) );
echo $calc->calculate();

Опитайте да замените низа, съхранен в $calculatable до Percentage и виждате, че операцията за изчисляване на процента ще бъде изпълнена.

Заключение

Моделът на стратегията ви позволява да създадете чист интерфейс за работа с динамични задачи, които се правят конкретни само по време на изпълнение. Нито вашата база данни трябва да знае как изчисляваме нещата, нито действителният ви калкулатор. Единственото нещо, което трябва да сме сигурни, е да кодираме срещу интерфейс който предоставя метод, който ни позволява да изчисляваме нещата.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Python Mysql, команди не са синхронизирани; не можете да изпълните тази команда сега

  2. Подобряване на производителността на mysql LOAD DATA / mysqlimport?

  3. Филтрирайте MySQL резултат в Delphi

  4. Използване на NoSQL база данни през MySQL

  5. MySQL програма mysql_tzinfo_to_sql