Funktionale Programmierung: Ein verrĂŒcktes Spielzeug, das die ArbeitsproduktivitĂ€t beeintrĂ€chtigt. Teil 1

Möglicherweise haben Sie bereits von der sogenannten „funktionalen“ Programmierung gehört. Vielleicht denkst du sogar, dass du es irgendwie versuchen solltest.

Auf keinen Fall!



Die funktionale Programmierung ist voller MĂ€ngel und nicht fĂŒr echte Projekte geeignet. Ihre Anwendung wird zu einem starken RĂŒckgang der ArbeitsproduktivitĂ€t fĂŒhren. Warum ist das so? Lass es uns herausfinden.

▍ → Teil 2

Die funktionale Programmierung kann die vielfĂ€ltigen Unternehmensanforderungen nicht erfĂŒllen



Um echte Software der Enterprise-Klasse zu erstellen, sind komplexe starre und verbindliche Anforderungen erforderlich, die sich auf die erwartete Anzahl der in die Softwarelösung eingebetteten Abstraktionen beziehen. Die objektorientierte Programmierung ermöglicht es dem Entwickler, viele Abstraktionsmechanismen zu verwenden, die die Anforderungen von Organisationen an Softwaresysteme vollstĂ€ndig erfĂŒllen können.

Ich glaube, der obige Text sieht nicht besonders klar aus. Aber sehr bald wird alles zusammenpassen.

Die sogenannte "funktionale" Programmierung hat keinen normalen Mechanismus zum Erstellen von Abstraktionen. Tatsache ist, dass es auf mathematischen Regeln basiert (diese Regeln, die durchaus verstĂ€ndlich sind, finden in der realen Welt, die sich außerhalb der Mauern von Bildungseinrichtungen befindet, keine Anwendung). Im Gegensatz zu OOP unternimmt die funktionale Programmierung keinen Versuch, all die vielen harten und komplexen Softwareanforderungen zu erfĂŒllen, die Unternehmen stellen.

Das folgende Codefragment zeigt die Probleme, die bei der Verwendung der funktionalen Programmierung weit verbreitet sind:

import { filter, first, get } from 'lodash/fp';

const filterByType = type =>
  filter( x => x.type === type );

const fruits = [
  { type: 'apple', price: 1.99 },
  { type: 'orange', price: 2.99 },
  { type: 'grape', price: 44.95 }  
];

const getFruitPrice = type => fruits =>
  fruits
  |> filterByType(type)
  |> first
  |> get('price');

const getApplePrice = getFruitPrice('apple');

console.log('apple price', getApplePrice(fruits));

, , !

, .

! - , , , . , , , .



, , , .

, . , , . , , :

class Fruit {
  constructor(type, price) {
    this.type = type;
    this.price = price;
  }
}

class AbstractFruitFactory {
  make(type, price) {
    return new Fruit(type, price);
  }
}

class AppleFactory extends AbstractFruitFactory {
  make(price) {
    return super.make("apple", price);
  }
}

class OrangeFactory extends AbstractFruitFactory {
  make(price) {
    return super.make("orange", price);
  }
}

class GrapeFactory extends AbstractFruitFactory {
  make(price) {
    return super.make("grape", price);
  }
}

class FruitRepository {
  constructor() {
    this.fruitList = [];
  }

  locate(strategy) {
    return strategy.locate(this.fruitList);
  }

  put(fruit) {
    this.fruitList.push(fruit);
  }
}

class FruitLocationStrategy {
  constructor(fruitType) {
    this.fruitType = fruitType;
  }

  locate(list) {
    return list.find(x => x.type === this.fruitType);
  }
}

class FruitPriceLocator {
  constructor(fruitRepository, locationStrategy) {
    this.fruitRepository = fruitRepository;
    this.locationStrategy = locationStrategy;
  }

  locatePrice() {
    return this.fruitRepository.locate(this.locationStrategy).price;
  }
}

const appleFactory = new AppleFactory();
const orangeFactory = new OrangeFactory();
const grapeFactory = new GrapeFactory();

