2015-09-17 5 views
2

У меня проблемы с дизайном классов сейчас. Вопрос заключается в следующем:Как создать классы с ООП?

Я хочу разработать классы для фруктов и соковыжималки. Занятия для фруктов (Apple, грушевый персик) выполнены. Теперь я хочу разработать классы для соковыжималки.

Требование соковыжималки являются:

1.Juicers принять конкретные фрукты (яблоко, груша, персик) и производят сок. ПРИМЕЧАНИЕ. Может быть смешанный сок (например, аромат яблони и груши).

2.Высокий соковыжималка может производить только один вид сока.

3.Juicers имеет место для хранения фруктов, и мы можем знать, сколько яблок или груш все еще там. (Мы предполагаем, что каждый раз, когда одна соковыжималка использует одно яблоко или грушу).

Может ли кто-нибудь дать мне несколько советов?

ответ

0

Ответ Марка довольно хорош и хороший старт ... Я бы немного расширил. Я, вероятно, не буду использовать массив для фруктов, так как вы будете добавлять, удалять и т. Д. ... возможно, проще реализовать со списком или похожим. Кроме того, Лэйн говорит, что ему нужно несколько фруктов в некоторых соковыжималках .. это немного усложняет ситуацию и дает нам некоторые решения.

Если он всегда будет не более двух плодов, я бы, вероятно, просто сделать два Соковыжималка классы, аналогичные тем, в ответ Марка:

public interface IFruit 
{ 
    string Name {get;} 
} 

public class Apple : IFruit 
{ 
    public string Name { get {return "Apple";} } 
} 

public class Pear : IFruit 
{ 
    public string Name { get {return "Pear";} } 
} 

public class Juicer<IFruit> 
{ 
    private IList<IFruit> fruits; 

    public Juicer(IList<IFruit> fruits) 
    { 
     this.fruits = fruits; 
    } 

    public int FruitCount 
    { 
     get { return this.fruits.Count; } 
    } 

    // Other members can go here... 
} 


public class TwoFruitJuicer<IFruit, IFruit2> 
{ 
    private IList<IFruit> fruits; 
    private IList<IFruit2> fruits2; 

    public TwoFruitJuicer(IList<IFruit> fruits, IList<IFruit2> fruits2) 
    { 
     this.fruits = fruits; 
     this.fruits2 = fruits2; 
    } 

    public int FruitCount 
    { 
     get { return this.fruits.Count + this.fruits2.Count; } 
    } 

    // Other members can go here... 
} 

Но, говорят, что вы хотели 3 или 4 различных соковыжималки комбинированные .. ,

public class MulitJuicer 
{ 
    private IList<Juicer<IFruit>> _juicers; 

    public MulitJuicer(IList<Juicer<IFruit>> juicers) 
    { 
     this._juicers = juicers;  
    } 

    public int FruitCount 
    { 
     get { 

      int allFruitCount = 0; 

      foreach (var j in _juicers) 
      { 
       allFruitCount += j.FruitCount; 
      } 

      return allFruitCount; 
     } 
    } 
} 

Однако, это, вероятно, будет довольно трудно использовать, много списков внутри списков для отслеживания создания и этажерки ... что, если вы хотите только один раз соковыжималки, что вы могли бы просто сбросить кучу фруктов в? Мы можем использовать Reflection, чтобы убедиться, что только разрешенные фрукты положить в соковыжималку:

public class MultiFruitJuicer 
{ 
    private IList<Type> _juiceTypes; 
    private IList<IFruit> _fruits; 

    public MultiFruitJuicer(IList<Type> juiceTypes, IList<IFruit> fruits) 
    { 
     _juiceTypes = juiceTypes; 
     _fruits = fruits; 

     if (!ValidateFruits()) 
     { 
      //you may not want to actually throw here... 
      throw new Exception("Not all proper fruit types"); 
     } 
    } 

    public bool ValidateFruits() 
    { 
     //there are about a million ways to do this... this is probably not the best... 
     foreach(var f in _fruits) 
     { 
      if (!_juiceTypes.Contains(f.GetType())) 
      { 
       return false; 
      } 
     } 

     return true; 
    } 

    public int FruitCount 
    { 
     get { return this._fruits.Count; } 
    } 
} 
0

Я хотел бы начать с реализации Builder design pattern для классов дизайна

для соковыжималки

Это поможет вам построить сложный объект (сок) и отделить его представление, так что же процесс строительства может создавать различные представления (виды соков).

Добавьте интерфейс (IFruit) и базовый класс (общий код для веса, размера и т.д.) к

классов для фруктов (яблоко, груша персик)

Каждый Соковыжималка будет

ICollection<IFruit> fruits 

, которым можно управлять - .Count(), .Add(IFruit) или .Remove(IFruit).

+0

Две вещи, которые заставили меня downvote этот ответ был ** а) ** unbased рекомендация Singleton в 2015 году ** б) ** Там в нет никаких указаний на то, что принудительное использование плодов под общим интерфейсом и/или базовым классом оправдано. Это имеет недостаток в закрытии доступа соковыжималки из добавленных типов, не зная этого кода. Во всяком случае, я бы ожидал, что доступ к типовым соковыжималкам будет стираться с типом, что рекомендует другой ответ. –

+0

@bartek Интерфейс 'Fruit' будет следить за тем, чтобы при добавлении новых типов фруктов остальная часть кода по-прежнему будет работать с ним -' Соковыжималка'. Более того, это позволит вам иметь коллекцию фруктов. Базовый класс поможет избежать повторения общего для всех полей, свойств, методов. – ekostadinov

+0

Но это также означает, что вы не сможете адаптировать любые классы, которые не наследуются от интерфейса Fruir или реализации фруктов, без написания сложных адаптеров, чего можно избежать с помощью дженериков. –

1

Если ваш язык поддерживает generics (как C# и Java), самое простое решение было бы сделать Соковыжималку родовой:

public class Juicer<T> 
{ 
    private T[] fruits; 

    public Juicer(T[] fruits) 
    { 
     this.fruits = fruits; 
    } 

    public FruitCount 
    { 
     get { return this.fruits.Length; } 
    } 

    // Other members can go here... 
} 

Вы можете создать один объект, который в Juicer<Apple>, еще как Juicer<Pear> и скоро. A Juicer<Apple> может содержать только Apple объектов и т. Д.

+0

Одним из требований было смешанный сок, поэтому потребуются генераторы переменной длины (например, шаблоны C++ 11 или, по крайней мере, ручное расширение до разумного числа параметров). Или, может быть, это может быть сформировано путем создания двух обычных соковыжималок вместе, но это довольно непонятно из Q, я думаю. –

Смежные вопросы