Caso simple de programación funcional y orientada a objetos

Caso simple de programación funcional y orientada a objetos

Pionero del front-end de Crazy Technology House

Caso simple de programación funcional y orientada a objetos

Introducción


Permítanme presentarles brevemente la programación funcional y orientada a objetos.

Ambos son paradigmas de programación y difieren en la tecnología permitida y prohibida.

Hay lenguajes de programación que admiten un solo paradigma, como Haskell (puramente funcional).

También hay lenguajes que admiten múltiples paradigmas, como JavaScript. Puede utilizar JavaScript para escribir código orientado a objetos o código funcional, o incluso mezclar ambos.

Crear proyecto


Antes de profundizar en las diferencias entre estos dos paradigmas de programación, cree un proyecto de calculadora factorial.

Primero cree todos los archivos y carpetas que necesita de la siguiente manera:


$ mkdir func-vs-oop
$ cd ./func-vs-oop
$ cat index.html
$ cat functional.js
$ cat oop.js 

A continuación, cree un formulario simple en index.html.


<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
  <script src="functional.js" defer></script>
</head>
<body>
  <div class="container mt-5">
    <div class="container mt-3 mb-5 text-center">
      <h2>Functional vs OOP</h2>
    </div>
    <form id="factorial-form">
      <div class="form-group">
        <label for="factorial">Factorial</label>
        <input class="form-control" type="number" name="factorial" id="factorial" />
      </div>
      <button type="submit" class="btn btn-primary">Calculate</button>
    </form>
    <div class="container mt-3">
      <div class="row mt-4 text-center">
        <h3>Result:</h3>
        <h3 class="ml-5" id="factorial-result"></h3>
      </div>
    </div>
  </div>
</body>
</html>

Para que la interfaz se vea menos fea, usamos bootstrap como marco CSS.

Si este HTML se muestra en el navegador, debería verse así:
Caso simple de programación funcional y orientada a objetos

Todavía no hay ninguna operación en este formulario.

Nuestro objetivo es implementar una lógica en la que pueda ingresar un número hasta 100. Después de hacer clic en el botón "Calcular", el resultado debe mostrarse en el resultado-div.

Lo siguiente se implementa de manera funcional y orientada a objetos.

Implementación funcional


Primero cree un archivo para el método de programación funcional.


$ cat functional.js

Primero, necesitamos que se llame a una función cuando este archivo se cargue en el navegador.

Esta función primero obtiene el formulario y luego agrega la función que necesitamos al evento de envío del formulario.


function addSubmitHandler(tag, handler) {
  const form = getElement(tag);
  form.addEventListener('submit', handler);
}

addSubmitHandler("#factorial-form", factorialHandler);

Primero declare una función llamada addSubmitHandler.

Esta función tiene dos parámetros, el primero es la etiqueta que se encuentra en HTML y el segundo es la función que se vincula al evento de confirmación del Elemento.

A continuación, llame a esta función pasando # factorial-form y el nombre de la función factorialHandler.

El # delante de la etiqueta indica que estamos buscando el atributo id en HTML.

Si intenta ejecutar el código ahora, se producirá un error porque las funciones getElement y factorialHandler no están definidas en ninguna parte.

Por lo tanto, primero defina getElement antes de la función addSubmitHandler, como se muestra a continuación:


function getElement(tag) {
  return document.querySelector(tag);
}

Esta función es muy simple y solo devuelve los elementos HTML encontrados a través del marcado pasado. Pero reutilizaremos esta función más adelante.

Ahora agregue la función factorialHandler para crear la lógica central.


function factorialHandler(event) {
  event.preventDefault();

  const inputNumber = getValueFromElement('#factorial');

  try {
    const result = calculateFactorial(inputNumber);
    displayResult(result);
  } catch (error) {
    alert(error.message);
  } 
}

Llame a preventDefault inmediatamente después de devolver el evento.

Esto evitará el comportamiento predeterminado del evento Enviar. Puede probar lo que sucede cuando hace clic en el botón sin llamar a preventDefault.

Después de eso, el valor ingresado por el usuario se obtiene del campo de entrada llamando a la función getValueFromElement. Después de obtener el número, use la función calculateFactorial para calcular el factorial y luego muestre el resultado en la página pasando el resultado a la función displayResult.

Si el formato del valor es incorrecto o el número es mayor que 100, se generará un error y aparecerá una alerta.

A continuación, cree otras dos funciones auxiliares: getValueFromElement y displayResult, y agréguelas después de la función getElement.


function getValueFromElement(tag) {
  return getElement(tag).value;
}

function displayResult(result) {
  getElement('#factorial-result').innerHTML = result
}

Ambas funciones usan nuestra función getElement. Esta reutilización es una de las razones por las que la programación funcional es tan eficaz.

Para hacerlo más reutilizable, puede agregar un segundo parámetro llamado etiqueta a displayResult.

Esto le permite establecer dinámicamente los elementos que deben mostrar los resultados.

Pero en este ejemplo, utilicé un enfoque codificado.

A continuación, cree la función calculateFactorial delante de factoryHandler.


function calculateFactorial(number) {
  if (validate(number, REQUIRED) && validate(number, MAX_LENGTH, 100) && validate(number, IS_TYPE, 'number')) {
    return factorial(number);
  } else {
    throw new Error(
      'Invalid input - either the number is to big or it is not a number'
    );
  }
}

Luego cree una función llamada validate para verificar si el número de parámetro está vacío y no es mayor que 100, y el tipo es número. Si la verificación pasa, se llama a la función factorial y se devuelve el resultado. Si falla, se lanza el error capturado en la función factorialHandler.


const MAX_LENGTH = 'MAX_LENGTH';
const IS_TYPE = 'IS_TYPE';
const REQUIRED = 'REQUIRED';

function validate(value, flag, compareValue) {
  switch (flag) {
    case REQUIRED:
      return value.trim().length > 0;
    case MAX_LENGTH:
      return value <= compareValue;
    case IS_TYPE:
      if (compareValue === 'number') {
        return !isNaN(value);
      } else if (compareValue === 'string') {
        return isNaN(value);
      }
    default:
      break;
  }
}

En esta función, el interruptor se utiliza para determinar el tipo de paradigma de verificación que se ejecutará. Esta es solo una simple verificación de valor.

Luego agregue la función de factor real delante de la declaración calculateFactorial. Esta es la última función.


function factorial(number) {
  let returnValue = 1;
  for (let i = 2; i <= number; i++) {
    returnValue = returnValue * i;
  }
  return returnValue;
}

El archivo funcional.js final se muestra a continuación:


const MAX_LENGTH = 'MAX_LENGTH';
const IS_TYPE = 'IS_TYPE';
const REQUIRED = 'REQUIRED';

function getElement(tag) {
  return document.querySelector(tag);
}

function getValueFromElement(tag) {
  return getElement(tag).value;
}

function displayResult(result) {
  getElement('#factorial-result').innerHTML = result
}

function validate(value, flag, compareValue) {
  switch (flag) {
    case REQUIRED:
      return value.trim().length > 0;
    case MAX_LENGTH:
      return value <= compareValue;
    case IS_TYPE:
      if (compareValue === 'number') {
        return !isNaN(value);
      } else if (compareValue === 'string') {
        return isNaN(value);
      }
    default:
      break;
  }
}

function factorial(number) {
  let returnValue = 1;
  for (let i = 2; i <= number; i++) {
    returnValue = returnValue * i;
  }
  return returnValue;
}

function calculateFactorial(number) {
  if (validate(number, REQUIRED) && validate(number, MAX_LENGTH, 100) && validate(number, IS_TYPE, 'number')) {
    return factorial(number);
  } else {
    throw new Error(
      'Invalid input - either the number is to big or it is not a number'
    );
  }
}

function factorialHandler(event) {
  event.preventDefault();

  const inputNumber = getValueFromElement('#factorial');

  try {
    const result = calculateFactorial(inputNumber);
    displayResult(result);
  } catch (error) {
    alert(error.message);
  } 
}

function addSubmitHandler(tag, handler) {
  const form = getElement(tag);
  form.addEventListener('submit', handler);
}

addSubmitHandler("#factorial-form", factorialHandler);

En este método, nos ocupamos exclusivamente de funciones. Cada función tiene un solo propósito y la mayoría de las funciones se pueden reutilizar en otras partes del programa.

Para este sencillo programa web, el enfoque funcional es demasiado. La misma función se escribirá a continuación, pero esta vez está orientada a objetos.

Implementación orientada a objetos


Primero, necesita cambiar el src en la etiqueta de script del archivo index.html a lo siguiente.


<script src="oop.js" defer></script>

Luego crea el archivo oop.js.


$ cat oop.js

Para el enfoque orientado a objetos, tenemos que crear tres clases diferentes, una para validación, una para cálculo factorial y la otra para procesar formularios.

Primero, cree una clase que maneje el formulario.


class InputForm {
  constructor() {
    this.form = document.getElementById('factorial-form');
    this.numberInput = document.getElementById('factorial');

    this.form.addEventListener('submit', this.factorialHandler.bind(this));
  }

  factorialHandler(event) {
    event.preventDefault();

    const number = this.numberInput.value;

    if (!Validator.validate(number, Validator.REQUIRED) 
      || !Validator.validate(number, Validator.MAX_LENGTH, 100)
      || !Validator.validate(number, Validator.IS_TYPE, 'number'))
      {
        alert('Invalid input - either the number is to big or it is not a number');
        return;
      }

      const factorial = new Factorial(number);
      factorial.display();
  }
}

new InputForm();

