Этот класс избегает временной связи - PullRequest
0 голосов
/ 01 мая 2020

У меня есть объект-оболочка, который принимает строку подключения, открывает базу данных и инициализирует API, прежде чем его можно будет использовать. После прочтения сообщения в блоге Марка Симанна о временной связи я сходил с ума от попыток реорганизовать мой API, чтобы он был понятен. Я посмотрел на NET класс SqlConnection, и они требуют Open, прежде чем использовать его, поэтому, возможно, этот тип связи неизбежен? Я не знаю, есть ли способ сделать то, что я хочу, так как это обертка существующего API, но вот что у меня есть. Одновременно может быть только одно соединение, иначе вам нужно закрыть и перезапустить

public class MyService
{
    public MyService(string dataSource)

    public void StopRequest()

    public void StopAPI()

    public Response SendRequest(string request, string pass)

}

Вы видите, что требуется строка источника данных и запускает API, так что SendRequests будет работать, но вы можете только реально иметь один сервис за раз, поэтому, если я не сохраню его в каком-либо состоянии c var или DI singleton, вам придется каждый раз вызывать новый .. (источник данных), даже если он всегда один и тот же. Единственное, что меня беспокоит, это то, что если вы позвоните StopRequest или StopAPI и затем позвоните SendRequest, это, конечно, вызовет ошибку. Я думаю, что это избегает временной связи, но хотел несколько мыслей.

1 Ответ

3 голосов
/ 01 мая 2020

Временная муфта - это дизайнерский запах, которого не всегда можно избежать. Особенно когда имеешь дело с уже существующими API или иногда с внешними сервисами, которые требуют выполнения операций в определенном (временно связанном) порядке. SqlConnection - хороший пример, потому что он требует от вас звонить Open, что является неявным и кое-что, что я до сих пор забываю делать время от времени. С другой стороны, позволить SqlConnection открывать соединение изнутри его конструктору также является плохой идеей, которая является причиной существования метода Open в первую очередь.

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

Трудно дать очень точную c обратную связь по вашему варианту использования, потому что некоторые детали отсутствуют. Но я могу представить, что StopAPI до , а не будут частью абстракции и будут вызываться изнутри Dispose метода на вашем адаптере.

Если порядок взаимодействия имеет решающее значение и невозможно абстрактный, вы можете предотвратить временную связь, позволяя методам возвращать экземпляры, которые должны быть переданы следующему методу для работы. Это делает зависимость между методами очень явной, проверенной компилятором и, следовательно, удаляет временную связь. Например:

public class MyService
{
    public MyService(string dataSource);

    public Api StartApi();
}

public class Api : IDisposable
{
    public Request SendRequest(string request, string pass);

    public void Dispose(); // Calls StopAPI internally
}

public class Request : IDisposable
{
    public Response Response { get; }

    public void Dispose(); // Calls StopRequest internally
}
...