const fruitRepository = new FruitRepository();
fruitRepository.put(appleFactory.make(1.99));
fruitRepository.put(orangeFactory.make(2.99));
fruitRepository.put(grapeFactory.make(44.95));

const appleLocationStrategy = new FruitLocationStrategy("apple");

const applePriceLocator = new FruitPriceLocator(
  fruitRepository,
  appleLocationStrategy
);

const applePrice = applePriceLocator.locatePrice();

console.log("apple", applePrice);

, . — .

. - , .

. , , .



, , . , -.

-, , .

, .

, «» . , . , , . , .

. :

//  :

// calculator.js:
const isValidInput = text => true;

const btnAddClick = (aText, bText) => {
  if (!isValidInput(aText) || !isValidInput(bText)) {
    return;
  }
}


//  :

// inputValidator.js:
export const isValidInput = text => true;

// calculator.js:
import { isValidInput } from './inputValidator';

const btnAddClick = (aText, bText, _isValidInput = isValidInput) => {
  if (!_isValidInput(aText) || !_isValidInput(bText)) {
    return;
  }
}

— , . , ? — ?

- :

//  :
public class CalculatorForm {
    private string aText, bText;
    
    private bool IsValidInput(string text) => true;
    
    private void btnAddClick(object sender, EventArgs e) {
        if ( !IsValidInput(bText) || !IsValidInput(aText) ) {
            return;
        }
    }
}


//  :
public class CalculatorForm {
    private string aText, bText;
    
    private readonly IInputValidator _inputValidator;
    
    public CalculatorForm(IInputValidator inputValidator) {
        _inputValidator = inputValidator;
    }
    
    private void btnAddClick(object sender, EventArgs e) {
        if ( !_inputValidator.IsValidInput(bText)
            || !_inputValidator.IsValidInput(aText) ) {
            return;
        }
    }
}

public interface IInputValidator {
    bool IsValidInput(string text);
}

public class InputValidator : IInputValidator {
    public bool IsValidInput(string text) => true;
}

public class InputValidatorFactory {
    public IInputValidator CreateInputValidator() => new InputValidator();
}

! , 22. . , , , .



«» - , . — .

- (, , ).

- :

class CountryUserSelectionStrategy {
  constructor(country) {
    this.country = country;
  }
  
  isMatch(user) {
    return user.country === this.country;
  }
}

class UserSelector {
  constructor(repository, userSelectionStrategy) {
    this.repository = repository;
    this.userSelectionStrategy = userSelectionStrategy;
  }
  
  selectUser() {    
    let user = null;

    for (const u in users) {
      if ( this.userSelectionStrategy.isMatch(u) ) {
        user = u;
        break;
      }
    }
    
    return user;
  }
}

const userRepository = new UserRepository();
const userInitializer = new UserInitializer();
userInitializer.initialize(userRepository);

const americanSelectionStrategy = new CountryUserSelectionStrategy('USA');
const americanUserSelector = new UserSelector(userRepository, americanSelectionStrategy);

const american = americanUserSelector.selectUser();

console.log('American', american);

for (const u in users). - , . , , .

, , , , , -. , , «» :

SELECT * FROM Users WHERE Country=’USA’;

, SQL-, - . SQL? - ? , . — , .



- — . «» . , , , .

. , . , , . . ( ) . , - , garfield.fishHead — , . , , garfield.swim() () garfield.layCaviar() (). , ! , , . , , !

. , . — .



, , . , , . «». , - . , . — .eat(veggies), , .doHomework(), . — . , , ? , !

, , . Manager. , , , , , , « Netflix ».

, , ? , , .

- , , , Factory. , , — MonaLisaFactory, WallFactory.

, — «» , . , .

, , , .



, , , . .

-, - , , . ( «») . 30 , . - .

— Domain-Driven Design, , . , Resharper, - — .

20-30 . , , 30 , . - . - , , . ?

? , . JavaScript. . , . ? .




! ?

Source: https://habr.com/ru/post/de462483/


All Articles