как использовать шаблон веса в составном шаблоне - PullRequest
0 голосов
/ 04 сентября 2018

Я слежу за книгой O'Reilly C # Design Pattern, поэтому я пытаюсь выполнить какое-то собственное упражнение для реализации следующих шаблонов проектирования, но не могу получить ожидаемый результат, чтобы очистить мои сомнения (, какие шаблоны следует реализовать чтобы получить ожидаемый результат )

public interface ICook<T> //Cook Interface
{
    IIngredient Ingredient { get; }

    void Add(ICook<T> cook);
    object Display();
    ICook<T> Find(string name);
    ICook<T> Remove(ICook<T> cook);
}

public interface IIngredient //abstraction of ingredient
{
    string Name { get; }
}

public class Beverage: IIngredient  //same as dish ingredient
{
    private string v;

    public Beverage(string v)
    {
        this.v = v;
    }

    public string Name => v;
}

public class Boil<T> : Cook<T> // kind of decorator
{
    private IIngredient _ingredient;

    public Boil(IIngredient ingredient) : base(ingredient)
    {
        this._ingredient = ingredient;
        base.CookName = "Boil";
    }

    public override object Display()
    {
        return base.Display();
    }
}

public class Cook<T> : ICook<T> //single Component of Composite Pattern
{
    protected string CookName;
    private IIngredient _ingredient;
    public Cook(IIngredient ingredient)
    {
        _ingredient = ingredient;

    }

    public IIngredient Ingredient => _ingredient;
    public void Add(ICook<T> cook)
    {
        throw new Exception("Cannot Add Cook in Cook");
    }

    public virtual object Display()
    {
        return CookName;
    }

    public ICook<T> Find(string name)
    {
        throw new NotImplementedException();
    }



    public ICook<T> Remove(ICook<T> cook)
    {
        throw new NotImplementedException();
    }
}

public class Dish : IIngredient // Kind of Ingredient
{
    private string v;

    public Dish(string v)
    {
        this.v = v;
    }

    public string Name => v;
}

public class Fry<T> : Cook<T> //same as boil class
{
    private IIngredient _ingredient;

    public Fry(IIngredient ingredient) : base(ingredient)
    {
        this._ingredient = ingredient;
        base.CookName = "Fry";
    }
    public override object Display()
    {
        return base.Display();
    }
}

public class Mix<T> : ICook<T> //collection of single components for composite pattern
{
    private IIngredient _name;
    private IList<ICook<T>> cooks;
    public Mix(IIngredient name)
    {
        _name = name;
        cooks = new List<ICook<T>>();

    }



    public IIngredient Ingredient => _name;

    public void Add(ICook<T> cook)
    {
        cooks.Add(cook);
    }

    public object Display()
    {
        return new { Ingredients = cooks.Select(c => c.Ingredient).Distinct(), cooks = cooks.Select(c => c.Display()) };
    }

    public ICook<T> Find(string name)
    {
        throw new NotImplementedException();
    }



    public ICook<T> Remove(ICook<T> cook)
    {
        throw new NotImplementedException();
    }
}



internal class Program
{
    private static void Main(string[] args)
    {
        IIngredient raw = new Dish("Basic");
        IIngredient egg = new Dish("Chiken Egg");
        IIngredient bread = new Dish("Oat Bread");
        IIngredient milk = new Beverage("Milk");
        ICook<IIngredient> cook = new Mix<IIngredient>(raw);
        cook.Add(new Boil<IIngredient>(egg));
        cook.Add(new Fry<IIngredient>(egg));
        cook.Add(new Boil<IIngredient>(milk));
        cook.Add(new Fry<IIngredient>(bread));
        Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(cook.Display()));     
    }


}

Фактический вывод

{
  "Ingredients": [
    {
      "Name": "Chiken Egg"
    },
    {
      "Name": "Milk"
    },
    {
      "Name": "Oat Bread"
    }
  ],
  "cooks": [
    "Boil",
    "Fry",
    "Boil",
    "Fry"
  ]
}

Исключение составляет

{
  "Ingredients": [
    {
      "Name": "Chiken Egg"
    },
    {
      "Name": "Milk"
    },
    {
      "Name": "Oat Bread"
    }
  ],
  "cooks": [
    {
      "Ingredients": [
        {
          "Name": "Chiken Egg"
        }
      ],
      "cooks": [
        "Boil",
        "Fry"
      ]
    },
    {
      "Ingredients": [
        {
          "Name": "Milk"
        }
      ],
      "cooks": [
        "Boil"
      ]
    },
    {
      "Ingredients": [
        {
          "Name": "Oat Bread"
        }
      ],
      "cooks": [
        "Fry"
      ]
    }
  ]
}

и как использовать шаблон flyweight, чтобы свести к минимуму создание одинаковых объектов для небольших приложений

...