Obtenga el elemento de formulario y el elemento de entrada en el constructor y guárdelos en variables de clase (también llamadas atributos). Luego agregue el método factorialHandler a Submit-event. En este caso, debe vincular el esto de la clase al método. Si no lo hace, obtendrá un error de referencia. Por ejemplo, llamar a this.numberInput.value no estará definido. Luego crea un método de clase factorialHandler con el evento como parámetro.

El código para este método debería parecer un poco familiar, por ejemplo, la instrucción if comprueba si el valor de entrada es válido, tal como se hace en la función calculateFactorial. Validator.validate es una llamada al método estático en la clase Validator que aún necesitamos crear. Si usa un método estático, no necesita inicializar una nueva instancia del objeto. Después de que se pasa la verificación, se crea una nueva instancia de la clase Factorial, se pasa el valor de entrada y el resultado calculado se muestra al usuario.

A continuación, cree la clase Validator delante de la clase InputForm.


class Validator {
  static MAX_LENGTH = 'MAX_LENGTH';
  static IS_TYPE = 'IS_TYPE';
  static REQUIRED = 'REQUIRED';

  static validate(value, flag, compareValue) {
    switch (flag) {
      case this.REQUIRED:
        return value.trim().length > 0;
      case this.MAX_LENGTH:
        return value <= compareValue;
      case this.IS_TYPE:
        if (compareValue === 'number') {
          return !isNaN(value);
        } else if (compareValue === 'string') {
          return isNaN(value);
        }
      default:
        break;
    }
  }
}

Todo dentro de esta clase es estático, por lo que no necesitamos ningún constructor.

La ventaja de esto es que no necesita inicializar la clase cada vez que la usa.

Las funciones de validación y validación son casi idénticas a nuestras funciones.js.

A continuación, cree la clase Factorial después de la clase Validator.


class Factorial {
  constructor(number) {
    this.resultElement = document.getElementById('factorial-result');
    this.number = number;
    this.factorial = this.calculate();
  }

  calculate() {
    let returnValue = 1;
    for (let i = 2; i <= this.number; i++) {
      returnValue = returnValue * i;
    }
    return returnValue;
  }

  display() {
    this.resultElement.innerHTML = this.factorial;
  }
}

Después de inicializar la instancia de esta clase, obtenemos el resultElement y lo almacenamos como un atributo y el número que le pasamos.

Luego llame al método calcular y almacenar su valor de retorno en el atributo. El método de cálculo contiene el mismo código que la función de factor en funcional.js. Finalmente, está el método de visualización, que establece el HTML interno del elemento de resultado en el número factorial calculado real.

El archivo oop.js completo se muestra a continuación.


class Validator {
  static MAX_LENGTH = 'MAX_LENGTH';
  static IS_TYPE = 'IS_TYPE';
  static REQUIRED = 'REQUIRED';

  static validate(value, flag, compareValue) {
    switch (flag) {
      case this.REQUIRED:
        return value.trim().length > 0;
      case this.MAX_LENGTH:
        return value <= compareValue;
      case this.IS_TYPE:
        if (compareValue === 'number') {
          return !isNaN(value);
        } else if (compareValue === 'string') {
          return isNaN(value);
        }
      default:
        break;
    }
  }
}

class Factorial {
  constructor(number) {
    this.resultElement = document.getElementById('factorial-result');
    this.number = number;
    this.factorial = this.calculate();
  }

  calculate() {
    let returnValue = 1;
    for (let i = 2; i <= this.number; i++) {
      returnValue = returnValue * i;
    }
    return returnValue;
  }

  display() {
    this.resultElement.innerHTML = this.factorial;
  }
}

class InputForm {
  constructor() {
    this.form = document.getElementById('factorial-form');
    this.numberInput = document.getElementById('factorial');

    this.form.addEventListener('submit', this.factorialHandler.bind(this));
  }

  factorialHandler(event) {
    event.preventDefault();

    const number = this.numberInput.value;

    if (!Validator.validate(number, Validator.REQUIRED) 
      || !Validator.validate(number, Validator.MAX_LENGTH, 100)
      || !Validator.validate(number, Validator.IS_TYPE, 'number'))
      {
        alert('Invalid input - either the number is to big or it is not a number');
        return;
      }

      const factorial = new Factorial(number);
      factorial.display();
  }
}

new InputForm();

Creamos tres clases para manejar tres funciones diferentes del programa:

  • Validación: clase de validación
  • Procesamiento factorial: clase factorial
  • Procesamiento de formularios: clase InputForm

    para resumir


Ambos métodos son formas efectivas de escribir código. Me gusta probar el método más eficaz en mis diferentes proyectos. En muchos casos, es incluso imposible separar los dos paradigmas con tanta claridad.

Espero que este artículo pueda brindarle una comprensión básica de los diferentes métodos de programación.

Supongo que te gusta

Origin blog.51cto.com/15077562/2609675
Recomendado
Clasificación