2015-09-17 3 views
-1

Я пишу метод в C# класса, как показано ниже:метод # шаблон C, который изменяет логику во время выполнения

using(sftpClient) 
{ 
    sftpClient.Connect(); 
    try{ 
     //Do some process 
    } 
    catch(Exception ex) 
    { 
    } 
    sftpClient.Disconnect(); 
} 

Мне нужно создать еще несколько методов, аналогичные приведенным выше, но логические изменения только внутри попытки { } catch {} block. Может ли кто-нибудь предложить лучший способ достичь этого, используя некоторые шаблоны проектирования?

+0

sftpclient.Disconnect() в блоке finally будет выглядеть лучше – sll

+0

@sll Я бы сказал, что класс должен просто вызывать 'Disconnect' в' Dispose', а не писать 'finally' вручную ... Но действительно' Disconnect' (или ' Закрыть ',' Flush' или явно 'Dispose') выглядят странно внутри' using'. –

+0

Чтобы использовать шаблон дизайна, который лучше кода выше, вы должны были предоставить информацию о используемом случае и клиенте SFTP, который вы используете. –

ответ

1

Посмотрите на Strategy Pattern (курсив мой собственный):

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

Так в принципе, вы бы объявить интерфейс, скажем, IBehaviour и определить какой метод:

public interface IBehaviour 
{ 
    void Process(); 
} 

Тогда есть другой класс реализации IBehaviour для каждой части логики вы хотите иметь.

Класс, в котором вам нужно использовать логику, позволит передать объект IBehaviour, а в вашем блоке try просто сделать behaviour.Process().

Это позволит вам настроить поведение вне класса, а затем просто передать его классу, в котором вы хотите что-то с ним делать.

+0

Я думаю, что он должен использовать шаблон шаблона, а не стратегию, потому что часть его кода (некоторые шаги) меняет не весь алгоритм внутри метода – Arash

+0

@Arashjo: Что-то вроде абстрактных классов? – npinti

+0

да как-то, google о различиях между этими – Arash

3

Вы можете создать абстрактный базовый класс:

abstract class MyBaseClass { 
    protected abstract void DoSomething(); 

    public void DoSmtpStuff() { 
     smtpClient.Connect(); 
     try { 
      DoSomething(); 
     } catch (Exception ex) { 

     } 
     smtpClient.Disconnect(); 
    } 
} 

, а затем просто создать наследства этого класса, которые реализуют только метод DoSomething.

+0

Может быть полезно разоблачить абстрактный метод, который вызвал в catch() как HandleError (Exception ex) – sll

0

Вы можете использовать этот шаблон:

abstract class ProcedureBase<T> 
{ 
    public T Work() 
    { 
     using(sftpClient) 
     { 
      sftpClient.Connect(); 
      try{ 
       ProtectedWork(); 
      } 
      catch(Exception ex) 
      { 
      } 
      sftpClient.Disconnect(); 
     } 
    } 
    protected abstract T ProtectedWork(); 
} 


class Procedure1 : ProcedureBase<TypeToReturn> 
{ 
    protected override TypeToReturn ProtectedWork() 
    { 
     //Do something 
    } 
} 

class Procedure2 : ProcedureBase<AnotherTypeToReturn> 
{ 
    protected override AnotherTypeToReturn ProtectedWork() 
    { 
     //Do something 
    } 
} 

Использование:

static void Main(string[] args) 
{ 
    Procedure1 proc = new Procedure1(); 
    proc.Work(); 
} 
+1

Уродливое именование, если честно, почему у класса есть префикс «Процедура»? Префикс «Защищенный» для защищенного метода ... Также общий параметр усложняет пример и слегка смещает акцент с основного вопроса. Метод «Работа» - это существительное, но имена методов лучше выглядят как глаголы, тогда как существительные, полезные для свойств – sll

1

Альтернатива классов просто принять меры в качестве аргумента:

TResult WithSftpClient<TResult>(Func<TResult, SftpClient> operation) 
{ 
    TResult result = default(TResult); 
    // Note that one may need to re-create "client" here 
    // as it is disposed on every WithSftpClient call - 
    // make sure it is re-initialized in some way. 
    using(sftpClient) 
    { 
    sftpClient.Connect(); 
    try 
    { 
     result = operation(sftpClient); 
    } 
    catch(Exception ex) 
    { 
     // log/retrhow exception as appropriate 
    } 
    // hack if given class does not close connection on Dispose 
    // for properly designed IDisposable class similar line not needed 
    sftpClient.Disconnect(); 
    } 
    return result; 
} 

И использовать его:

var file = WithSftpClient(client => client.GetSomeFile("file.name")); 
Смежные вопросы