Какова желательная ситуация (пример реальной жизни) для создания статических методов, кроме создания помощника?
Я просто хочу понять цель, которой служит статический метод, и какова желательная ситуация, когда я могу создавать статические методы, за исключением некоторых, которые сказали бы, что статические методы используются для создания помощника.
считают, что у меня есть 1 веб-сайт, который будет использоваться в моей компании только как система управления людскими ресурсами как сайты.
Теперь после входа администратора в систему администратор увидит список сотрудников.таким образом, метод прост, что делает не более чем получение всех сведений о сотрудниках из таблицы employee и отображение их на веб-сайте, и этот метод будет определен на уровне бизнес-доступа, как это в .net:
public class EmployeeBal
{
public List<Employee> GetAllEmployees()
{
return Select * from Employee
}
}
вот как я бы назвал этот метод из моего приложения.Например(.aspx или контроллер MVC и т. д....)
var employeeBal= new EmployeeBal();
employeeBal.GetAllEmployees();
Итак, мой вопрос: Должен ли я создать этот метод как статический метод или нестатический метод??
Примечание:это просто пример метода, и этот метод в моем бизнес-уровень доступа.
считай я 1 сайт где на домашней странице Я показываю некоторый список продуктов и при посещении этого веб-сайта каждый пользователь может увидеть этот список продуктов.
таким образом, моя функция будет такой же, как и выше, в Business acess layer:
public class ProductBal
{
public List<Product> DisplayProductonHomePage()
{
return Select * from Products
}
}
таким образом, мой вопрос будет таким же, как создать ли этот метод как статический метод или нестатический метод, и что произойдет, если больше чем 10 пользователей одновременно получают доступ к этому веб-сайту, то каково будет поведение/последствия этого метода???
будет ли этот метод служить цели этого каждого пользователя, если мы объявим этот метод статическим??
может ли кто-нибудь ответить на этот вопрос, кратко объяснив каждый сценарий???
7 ответов
статический метод имеет смысл, когда нет государства. Что я имею в виду под государством? Хорошо, рассмотрим следующее: У вас есть два разных объекта, a
и b
, которые оба типа EmployeeBal
. Есть ли когда-нибудь дело в вашей программе, где a.GetAllEmployees()
и b.GetAllEmployees()
будет давать разные результаты?
если нет, то почему объекты a
и b
существуют вообще? Весь смысл наличия объектов заключается в том, чтобы связать с ними какое-то отдельное состояние. Если два разных объекта никогда не могут относиться к другому состоянию, тогда они не выполняют никакой цели.
в самом деле, в этой ситуации ваш EmployeeBal
было бы точно эквивалентно System.Math
, и все его методы являются "вспомогательными методами" (если это то, что вы хотите назвать их). В этом случае забудьте на минуту о статических методах: весь ваш класс должен быть статическим (static class EmployeeBal
), и он не должен иметь никаких конструкторов; потому что понятие объекта типа EmployeeBal
просто не имеет смысла. Фактически, на других языках EmployeeBal
не было бы классом вообще; вместо этого это было бы что-то, обычно называемое модуль: логически группирует код. C# не имеет модулей, и весь код должен находиться в классах. Таким образом, классы выполняют двойную цель: они группируют код и генерируют объекты.1
Теперь рассмотрим менее экстремальный случай: EmployeeBal
объекты фактически поддерживают состояние и отличаются. Еще GetAllEmployees()
будет все равно даст тот же результат, независимо от какой объект вызывает метод.
в этом случае EmployeeBal
очевидно, не может быть статическим классом. Но!--15--> по-прежнему без гражданства и, следовательно, не принадлежит объекты типа EmployeeBal
. Таким образом, метод должен быть статичным.
1 это отсутствие различия между двумя принципиально различными понятиями (модуль и класс) на самом деле довольно раздражает, и основная причина, по которой C# ведет себя таким образом потому что он был задуман, чтобы быть похожими на Java. Это было ошибкой в ретроспективе, но не серьезным.
есть ли причина, по которой метод должен быть статическим? Если бы я всегда была на стороне нестатическим. Одна из главных причин-возможность писать модульные тесты. Чтобы написать модульные тесты, вы хотите иметь возможность изолировать тестируемый класс от других классов. Но если класс A содержит ссылку на статический класс B, то вы не можете протестировать A без тестирования B. возможно, B зависит от строк подключения или настроек конфигурации. Может быть, зависит от других статических классов. Теперь вы не можете проверить A, если B и все остальное это зависит от того на месте.
если, с другой стороны, класс A зависит от интерфейс как IEmployeeProvider
который предоставляется через его конструктор, то вы можете протестировать класс A с издевательской реализацией IEmployeeProvider
.
если A имеет IEmployeeProvider
в качестве аргумента в своем конструкторе, то вы можете сказать, глядя на конструктор, что он зависит от IEmployeeProvider
. Но если это зависит от static EmployeeProvider
класс где-то внутри метода, то зависимость скрытый. Вы должны прочитать весь класс, чтобы узнать, от чего он зависит.
кроме того, сам статический класс может быть труднее испытания. Если это абсолютно всегда будет оставаться без состояния, то лучше иметь нестатический класс,который вы можете тестировать.
нормально иметь несколько потоков, выполняющих один и тот же статический метод, если метод не имеет доступа к статическому состоянию, такому как поле или свойства. В этом случае общие объекты, хранящиеся в полях/свойствах, должны быть потокобезопасными. Части доступа к данным .Net не предназначены для потокобезопасности.
Как только вы начнете рассматривать такие аспекты, как управление подключением к базе данных, которое может быть повторно использовано для нескольких запросов во время выполнения одного веб-сайта запрос, вы должны рассмотреть, является ли static лучшим подходом. Поскольку вы не можете сохранить соединение в статическом поле, как описано выше, вам придется передать его в качестве параметра каждому статическому методу. С другой стороны, если вы передадите соединение конструктору и сохраните его в (нестатическом) поле, вы можете получить к нему доступ из нескольких нестатических методов этого экземпляра, что будет легче управлять IMO.
Это довольно большая тема, однако, и в целом управление классом зависимости довольно сложно получить прямо в ООП. Некоторые программисты предпочитают делегировать эту задачу"инверсии управления" -библиотеке. Есть много доступных для .Чистая, такими как Microsoft единства, помощью StructureMap, AutoFac и т. д.
Если мы собираемся говорить о статике, нам нужно ввести зависимость. В этом случае это клиент sql. Вот как выглядит код с этим введенным. Поскольку мы не собираемся вдаваться в детали клиента sql, он используется в качестве интерфейса в статическом методе.
var client = new SqlClient();
var allEmployeeData = EmployeeBal.GetAllEmployees(client);
class EmployeeBal
{
public static Employee GetAllEmployees(ISqlClient client)
{
return client.Execute("Select * from Employee");
}
}
внедрение зависимостей через интерфейс меняет все. Теперь метод хорош как статический, потому что он имеет дело только с интерфейсом и строкой. Оба они не имеют гражданства. С все компоненты метода без состояния они абсолютно безопасны для статического метода, который может иметь только одно глобальное состояние.
поскольку ваш код был написан изначально, это небезопасно как статическое, потому что как я могу быть уверен, что клиент sql готов к использованию, и после того, как я проверил, что он готов, он не был изменен, когда я иду запускать запрос? Если я могу ввести клиент sql, я могу управлять им, так как он имеет локальную и глобальную область.
лучшим примером будет что-то вроде фабрики для клиента SQL. Например, с nhibernate должна быть создана только одна фабрика сеансов. Эта фабрика сеансов потокобезопасности может создавать несколько сеансов, не являющихся потокобезопасными, для выполнения SQL-запросов. В этом случае целесообразно, чтобы фабрика сеансов была открыта с помощью статического метода, потому что это описывает тот факт, что когда-либо будет только одна фабрика сеансов.
var session = SessionFactory.OpenSession();
чтобы ответить на ваш вопрос:
Итак, мой вопрос: Должен ли я создать этот метод как статический метод или нестатический метод?? Примечание: это всего лишь пример метода, и этот метод находится в моем уровне бизнес-доступа.
Я хотел сделать эти методы статическими учитывая то, что вы предоставили. Но я уверен, что у вас будут переменные экземпляра, объявленные в вашем классе или в методах в этом классе, что, конечно, будет означать, что не делайте этого статический.
поэтому определяющим фактором для меня, если я решу использовать статический метод или нет, является повторное использование и ресурсы.
Если я обнаружу, что повторно использую метод много раз, и я заключаю, что ему не нужно состояние (хранится в памяти) - я сделаю его статическим методом.
также я обычно буду делать свои методы статическими, если они могут быть использованы в других приложениях или если я думаю, что они будут полезны в будущем.
например, я недавно написал метод, который преобразует файл Excel в плоский файл. Я сделал этот статический метод в своем собственном статическом классе (я могу поместить его в аналогичный служебный класс по дороге), потому что я, вероятно, снова использую его в другом проекте, поэтому теперь я могу просто ссылаться на его класс без создания экземпляра нового объекта, чтобы просто вызвать метод. (Мне не нужно состояние в любом случае)
Я довольно новичок в программировании, и я надеюсь, что вы нашли это полезным.
использование статических методов эквивалентно глобальному поведению. Он поставляется с преимуществами: простота доступа для простых сценариев.
Он также поставляется со всеми проблемами, которые имеют глобальные данные и состояние. Среди них вы не можете заменить реализацию другой (например, для тестов). Смотри https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil
хотя вы можете считать, что у вас нет глобального состояния ... концептуально да. У вас есть уникальный, предопределенный, неконфигурируемый, жестко закодированный способ доступа к некоторому поведению. Вы опубликовали его и не можете изменить ... когда-либо. Вы нарушаете принцип открытия-закрытия. Вы нарушаете принцип замены Лискова.
Java имеет это, но scala исправил это. Подробнее об этом здесь: почему у Scala нет статических членов внутри класса?
варианты использования статических и нестатических методов различаются, поэтому вам нужно создать один, основанный на том, что они выполняют:
- статический метод не участвует в полиморфизме на основе наследования, в то время как нестатический. Другими словами, вы не можете пометить статический метод как виртуальный или абстрактный, что означает, что вы не можете изменить его поведение. Это также означает, что вызывающий статический метод точно знает что этот статический метод будет делать и как точно. С помощью нестатического метода вы можете вызывать его в базовом классе, но из-за полиморфизма вы можете вызвать метод производного класса с переопределенным поведением.
- как статические, так и нестатические методы могут изменять состояние чего-то (в отличие от того, что другие требования), но есть разница. Вы можете создать статический класс, который имеет все статические члены (свойства, методы и т. д.) в нем, поэтому методы могут изменять состояние этого статического класса (что сказал, хоть и
C#
позволяет вам это делать, я не рекомендую создавать такой класс в любом случае). С помощью нестатического метода можно изменять как статическое, так и нестатическое состояние класса. Это идет дальше в различия между статическими и нестатическими классами, что вкратце означает: статический класс один б экземпляр, в то время как нестатический класс может быть умножен, и каждый из них будет иметь свою собственную копию состояния (так зачем создавать статический класс с искусственным ограничение тогда - вот почему я не рекомендовал их раньше). - еще одно хорошее использование статических методов-это методы расширения. Они должны быть определены как статические, но вы можете вызвать их на экземпляре класса, который они расширяют. Они по-прежнему служат за пределами ярлыки для экземпляра, так как они не могут делать ничего, кроме обычных статических методов (например, не могут получить доступ к частным или защищенным членам).
- и вы правы, статический класс подходит ну, при определении вспомогательных методов, потому что они обычно являются просто ярлыками для некоторых фиксированных функций, легко доступных для повторного выполнения из многих мест. В Visual Basic вместо
static
ключевое слово, которое вы будете использоватьshared
ключевое слово, которое прекрасно объясняет цель статического метода.
наконец, я лично рекомендую создавать статические методы как чистые функции, которые всегда производят такой же выход для такого же входного сигнала (никакие побочные эффекты, как выход различные, основанные на времени или других неявных факторах). У вас должна быть веская причина проектировать его иначе (например, если вы пишете Math.Random()
).
теперь, чтобы ответить на вопросы из вашего вопроса (я знаю, наконец):
- Я думаю, что уровень бизнес-доступа не должен быть статическим, потому что вам, скорее всего, понадобятся преимущества нестатических классов, таких как инъекция зависимостей и модульная тестируемость.
- нет никакой разницы между статическими и нестатическими методами с точки зрения потоков / многопоточности оба они могут вызываться несколькими потоками одновременно, и все они будут выполняться одновременно (если не использовать конструкции синхронизации). Однако существует общая рекомендация по дизайну, что вы должны сделать статические методы потокобезопасными, если вы ожидаете условий гонки. Нестатические методы не должны беспокоиться об этом, так как это поставило бы их в слишком много допущений.