статические члены против модуля для типа в F #? - PullRequest
0 голосов
/ 30 декабря 2018

Предположим, у меня есть такой тип:

type Season =
| Spring
| Summer
| Autumn
| Winter

Я хочу иметь функцию next, которая возвращает следующий сезон:

let next s = 
  match s with
  | Spring -> Summer
  | Summer -> Autumn
  | Autumn -> Winter
  | Winter -> Spring

Есть два места, где я могупоставить эту функцию.

В именованном модуле:

module Season = 
  let next s = 
    match s with
    | Spring -> Summer
    | Summer -> Autumn
    | Autumn -> Winter
    | Winter -> Spring

Или как статический член типа:

type Season =
| Spring
| Summer
| Autumn
| Winter
  with 
    static member next s = 
      match s with
      | Spring -> Summer
      | Summer -> Autumn
      | Autumn -> Winter
      | Winter -> Spring

Каковы причины для предпочтения каждого подхода?

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

В конечном счете, это призыв к моделированию предметной области, и здесь нет однозначного правильного ответа.Важно то, как каждый выбор влияет на удобочитаемость и удобство сопровождения кода.

Я предпочитаю использовать статические члены для функциональности, которая очень «согласована» с типом, больше, чем какой-либо конкретный фрагмент кода бизнес-логики.Вспомните Parse функции или умные конструкторы / фабричные методы.Общий подход заключается в том, что если бы я реорганизовал код, переместив тип в другое место, это были бы функции, которые я определенно хотел бы переместить вместе с ним.Наличие их в качестве статических членов также помогает обнаружению через intellisense, так как вам нужно только знать имя типа, чтобы найти их.

С другой стороны, я бы использовал модуль для размещения бизнес-логики, которая представляет некоторыеабстрактный процесс, и если рассматриваемая функция каким-то образом специфична для этой бизнес-логики и вряд ли будет полезна вне ее, то я бы пошел с функцией в модуле, даже если она все еще в некоторой степени зависит от типа.Например, синтаксический анализатор с очень конкретной целью, полезный только как часть этого одного рабочего процесса по унаследованным причинам, был бы функцией с ограниченным доступом, а не статическим членом, потому что другие клиенты, использующие этот тип, вообще не должны даже знать об этой функции,

В вашем случае я бы выбрал статический член Next, если имеет смысл использовать его в нескольких различных модулях в вашем контексте - если возможность циклически проходить через Seasons является фундаментальнойкачество, которое определяет, что такое Season.

В противном случае, если у вас есть только один модуль, скажем, WeatherPatterns, который регулирует количество осадков в зависимости от смены сезона, и это единственная часть вашего кода, где вы заботитесь о циклическом переходе по Seasons, тогда я 'Я поставил бы это как функцию в этом модуле.

0 голосов
/ 31 декабря 2018

Ваш пример довольно прост, и поэтому любой подход здесь, вероятно, подойдет.Но представьте, что вы добавили еще дюжину функций, которые принимают параметр Season.Теперь определение типа будет выглядеть крайне загроможденным.Кроме того, эти функции могут нуждаться в использовании некоторых общих значений и функций, которые могут быть объявлены как частные внутри модуля Season.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...