
Steven
24.11.2016
16:42:15
Ну, в конкретно взятой ситуации...

Sergey
24.11.2016
16:44:15
я не могу придумать ни одного кейса где наследование единственно вервый выбор
не в 2016-ом году
когда памяти хоть жопой жуй

Google

Steven
24.11.2016
16:44:59
А кто сказал, что единственно верный выбор существует?
Парадигмы можно бесконечно придумывать и всех будут недостатки.

Sergey
24.11.2016
16:50:55
окей, просто не могу придумать кейса где наследование однозначно лучше чем композиция.
мы уже в нашей команде вводим правило что extends в коде надо обосновать.

Sergey
24.11.2016
16:52:42
так же как и protected)

Steven
24.11.2016
16:53:39
На кулаках?)

Sergey
24.11.2016
16:55:29
по понятиям

Steven
24.11.2016
16:57:03
Жестко у вас там.
Это мы еще даже до инкапсуляции не добрались.
Там тоже можно пояснять.

Sergey
24.11.2016
17:06:46
ну и в целом вот эти загоны про типы это как раз про инкапсуляцию
инкапсуляция - важный принцип, причем никакого отношения к ООП он не имеет. он просто важный. Наследование - ненужный механизм.

Google

Sergey
24.11.2016
17:07:37
полиморфизм - тоже присущ не только ооп, это тоже про типы
а ООП это message passing (инкапсуляция) и late binding (полиморфизм).

Aleh
24.11.2016
17:18:52
я не до конца понимаю, зачем они вообще ввели понятие интерфейса(уже было понятие type), но есть как есть
как жить когда все immutable?
@fes0r этот Егор за AR топит
active record который

Sergey
24.11.2016
18:02:54

Aleh
24.11.2016
18:03:33

Sergey
24.11.2016
18:03:57
Есть спор Егорки и чувака из Spring
где они размышляют на тему "чье ООП круче"

Aleh
24.11.2016
18:04:08
сложна

Sergey
24.11.2016
18:06:39
https://www.youtube.com/watch?v=Y-16C5yhKLo

Aleh
24.11.2016
19:47:55
https://gbracha.blogspot.com.by/2007/06/constructors-considered-harmful.html

Sergey
24.11.2016
19:49:36
занятно

Aleh
24.11.2016
19:53:23
ща осознал, что в хаскеле DIP тебя заставляет сам язык соблюдать

Steven
25.11.2016
07:44:04
Какой Сергей? Ненужный для кого? Может, просто у тебя и без него все хорошо, поэтому тебе и не нужен?)

Google

Steven
25.11.2016
07:44:38
Никто часом в Ubisoft не работал?

Aleh
25.11.2016
08:17:23
так же как и protected)

Steven
25.11.2016
08:30:52

Sergey
25.11.2016
09:00:52
сейчас структура примерно такая
User {
Credentials $credentials;
?Customer $customer;
?Merchant $merchant;
Profile $profile;
}
$profile как embeddable структура

Steven
25.11.2016
11:23:37
Хорошо. Получился гибридный объект. В чем преимущество перед тем, если отнаследоваться, например:
User
/ \
Customer Merchant
\ /
CustoMerchant

Sergey
25.11.2016
11:27:32

Sergey
25.11.2016
11:44:52
и это не гибридный объект, это юзер. Он может быть мерчантом, кастомером... у него могут быть новые креды
он может "обновить" профайл

Ilya
25.11.2016
11:48:30
а как с кучей if борешься в таком случае?
if($user->isCustomer()) { ... } else { ... }

Aleh
25.11.2016
11:49:29
полиморфизмом?
$user->doSmth()

Ilya
25.11.2016
11:50:25
а если это действия только для определенного типа
вывываешь и функция ничего не делает?

Aleh
25.11.2016
11:51:02
ну, перед нами юзер и он как-то будучи не того типа это сделал, значит надо кинуть эксепшн
мол как ты сюда вообще попал чувак

Google

Ilya
25.11.2016
11:51:19
я вот не парюсь, юзаю как в симфони сделано
в юзере только маркер роли
а сами роли отдельно
и юзера воспринимаю только как набор крендельков
для базовой проверки доступа к чему-либо
а дальше если есть доступ, оперирую только его id

Sergey
25.11.2016
11:53:41
связи с отдельными обьектами Customer/Merchant + роли да

Steven
25.11.2016
11:53:53
сложна

Admin
ERROR: S client not available

Sergey
25.11.2016
11:54:04
user->isCustomer() или isGranted(User::ROLE_CUSTOMER)

Ilya
25.11.2016
11:54:43
да даже не нужно так проверять, все на уровне beforeAction или подобного

Steven
25.11.2016
11:55:03
Он может быть мерчантом new Merchant();
Он может быть кастомером new Customer();

Fayozjon [CybernatiC]
25.11.2016
11:55:51
MerchantCustomer extends Merchant extends Customer ?
не вариант
?

Steven
25.11.2016
11:56:52
Как отнаследоваться это уже другой вопрос. Тут говорят, что наследование в принципе не надо.

Fayozjon [CybernatiC]
25.11.2016
11:58:01
Тогда придется при условии создавать копию класса внутри
class B {
public function method_from_b($s) {
echo $s;
}
}
class C {
public function method_from_c($s) {
echo $s;
}
}
class A extends B
{
private $c;
public function __construct()
{
$this->c = new C;
}
// fake "extends C" using magic function
public function __call($method, $args)
{
$this->c->$method($args[0]);
}
}
$a = new A;
$a->method_from_b("abc");
$a->method_from_c("def");

Ilya
25.11.2016
11:59:15
сложно

Dmitriy
25.11.2016
11:59:23

Google

Steven
25.11.2016
11:59:44
Если захотеть будет. И вопрос не про пхп.

Sergey
25.11.2016
11:59:51
traits?)
CustomerTrait, MerchantTrait

Steven
25.11.2016
12:00:08
Его делали еще и до трейтов на костылях.

Fayozjon [CybernatiC]
25.11.2016
12:01:03
Остается только тот вариант с гребанным __call

Aleh
25.11.2016
12:01:06
коооомпооозиция

Fayozjon [CybernatiC]
25.11.2016
12:01:13
который я скинул наверху

Aleh
25.11.2016
12:01:15
зачем ты делаешь __call
если мог явно написать method_from_c
?

Fayozjon [CybernatiC]
25.11.2016
12:01:23
:magic:
Еще нашлось вот это
class Extendable{
private $extender=array();
public function addExtender(Extender $obj){
$this->extenders[] = $obj;
$obj->setExtendee($this);
}
public function __call($name, $params){
foreach($this->extenders as $extender){
//do reflection to see if extender has this method with this argument count
if (method_exists($extender, $name)){
return call_user_func_array(array($extender, $name), $params);
}
}
}
}
$foo = new Extendable();
$foo->addExtender(new OtherClass());
$foo->other_class_method();

Steven
25.11.2016
12:08:24
Мне кажется, тут идеологическое отличие. Наследование это иерархия связей, отношения между объектами, а композиция - создание объекта из разрозненных частей. Что-то типо усыновленного ребенка или цыганей.

Sergey
25.11.2016
12:13:59
у тебя может быть $roles
а может быть как у меня и метод getRoles который возвращает что чувак умеет
и да, с наследованием как раз появляются ифы, а когда все разделено на отдельные объекты, я просто там где нужен мерчант даю мерчанта, а там где нужен кастомер - даю кастомера. Где пофигу - даю юзера