Как издеваться над статическими методами?

Я новичок в имитации объектов, но понимаю, что мне нужно, чтобы мои классы реализовывали интерфейсы, чтобы имитировать их.

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

Как лучше всего обойти это? Должен ли я просто использовать методы экземпляра (что кажется неправильным) или есть другое решение?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
34
0
41 592
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

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

т.е. в вашем классе со статическим методом есть:

private static final MethodObject methodObject = new MethodObject();

public static void doSomething(){
    methodObject.doSomething();
}

и ваш объект метода может быть очень простым и легко тестируемым:

public class MethodObject {
    public void doSomething() {
        // do your thang
    }
}

Есть ли у вас какие-нибудь хорошие ссылки на этот паттерн? Не знаю, как бы я это сделал.

brien 30.09.2008 17:56

Эээ, на самом деле нет. Я не уверен, придумал ли я это имя, или это считается скорее идиомой, чем шаблоном, но я не вижу никаких достойных ссылок от Google. Хотя буду продолжать искать.

Grundlefleck 30.09.2008 18:05

Спасибо, пример помог мне понять, что вы имели в виду.

brien 30.09.2008 18:07

Это фактически убивает всякую идею о статических методах.

SevDer 08.10.2010 12:03

разве это не называется синглтоном?

Ramadheer Singh 14.11.2012 02:24

Да, вы используете методы экземпляра. Статические методы в основном говорят: «Есть один способ реализовать эту функциональность - он не полиморфен». Издевательство основано на полиморфизме.

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

По возможности используйте методы экземпляра.

Используйте общедоступные статические функции Func [T, U] (ссылки на статические функции, которые могут быть заменены фиктивными функциями), где методы экземпляра невозможны.

Возможно, вы пытаетесь начать тестирование слишком глубоко. Нет необходимости создавать тест для проверки каждого метода в отдельности; частные и статические методы следует тестировать, вызывая общедоступные методы, которые затем по очереди вызывают частные и статические методы.

Допустим, ваш код выглядит так:

public object GetData()
{
 object obj1 = GetDataFromWherever();
 object obj2 = TransformData(obj1);
 return obj2;
} 
private static object TransformData(object obj)
{
//Do whatever
}

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

Я нашел блог через гугл с отличными примерами того, как это сделать:

  1. Класс рефакторинга должен быть классом экземпляра и реализовывать интерфейс.

    Вы уже заявили, что не хотите этого делать.

  2. Используйте класс экземпляра оболочки с делегатами для членов статических классов

    Таким образом вы можете смоделировать статический интерфейс через делегатов.

  3. Используйте класс экземпляра оболочки с защищенными членами, которые вызывают статический класс

    Это, вероятно, самый простой способ имитировать / управлять без рефакторинга, поскольку его можно просто унаследовать и расширить.

Простое решение - разрешить изменение реализации статического класса через сеттер:

class ClassWithStatics {

  private IClassWithStaticsImpl implementation = new DefaultClassWithStaticsImpl();

  // Should only be invoked for testing purposes
  public static void overrideImplementation(IClassWithStaticsImpl implementation) {
     ClassWithStatics.implementation = implementation;
  }

  public static Foo someMethod() {
    return implementation.someMethod();
  }

}

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

Небольшой момент, разве не нужно было бы объявлять реализацию статической, если бы к ней можно было получить доступ статическим способом?

Grundlefleck 30.09.2008 21:29

Проблема в том, что вы используете сторонний код и вызываете его из одного из ваших методов. В итоге мы обернули его в объект и передали его с помощью dep inj, а затем ваш модульный тест может имитировать сторонний статический метод, вызывая с ним сеттер.

Другие вопросы по теме