История изменений
Исправление KivApple, (текущая версия) :
Этот инстанс является глобальной переменной, поэтому ничего нового не даёт
Открою тебе секрет - со времён изобретения процедур ничего принципиально нового в программировании не появлялось. Всё можно реализовать на базе более простых примитивов. Но это не делает ООП и другие вещи ненужными - это синтаксический сахар, с ним код становится выразительнее и понятнее.
Это тупо мемоизация, есть сотни способов реализации этого
Это не только лишь это. Это ещё и проверка интерфейса.
Смотри:
function foo() {
...
}
function bar() {
...
}
Да, ты можешь написать подобных файликов на каждую платформоспецифичную реализацию (я не могу сходу придумать пример для PHP и веба, но в другом случае это может быть например кусок игрового движка, который отвечает за создание окошек и обработку ввода - на каждой платформе реализации функций разные, при этом никогда не потребуется работать с более чем одной реализацией одновременно).
Только вот при написании новой реализации придётся постоянно подсматривать в реализации для других платформ - «а какие ещё функции я забыл реализовать». Если же захочется добавить ещё одну функцию, то придётся бегать по всем реализациям и проверять - где эта функция уже добавлена, а где нет (а когда забудем добавить, то будем получать ошибку неизвестной функции в момент вызова - во-первых, вызов некоторых функций может случаться очень редко, во-вторых, сразу может быть не очевидно - не ошибка ли это в вызывающем коде). При работе с этими функциями, чтобы вспомнить параметры, придётся подглядывать в реализацию для конкретной платформы, что тоже не совсем правильно. Наконец, разработка платформонезависимого интерфейса будет происходить неотрывно от написания реализаций, что представляет большой риск притащить в кроссплатформенный интерфейс излишних подробностей.
А можно сделать так:
class AbstractPlatform {
abstract function foo();
abstract function bar();
static function getInstance() {
...
}
}
А затем:
class WindowsPlatform extends AbstractPlatform {
function foo() {
...
}
function bar() {
...
}
}
class LinuxPlatform extends AbstractPlatform {
function foo() {
...
}
function bar() {
...
}
}
Соответственно, getInstance при первом вызове детектит платформу, подгружает нужный класс, создаёт его экземпляр, сохраняет на будущее и возвращает.
Какие мы получаем профиты?
А такие, что теперь кроссплатформенный интерфейс отделён от платформозависимых реализаций. Мы спокойно можем придумать набор функций, абстрагировавшись от конкретных платформ (чтобы потом не притягивать за уши другие платформы, потому что мы заточили наш интерфейс на одну). Когда мы будем реализовывать эти функции в новом классе, умная IDE сразу подскажет нам, какие функции мы должны реализовать, а в крайнем случае смотреть мы будем в абстрактный класс, а не код от другой платформы (рискуя подхватить оттуда лишнего). Когда мы захотим изменить абстрактный интерфейс, то мгновенно увидим появившиеся ошибки не реализованных методов в классах-потомках и точно не забудем добавить их (умная IDE подсветит, в случае компилируемых же языков мы ещё словим ошибки компиляции). Наконец, если таки забудем (и у нас динамический язык), то словим ошибку в момент вызова getInstance, а не в момент вызова нового метода - сразу понятно, что ошибка в реализации, а не в вызывающем коде, плюс ошибка произойдёт сразу, а не когда будут условия для вызова нужного метода (которые могут наступать редко, если метод не очень популярный).
Это самый очевидный для меня пример. Можно придумать ещё, но мне лень.
Исправление KivApple, :
Этот инстанс является глобальной переменной, поэтому ничего нового не даёт
Открою тебе секрет - со времён изобретения процедур ничего принципиально нового в программировании не появлялось. Всё можно реализовать на базе более простых примитивов. Но это не делает ООП и другие вещи ненужными - это синтаксический сахар, с ним код становится выразительнее и понятнее.
Это тупо мемоизация, есть сотни способов реализации этого
Это не только лишь это. Это ещё и проверка интерфейса.
Смотри:
function foo() {
...
}
function bar() {
...
}
Да, ты можешь написать подобных файликов на каждую платформоспецифичную реализацию (я не могу сходу придумать пример для PHP и веба, но в другом случае это может быть например кусок игрового движка, который отвечает за создание окошек и обработку ввода - на каждой платформе реализации функций разные, при этом никогда не потребуется работать с более чем одной реализацией одновременно).
Только вот при написании новой реализации придётся постоянно подсматривать в реализации для других платформ - «а какие ещё функции я забыл реализовать». Если же захочется добавить ещё одну функцию, то придётся бегать по всем реализациям и проверять - где эта функция уже добавлена, а где нет (а когда забудем добавить, то будем получать ошибку неизвестной функции в момент вызова - во-первых, вызов некоторых функций может случаться очень редко, во-вторых, сразу может быть не очевидно - не ошибка ли это в вызывающем коде). При работе с этими функциями, чтобы вспомнить параметры, придётся подглядывать в реализацию для конкретной платформы, что тоже не совсем правильно. Наконец, разработка платформонезависимого интерфейса будет происходить неотрывно от написания реализаций, что представляет большой риск притащить в кроссплатформенный интерфейс излишних подробностей.
А можно сделать так:
class AbstractPlatform {
abstract function foo();
abstract function bar();
static function getInstance() {
...
}
}
А затем:
class WindowsPlatform extends AbstractPlatform {
function foo() {
...
}
function bar() {
...
}
}
class LinuxPlatform extends AbstractPlatform {
function foo() {
...
}
function bar() {
...
}
}
Соответственно, getInstance при первом вызове детектит платформу, подгружает нужный класс, создаёт его экземпляр, сохраняет на будущее и возвращает.
Какие мы получаем профиты?
А такие, что теперь кроссплатформенный интерфейс отделён от платформозависимых реализаций. Мы спокойно можем придумать набор функций, абстрагировавшись от конкретных платформ (чтобы потом не притягивать за уши другие платформы, потому что мы заточили наш интерфейс на одну). Когда мы будем реализовывать эти функции в новом классе, умная IDE сразу подскажет нам, какие функции мы должны реализовать, а в крайнем случае смотреть мы будем в абстрактный класс, а не код от другой платформы (рискуя подхватить оттуда лишнего). Когда мы захотим изменить абстрактный интерфейс, то мгновенно увидим появившиеся ошибки не реализованных методов в классах-потомках и точно не забудем добавить их (умная IDE подсветит, в случае компилируемых же языков мы ещё словим ошибки компиляции). Наконец, если таки забудем, то словим ошибку в момент вызова getInstance, а не в момент вызова нового метода - сразу понятно, что ошибка в реализации, а не в вызывающем коде, плюс ошибка произойдёт сразу, а не когда будут условия для вызова нужного метода (которые могут наступать редко, если метод не очень популярный).
Это самый очевидный для меня пример. Можно придумать ещё, но мне лень.
Исправление KivApple, :
Этот инстанс является глобальной переменной, поэтому ничего нового не даёт
Открою тебе секрет - со времён изобретения процедур ничего принципиально нового в программировании не появлялось. Всё можно реализовать на базе более простых примитивов. Но это не делает ООП и другие вещи ненужными - это синтаксический сахар, с ним код становится выразительнее и понятнее.
Это тупо мемоизация, есть сотни способов реализации этого
Это не только лишь это. Это ещё и проверка интерфейса.
Смотри:
function foo() {
...
}
function bar() {
...
}
Да, ты можешь написать подобных файликов на каждую платформоспецифичную реализацию (я не могу сходу придумать пример для PHP и веба, но в другом случае это может быть например кусок игрового движка, который отвечает за создание окошек и обработку ввода - на каждой платформе реализации функций разные, при этом никогда не потребуется работать с более чем одной реализацией одновременно).
Только вот при написании новой реализации придётся постоянно подсматривать в реализации для других платформ - «а какие ещё функции я забыл реализовать». Если же захочется добавить ещё одну функцию, то придётся бегать по всем реализациям и проверять - где эта функция уже добавлена, а где нет (а когда забудем добавить, то будем получать ошибку неизвестной функции в момент вызова - во-первых, вызов некоторых функций может случаться очень редко, во-вторых, сразу может быть не очевидно - не ошибка ли это в вызывающем коде). При работе с этими функциями, чтобы вспомнить параметры, придётся подглядывать в реализацию для конкретной платформы, что тоже не совсем правильно. Наконец, разработка платформонезависимого интерфейса будет происходить неотрывно от написания реализаций, что представляет большой риск притащить в кроссплатформенный интерфейс излишних подробностей.
А можно сделать так:
class AbstractPlatform {
abstract function foo();
abstract function bar();
static function getInstance() {
...
}
}
А затем:
class WindowsPlatform extends AbstractPlatform {
function foo() {
...
}
function bar() {
...
}
}
class LinuxPlatform extends AbstractPlatform {
function foo() {
...
}
function bar() {
...
}
}
Соответственно, getInstance при первом вызове детектит платформу, подгружает нужный класс, создаёт его экземпляр, сохраняет на будущее и возвращает.
Какие мы получаем профиты?
А такие, что теперь кроссплатформенный интерфейс отделён от платформозависимых реализаций. Мы спокойно можем придумать набор функций, абстрагировавшись от конкретных платформ (чтобы потом не притягивать за уши другие платформы, потому что мы заточили наш интерфейс на одну). Когда мы будем реализовывать эти функции в новом классе, умная IDE сразу подскажет нам, какие функции мы должны реализовать, а в крайнем случае смотреть мы будем в абстрактный класс, а не код от другой платформы (рискуя подхватить оттуда лишнего). Когда мы захотим изменить абстрактный интерфейс, то мгновенно увидим появившиеся ошибки не реализованных методов в классах-потомках и точно не забудем добавить их. Наконец, если таки забудем, то словим ошибку в момент вызова getInstance, а не в момент вызова нового метода - сразу понятно, что ошибка в реализации, а не в вызывающем коде, плюс ошибка произойдёт сразу, а не когда будут условия для вызова нужного метода (которые могут наступать редко, если метод не очень популярный).
Это самый очевидный для меня пример. Можно придумать ещё, но мне лень.
Исправление KivApple, :
Этот инстанс является глобальной переменной, поэтому ничего нового не даёт
Открою тебе секрет - со времён изобретения процедур ничего принципиально нового в программировании не появлялось. Всё можно реализовать на базе более простых примитивов. Но это не делает ООП и другие вещи ненужными - это синтаксический сахар, с ним код становится выразительнее и понятнее.
Это тупо мемоизация, есть сотни способов реализации этого
Это не только лишь это. Это ещё и проверка интерфейса.
Смотри:
function foo() {
...
}
function bar() {
...
}
Да, ты можешь написать подобных файликов на каждую платформоспецифичную реализацию (я не могу сходу придумать пример для PHP и веба, но в другом случае это может быть например кусок игрового движка, который отвечает за создание окошек и обработку ввода - на каждой платформе реализации функций разные, при этом никогда не потребуется работать с более чем одной реализацией одновременно).
Только вот при написании новой реализации придётся постоянно подсматривать в реализации для других платформ - «а какие ещё функции я забыл реализовать». Если же захочется добавить ещё одну функцию, то придётся бегать по всем реализациям и проверять - где эта функция уже добавлена, а где нет (а когда забудем добавить, то будем получать ошибку неизвестной функции в момент вызова - во-первых, вызов некоторых функций может случаться очень редко, во-вторых, сразу может быть не очевидно - не ошибка ли это в вызывающем коде). При работе с этими функциями, чтобы вспомнить параметры, придётся подглядывать в реализацию для конкретной платформы, что тоже не совсем правильно. Наконец, разработка платформонезависимого интерфейса будет происходить неотрывно от написания реализаций, что представляет большой риск притащить в кроссплатформенный интерфейс излишних подробностей.
А можно сделать так:
class AbstractPlatform {
abstract function foo();
abstract function bar();
static function getInstance() {
...
}
}
А затем:
class WindowsPlatform extends AbstractPlatform {
function foo() {
...
}
function bar() {
...
}
}
class LinuxPlatform extends AbstractPlatform {
function foo() {
...
}
function bar() {
...
}
}
Соответственно, getInstance при первом вызове детектит платформу, подгружает нужный класс, создаёт его экземпляр, сохраняет на будущее и возвращает.
Какие мы получаем профиты?
А такие, что теперь кроссплатформенный интерфейс отделён от платформозависимых реализаций. Мы спокойно можем придумать набор функций, абстрагировавшись от конкретных платформ (чтобы потом не притягивать за уши другие платформы, потому что мы заточили наш интерфейс на одну). Когда мы будем реализовывать эти функции в новом классе, умная IDE сразу подскажет нам, какие функции мы должны реализовать, а в крайнем случае смотреть мы будем в абстрактный класс, а не код от другой платформы (рискуя подхватить оттуда лишнего). Когда мы захотим изменить абстрактный интерфейс, то мгновенно увидим появившиеся ошибки не реализованных методов в классах-потомках и точно не забудем добавить их. Наконец, если таки забудем, то словим ошибку в момент вызова getInstance, а не в момент вызова нового метода - сразу понятно, что ошибка в реализации, а не в вызывающем коде, плюс ошибка произойдёт сразу, а не когда будут условия для вызова нужного метода (которые могут наступать редко, если метод не очень популярный).
Исходная версия KivApple, :
Этот инстанс является глобальной переменной, поэтому ничего нового не даёт
Открою тебе секрет - со времён изобретения процедур ничего принципиально нового в программировании не появлялось. Всё можно реализовать на базе более простых примитивов. Но это не делает ООП и другие вещи ненужными - это синтаксический сахар, с ним код становится выразительнее и понятнее.
Это тупо мемоизация, есть сотни способов реализации этого
Это не только лишь это. Это ещё и проверка интерфейса.
Смотри:
function foo() {
...
}
function bar() {
...
}
Да, ты можешь написать подобных файликов на каждую платформоспецифичную реализацию (я не могу сходу придумать пример для PHP и веба, но в другом случае это может быть например кусок игрового движка, который отвечает за создание окошек и обработку ввода - на каждой платформе реализации функций разные, при этом никогда не потребуется работать с более чем одной реализацией одновременно).
Только вот при написании новой реализации придётся постоянно подсматривать в реализации для других платформ - «а какие ещё функции я забыл реализовать». Если же захочется добавить ещё одну функцию, то придётся бегать по всем реализациям и проверять - где эта функция уже добавлена, а где нет (а когда забудем добавить, то будем получать ошибку неизвестной функции в момент вызова - во-первых, вызов некоторых функций может случаться очень редко, во-вторых, сразу может быть не очевидно - не ошибка ли это в вызывающем коде). При работе с этими функциями, чтобы вспомнить параметры, придётся подглядывать в реализацию для конкретной платформы, что тоже не совсем правильно. Наконец, разработка платформонезависимого интерфейса будет происходить неотрывно от написания реализаций, что представляет большой риск притащить в кроссплатформенный интерфейс излишних подробностей.
А можно сделать так:
class AbstractPlatform {
abstract function foo();
abstract function bar();
static function getInstance() {
...
}
}
А затем:
class WindowsPlatform extends Platform {
function foo() {
...
}
function bar() {
...
}
}
class LinuxPlatform extends Platform {
function foo() {
...
}
function bar() {
...
}
}
Соответственно, getInstance при первом вызове детектит платформу, подгружает нужный класс, создаёт его экземпляр, сохраняет на будущее и возвращает.
Какие мы получаем профиты?
А такие, что теперь кроссплатформенный интерфейс отделён от платформозависимых реализаций. Мы спокойно можем придумать набор функций, абстрагировавшись от конкретных платформ (чтобы потом не притягивать за уши другие платформы, потому что мы заточили наш интерфейс на одну). Когда мы будем реализовывать эти функции в новом классе, умная IDE сразу подскажет нам, какие функции мы должны реализовать, а в крайнем случае смотреть мы будем в абстрактный класс, а не код от другой платформы (рискуя подхватить оттуда лишнего). Когда мы захотим изменить абстрактный интерфейс, то мгновенно увидим появившиеся ошибки не реализованных методов в классах-потомках и точно не забудем добавить их. Наконец, если таки забудем, то словим ошибку в момент вызова getInstance, а не в момент вызова нового метода - сразу понятно, что ошибка в реализации, а не в вызывающем коде, плюс ошибка произойдёт сразу, а не когда будут условия для вызова нужного метода (которые могут наступать редко, если метод не очень популярный).