Здравствуйте!
Никак не могу определиться, какой подход лучше применить для реализации паттерна стратегия. (может я не тот паттерн выбрал?)
Задача такая. Есть магазин, который продаёт товары. Каждый товар должен продаваться по своему алгоритму. Было решено применить паттерн стратегия. Получилось два варианта. Какой из них более правильный я не пойму. Я приведу оба примера и опишу что смущает.
Вариант 1. Логику продажи каждого товара инкапсулируем в класс магазина, который наследуем от интерфейса:
using System;
public class Program
{
public static void Main()
{
Shop shop = new Shop();
var a = new A("A");
shop.Sell(a);
var b = new B("B");
shop.Sell(b);
}
}
interface IShop
{
void Sell(A a);
void Sell(B b);
}
class baseClass
{
public string Name;
}
class A : baseClass
{
public A(string s)
{
this.Name = s;
}
}
class B : baseClass
{
public B(string s)
{
this.Name = s;
}
}
class Shop : IShop
{
public void Sell(A a)
{
Console.WriteLine("sell AAA"+a.Name);
}
public void Sell(B b)
{
Console.WriteLine("sell BBB"+b.Name);
}
}
Здесь смущает то, что класс магазина будет большой, и должен описывать схему продажи (и не только) каждого товара.
Вариант 2. Логику продажи каждого товара икапсулируем в сам товар:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
List<baseClass> list = new List<baseClass> { new A("A"), new B("B"), new B("B"), new A("A") };
Shop shop = new Shop();
foreach(baseClass item in list)
{
shop.seller = item.seller;
shop.seller.Sell(item);//это эквивалентно item.seller.Sell(item);
}
}
}
class Shop
{
public ISellable seller;
}
interface ISellable
{
void Sell(baseClass a);
}
class baseClass
{
public string Name;
public ISellable seller;
}
class A : baseClass
{
public A(string s)
{
this.Name = s;
seller = new SellerA();
}
}
class B : baseClass
{
public B(string s)
{
this.Name = s;
seller = new SellerB();
}
}
class SellerA : ISellable
{
public void Sell(baseClass a)
{
Console.WriteLine("sell AAA"+a.Name);
}
}
class SellerB : ISellable
{
public void Sell(baseClass b)
{
Console.WriteLine("sell BBB"+b.Name);
}
}
Здесь смущает то, что продаёт-то магазин! А не товар сам себя продаёт! shop.seller.Sell(item); === item.seller.Sell(item); Зачем тогда класс магазина вообще нужен? Нет, ну, конечно, я описываю абстрактную ситуацию, и класс магазина описывает ещё полно всякого поведения и параметров. Но в данном конкретном примере получается, что товар продаёт сам себя. И только искусственно если добавить ссылку в магазин на интервейс, то типа будет выглядеть как-будто продаёт магазин. Ещё смущает то, что нужно присваивать каждый раз нужный интерфейс перед продажей. Ну или не присваивать, а сказать товару, чтобы продал сам себя, а он ещё и ссылку на себя получает.
Я понимаю, что вопрос тот ещё. Но может всё-таки я где-то блуждаю не там?
Что можно сказать про "магазин"? Типов товаров будет немного, всего около 7-8. Ещё магазин должен будет каждый товар уметь принимать на склад, принимать бракованый товар назад, отсылать товар в ремонт и т.д.
Даже этот список дейтсвий помножить на 7 получится ~30 методов в IShop для первого примера. А для второго примера получится, что не магазин управляет товаром, а товар управляет сам собой ...
Лично мне больше нравится второй пример, если б не то обстоятельство, что товар сам себя "обслуживает". Или это нормально? Посоветуйте, пожалуйста, что-нибудь! Может другой паттерн или где-то я ошибся в реализации?
использую c#
Спасибо.