简体   繁体   中英

How to design the classes with OOP?

I have problems about classes design now. The question is as follows:

I want to design classes for fruit and juicer. The classes for fruit (Apple, pear peach) are done. Now I want to design classes for juicer.

The requirement for juicer are:

1.Juicers take specific fruit (apple, pear, peach) and produce juice. NOTE: there may be mixed juice (such as flavor of apple and pear).

2.One kind of juicer can only produce one kind of juice.

3.Juicers have space to store fruit, and we can know how many apples or pears are still there. (We assume that every time one juicer uses one apple or pear).

Could anyone give me some advices?

If your language supports generics (as do C# and Java), the simplest solution would be to make the Juicer generic:

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...
}

You can create one object that's a Juicer<Apple> , another as a Juicer<Pear> , and so on. A Juicer<Apple> can only contain Apple objects, etc.

I would start by implementing Builder design pattern for the

design classes for juicer

It'll help you to construct a complex object (juice) and separate its representation, so that the same construction process can create different representations (kinds of juice).

Add some interface (IFruit) and base class (shared code for Weight, Size etc.) to

classes for fruit (Apple, pear peach)

Each Juicer will have

ICollection<IFruit> fruits

that can be managed - .Count() , .Add(IFruit) or .Remove(IFruit) .

Mark's answer is pretty good and a good start... I'd expand a bit. I probably wouldn't use an array for fruits since you will be adding, removing etc... probably easier to implement with a list or similar. Also, Laine says he wants multiple fruits in some juicers.. that complicates things a bit and gives us some decisions to make.

If it will always be a maximum of two fruits, I would probably just make two juicer classes similar to those in Mark's answer:

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...
}

But, say you wanted 3 or 4 different juicers combined...

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;
        }
    }
}

However, That would probably be pretty difficult to use, a lot of lists inside of lists to keep track of build up and whatnot... what if you wanted just once juicer that you could just dump a bunch of fruits in? We can use Reflection to verify that only allowed fruits are put in the juicer:

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; }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM