Как красиво решить это с помощью ООП?

Ребзи, подскажите как это красиво решить, с точки зрения ООП.
Дан исходный класс, в котором есть 2 метода: save, delete.
Есть 2-N "типа" материалов, с которыми этот класс может работать. С каждым материалом можно проводить все эти действия, но с каждым нужно делать это по разному. Если подойти к задаче с точки зрения: вот так вот это будет работать, то можно сделать это так:
public function save($one,$type){
if($type == 'type_1'){
//some actions
}elseif($type == 'type_2'){
//else actions
}
}
..

Вполне логично, что это простой и действенный способ, и он долгие годы служил верой и правдой, но(!).
Теперь задача немного расширилась, и "типов" может быть больше чем 2, а следовательно допиливать код таким способом - не комельфо.
Вопрос: Как решить эту задачу с помощью современных техник ООП (интерфейсы, наследование, етц). Что бы для каждого типа можно было просто и легко делать расширение ф-ционала, скажем, добавлением нового класса.
Если вам не сложно, то можно с примерами кода.
// Забыл уточнить. Операции с методами происходят по одному и тому же алгоритму, меняются некоторые данные нужные для записи/чтения, работы по сети (разные параметры post' запроса).
  • Вопрос задан
  • 3211 просмотров
Решения вопроса 1
pavel_salauyou
@pavel_salauyou
Symfony2 & Angular разработчик
наверно в вашем случае нужен паттерн проектирования Фабричный метод.

class MaterialFactory 
{
    public static function build($type)
    {
        // тут генерим путь до класса на основе его типа
        return new $className();
    }
}

class Material
{
    public function save()
    {
        // тут свои действия
    }
}

class SuperMaterial
{
    public function save()
    {
        // тут другие действия
    }
}


потом в вашем методе

public function save($one,$type){
     $obj = MaterialFactory::build($type);
     $obj->save();
}


но схему можно ещё улучшить, всё зависит от текущего вашего кода
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@andfadeev
www.startupfellows.ru - поиск людей в стартапы
Код на джаве, но суть ООП одна и та же. Материал это интерфейс, конкретный материал - его реализация. В методы первого класса подаем интерфейс, дальше работает полиморфизм.

class A {
	void save(Material m) {
		m.save();
	}
	void delete(Material m) {
		m.delete();
	}
}


interface Material {
	void save();
	void delete();
}

class MaterialNumberOne  implements Material  {
	void save() {
		//делаем что нужно для первого материала
	}
	void delete() {
		//делаем что нужно для первого материала
	}
}

class MaterialNumberTwo  implements Material  {
	void save() {
		//делаем что нужно для второго материала
	}
	void delete() {
		//делаем что нужно для второго материала
	}
}


// юзаем так
public static void main(String[] args) {
	Material m1 = new MaterialNumberOne();
	Material m2 = new MaterialNumberTwo();

	A a = new A();
	a.save(m1);
	a.delete(m1);
	a.save(m2);
	a.delete(m2);
}
Ответ написан
akubintsev
@akubintsev
Опытный backend разработчик
interface StorableMaterial
{
    public function save();
}

class Material implements StorableMaterial
{
    public function save()
    {
        // ...
    }
}

class SuperMaterial implements StorableMaterial
{
    public function save()
    {
        // ...
    }
}

А затем в нужно смотреть тот класс, откуда дергается метод save() и работать там с абстракцией в виде интерфейса SavableMaterial, а не конкретным классом
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы