Когда следует использовать статические методы?

У меня есть класс, содержащий 10 методов. Мне всегда нужно использовать один из этих методов. Теперь я хочу знать, какой подход лучше?

class cls{
    public function func1(){}
    public function func2(){}
    .
    .
    public function func10(){}
}

$obj  = new cls;
$data = $obj->func3(); // it is random, it can be anything (func1, or func9 or ...)

ИЛИ

class cls{
    public static function func1(){}
    public static function func2(){}
    .
    .
    public static function func10(){}
}

cls::func3(); // it is random, it can be anything (func1, or func9 or ...)

Ответ 1

Это интересная тема. Я дам вам ориентированный на дизайн ответ.

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

Когда вы используете static, это вызов функции без экземпляра класса. Основная причина часто заключается в том, чтобы представлять класс обслуживания, который не должен быть создан несколько раз.

Я дам вам 3 решения (от мира до лучших), чтобы добиться этого:

Static

Статический класс (только с статическими функциями) не позволяет использовать многие функции ООП, такие как наследование, реализация интерфейса. Если вы действительно думаете о статической функции, это функция, именуемая именем своего класса. У вас уже есть пространства имен в PHP, поэтому зачем добавлять еще один слой?

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

Singleton

Синтаксис - это способ заставить класс иметь только один экземпляр:

<?php

class Singleton {
    // Unique instance.
    private static $instance = null;

    // Private constructor prevent you from instancing the class with "new".
    private function __construct() {  
    }

    // Method to get the unique instance.
    public static function getInstance() {
        // Create the instance if it does not exist.
        if (!isset(self::$instance)) {
            self::$instance = new Singleton();  
        }

        // Return the unique instance.
        return self::$instance;
    }
}

Это лучший способ, потому что вы можете использовать наследование, интерфейсы, и ваш метод будет вызван на объект-подстрекатель. Это означает, что вы можете определить контракты и использовать низкую связь с использованием классов. Однако некоторые люди рассматривают singleton как анти-шаблон, особенно потому, что если вы хотите иметь 3 экземпляра своего класса с разными свойствами ввода, вы не можете.

Сервис

Служба - это экземпляр стандартного класса. Это способ рационализировать ваш код. Такая архитектура называется SOA (сервис-ориентированная архитектура). Я приведу вам пример:

Если вы хотите добавить метод для продажи продукта в магазине потребителю, и у вас есть классы Product, Store и Consumer. Где вы должны создать этот метод? Я могу гарантировать, что, если вы считаете, что это более логично в одном из этих трех классов сегодня, завтра может быть что угодно. Это приводит к большому количеству дубликатов и трудностей в поиске кода, который вы ищете. Вместо этого вы можете использовать класс сервиса, например SaleHandler, который будет знать, как манипулировать вашими классами данных.

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


Подводя итог:

  • Если у вас нет рамки, синглтоны, безусловно, являются хорошим вариантом.

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

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

Ответ 2

Итак, в методах static есть очень основное отличие.

Чтобы использовать статические функции, вам не нужно инициализировать класс как объект. Например, Math.pow(), здесь .pow() (в Java, но объяснение по-прежнему сохраняется) является статическим методом.

Общее правило заключается в создании вспомогательных методов static.

Итак, например, если у вас есть класс Math, вы не хотите заполнять сборщик мусора классами, которые просто помогают другим, более важным классам.

Вы можете использовать его как динамические инициализаторы, если хотите!

Скажем, у вас есть класс RSAEncryptionHelper, теперь вы можете его инициализировать без каких-либо параметров, и это сгенерирует объект с размером ключа (скажем) 512 бит; но у вас также есть перегруженный конструктор объектов , который получает все свойства из других классов:

$a = new RSAEncryptionHelper::fromPrimeSet(...);

Ответ 3

Ответ зависит от того, что делают эти методы. Если вы используете их для изменения состояния объекта под рукой, вам нужно использовать вызовы метода экземпляра. Если они являются независимыми функциями, то вы можете использовать статические версии, но потом я бы поставил под вопрос, почему они являются частью класса вообще.