2013-07-02 1 views
1

Мой образец так просто, как это:Могу ли я избежать повторного набора двух очень похожих функций с помощью scala?

def func(arg1: Long, arg2: Long, arg3: String) { 
    privateFunc1(arg1); 
    privateFunc2(arg1, arg2, arg3); 
} 

и это перегруженная функция, которая также работает

def func(arg1: Long, arg2: Long, arg3: File) { 
    privateFunc1(arg1); 
    privateFunc2(arg1, arg2, arg3); 
} 

, как вы, возможно, догадались privateFunc2 уже перегружен, поэтому обе функции работают.

Мог ли я избежать этого избыточного повторения кода, что в scala, используя функцию композиции, возможно? Какая была бы лучшая практика?

Спасибо!

ответ

2

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

Если две версии privateFunc2 действительно похожи, является преобразование/предварительной обработки, что можно сделать, скажем, от File к String или наоборот, или преобразовать как в коллекции? Затем у вас есть только 1 версия privateFunc2, и одна из версий func применяет преобразование и переводит ее в другую, и вы устранили избыточность в наличии двух версий.

Я бы держался подальше от Either и неявных преобразований, так как если вы хотите сделать это правильно, вам нужно использовать тип-оболочку (неявные преобразования между общими типами сильно обескуражены, поскольку это может вызвать проблемы в другом месте вашего кода) и в в любом случае вы просто задерживаете неизбежное ветвление, чтобы иметь дело с каждой возможностью, а также вводить кучу шаблона.

tl; dr: split privateFunc2 поэтому требуется всего 1 вход. Или держите его как есть.

2

Я полагаю, вы могли бы попытаться использовать Either[String,File] для третьего аркта. Затем вам нужно будет выполнить сопоставление в privateFunc2. Код может выглядеть следующим образом:

def func(arg1: Long, arg2: Long, arg3: Either[String,File]) { 
    privateFunc1(arg1); 
    privateFunc2(arg1, arg2, arg3); 
} 

def privateFunc2(arg1: Long, arg2: Long, arg3: Either[String,File]){ 
    arg3 match{ 
    case Left(str) => //handle string case 
    case Right(file) => //handle file case 
    } 
} 

EDIT

Честно говоря, хотя, если String действительно путь к File, затем настроить частный FUNC работать только с File входом, а затем перегрузите общедоступный func, чтобы взять как String, так и File в качестве третьего arg, а затем в тот, который принимает String, конвертировать в File и вызвать частный func. Это работает так же и делает вещи относительно простыми.

+3

Позволяет ввести обертку и неявные преобразования, чтобы сохранить две строки. Это хорошо*. –

+0

@ om-nom-nom, можете ли вы подробнее разобраться, чтобы я мог изменить ответ? – cmbaxter

+0

К сожалению, у меня нет ничего лучше, чем ваше предложение :((так что я могу только жалуюсь на чрезмерное изнашивание –

Смежные вопросы