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.
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; }
}
}
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).
Related
I humbly ask for help in order to solve this problem. I successfully take a quick guide to learn more about save and load state of the game. Basically first, I know how to use PlayerPrefsto store basic string, int, and float.
Now, looking for a more effective way to store saved files via serialization. At first, after my first few researches online, I watch some video tutorial and only provides storing basic fields (int, string, bool, float, etc.) and saved in a created file. I attempt to try it on classes but didn't worked unless I marked as [Serializable].
Next, trying to save Gameobject created, prefabs or not, didn't work and it requires to serialize that class itself that is "GameObject". I took first attempt using this guide from StackOverflow with the accepted answer, I do understand and saving a GameObject or other custom classes require to store it and converted into .xml file.
Here's my two main problem need to resolve. the first one is that the runtime returned NullPointerException after I ensured all of the necessary objects are created as new. The error stopped at this line (ask for more code source if you need):
DataContractSerializer ds = new DataContractSerializer (data2.GetType ()); // --> Serialize to .xml file.
MemoryStream stream = new MemoryStream();
ds.WriteObject (stream, data2); // --> The error stops here.
stream.Seek (0, SeekOrigin.Begin);
file.Write (stream.GetBuffer (), 0, stream.GetBuffer ().Length);
file.Close();
As you can see, this is the part of the code where you can save and stored in a file created on a persistent file directory for the stored classes such as GameObject, List, and/or other custom classes.
The second problem will be tackled after the first problem is resolved. The second problem involves loading last state saved. For the normal fields such as integer or string, using BinaryFormatter and FileStream works well to load stored values form a file created last time. I tried that on stored custom classes such as GameObject but it required a different method like this one but it is a bit hard to understand how to translate it in Unity and still observe some ways to work it out, the best way to load stored classes from a file.
Here is the class I'm trying to deserialize a class that contains the following fields inside.
[DataContract]
public class TreeData2 {
// - - - Spouse - - -
[DataMember] private List<GameObject> _masters;
public List<GameObject> masters {
get { return _masters; }
set { _masters = value; }
}
[DataMember] private List<GameObject> _targets;
public List<GameObject> targets {
get { return _targets; }
set { _targets = value; }
}
[DataMember] private List<FamilyDatabase> _familyGroup;
public List<FamilyDatabase> familyGroup {
get { return _familyGroup; }
set { _familyGroup = value; }
}
[DataMember] private GameObject _node;
public GameObject node {
get { return _node; }
set { _node = value; }
}
[DataMember] private List<string> _mothers;
public List<string> mothers {
get { return _mothers; }
set { _mothers = value; }
}
[DataMember] private List<string> _fathers;
public List<string> fathers {
get { return _fathers; }
set { _fathers = value; }
}
[DataMember] private List<GenerationDatabase> _genDb;
public List<GenerationDatabase> genDb {
get { return _genDb; }
set { _genDb = value; }
}
// - - - Root Action - - -
[DataMember] private List<GameObject> _child;
public List<GameObject> child {
get { return _child; }
set { _child = value; }
}
// Gen Database (Main)
[DataMember] private List<string> _mothersDB;
public List<string> mothersDB {
get { return _mothersDB; }
set { _mothersDB = value; }
}
[DataMember] private List<string> _fathersDB;
public List<string> fathersDB {
get { return _fathersDB; }
set { _fathersDB = value; }
}
[DataMember] private List<GameObject> _mastersDB;
public List<GameObject> mastersDB {
get { return _mastersDB; }
set { _mastersDB = value; }
}
[DataMember] private List<GameObject> _targetsDB;
public List<GameObject> targetsDB {
get { return _targetsDB; }
set { _targetsDB = value; }
}
[DataMember] private List<string> _mothersT;
public List<string> mothersT {
get { return _mothersT; }
set { _mothersT = value; }
}
[DataMember] private List<string> _fathersT;
public List<string> fathersT {
get { return _fathersT; }
set { _fathersT = value; }
}
[DataMember] private List<GameObject> _mastersT;
public List<GameObject> mastersT {
get { return _mastersT; }
set { _mastersT = value; }
}
[DataMember] private List<GameObject> _targetsT;
public List<GameObject> targetsT {
get { return _targetsT; }
set { _targetsT = value; }
}
}
data2 is the variable name of the TreeData2 class and yes I'm making a family tree like structure via Unity for the game that shows progress of unlocking and storing lists of the branches. Here's the recap with the mentioned variable name while serializing GameObject and List classes.
FileStream file = File.Create (Application.persistentDataPath + "/check/treeData2.dat");
TreeData2 data2 = new TreeData2();
. . .
DataContractSerializer ds = new DataContractSerializer (data2.GetType ());
MemoryStream stream = new MemoryStream();
ds.WriteObject (stream, data2); // --> Error stops here. Returns NullPointerException due to failed in parsing in .xml file in storing GameObject classes and List<T>.
stream.Seek (0, SeekOrigin.Begin);
file.Write (stream.GetBuffer (), 0, stream.GetBuffer ().Length);
file.Close();
string result = XElement.Parse(Encoding.ASCII.GetString(stream.GetBuffer()).Replace("\0", "")).ToString();
print ("SAVE TREE COMPLETE");
print ("Result: " + result);
Redirect from this original question from Game Development.
Let me start with clearing a confusion I find so often. 'Serializable' will serialize a class for display in inspector only. You can say that it will serialize your class into a format that can be represented by inspector. Often, serialize means convert into byte arrays, it doesn't have to be a byte array, it can be any other format, e.g. strings.
Unity does not allow you to save your gameobjects directly, however, it doesn't stop you from recreating them to reflect some previous state. A gameobject may have so many components, e.g. MeshRenderer, Camera, etc, and it could get rough serializing all that down, imagine some big hierarchy!.
Generally, you want to separate your behaviors from data, i.e. your MonoBehavior from model/data (not 3d model), its a common OOP practice. You can come up with how you can save and retrieve some data from disk. I used Json.Net to serialize my data models into json. That gave me flexibility to save it locally as well as send it over network, but its just an example.
For an example, if I had to serialize a user's inventory, I would make a class like this:
[Serializable]
public class Inventory
{
public List<InventoryItem> _items;
// Some serializable and transient variables
}
[Serializable]
public class InventoryItem
{
// Some serializable and transient variables
}
Then my Monobehaviour that would show inventory would look like this:
public class InventoryView : MonoBehaviour
{
public Inventory _inventory; //Now the inventory items show in the inspector also, because it is serialized.
void createViewFromInventory()
{ //... }
}
And now, anywhere I have reference to an Inventory object, I can serialize it however I wish to do so. With Json.Net, all I had to do looked something like this:
Inventory inv = getInventoryRef(); // get inventory here
string serializedInv = JsonConvert.Serialize(inv); // It converts it into json.
PlayerPrefs.Save("inventory", serializedInv); //
And in order to retrieve the saved inventory, I would do something like this:
void loadInventory()
{
string invStr = PreferPrefs.GetString("inventory");
Inventory inv = JsonConvert.Deserialize<Inventory>(invStr);
}
This way, monobehavior view classes need only ACT upon inventory state, but not save other components on the gameobject. Hope it helps.
Unfortunately, after several experiments to find the easy way to store GameObjects effectively without hassle, there is no shortcut in preserving files + game objects during save and load state. I decided to give up for banging my head too hard to go crazy in making expectations on saving scene in one go. There are many steps to understand it.
Right now, storing info on each game object's specified sections/components require complex serializable classes, a meticulous way for sharing and retrieving each part of data. Explanation on this link and for more effective way in preserving data (but still not on game object) via formatting into JSON file.
It is a wise choice to make a better roadmap for tracking last state from scratch if you want to make your own save/load state for both common variables, serializable classes, and game object.
However, there is another way to save and load GameObject using this solution found on this Unity Q&A section. It discusses about "SerializerHelper" that lets you serialize not only serialized classes but also game objects, scenes and other non-serializable classes. Check this forum as well in order to understand how it works. You can try this Unity package to try out saving/loading GO here to download. (Requires to register Dropbox account if needed.)
please, help me to figure out how to write the query :)
The code is:
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
var man = new Man("Joe");
Console.WriteLine(man.ToString());
}
}
public class SuperMan
{
public SuperMan(string name)
{
this.name = name;
}
public override string ToString()
{
return name;
}
string name;
}
public class Man : SuperMan
{
public Man(string name) : base(name)
{
}
}
}
I want to find all direct and indirect dependencies (methods) to Man.ToString(). There is only one call in Main() method.
The query I'm trying is:
from m in Methods
let depth0 = m.DepthOfIsUsing("ConsoleApplication1.SuperMan.ToString()")
where depth0 >= 0 orderby depth0
select new { m, depth0 }.
but it doesn't find dependent Program.Main() method....
How to modify query so that it finds usages for such kind of methods?
First let's look at direct callers. We want to list all methods that calls SuperMan.ToString() or any ToString() methods overriden by SuperMan.ToString(). It can looks like:
let baseMethods = Application.Methods.WithFullName("ConsoleApplication1.SuperMan.ToString()").Single().OverriddensBase
from m in Application.Methods.UsingAny(baseMethods)
where m.IsUsing("ConsoleApplication1.Man") // This filter can be added
select new { m, m.NbLinesOfCode }
Notice we put a filter clause, because in the real world pretty much every method calls object.ToString() (this is a particular case).
Now to handle indirect calls this is more tricky. We need to call the magic FillIterative() extension methods on generic sequences.
let baseMethods = Application.Methods.WithFullName("ConsoleApplication1.SuperMan.ToString()").Single().OverriddensBase
let recursiveCallers = baseMethods.FillIterative(methods => methods.SelectMany(m => m.MethodsCallingMe))
from pair in recursiveCallers
let method = pair.CodeElement
let depth = pair.Value
where method.IsUsing("ConsoleApplication1.Man") // Still same filter
select new { method , depth }
Et voilĂ !
I have a method which i'd like to refactor
Basically i want to split the top level method in a abstract and a final part.
The method in question is overridden in quite a few places where additional functionality is added, but eventualy the super call is always made.
The code now basically look like:
(not all Extending classes override but those that do, do it this way)
class Base {
public Object getStuff(String key) {
out = //code to get data from the Database.
return out
}
class Extended1 extends Base {
public Object getStuff(String key) {
if("some_non_db_value".equals(key)) {
return "some custom stuff";
}
return super.getStuff(key);
}
}
What i'd like as a result would be something like:
class Base {
public final Object getStuff(String key) {
out = getCustom(key);
if(out != null) {
return custom;
}
out = //code to get data from the Database.
return out
}
public abstract Object getCustom(String key);
}
class Extended1 extends Base {
public Object getCustom(String key) {
if("some_non_db_value".equals(key)) {
return "some custom stuff";
}
return null;
}
}
I was hoping there would be a refactor action (or partial refactor) to get to (or closer to) this point.
I would first rename getStuff() to getCustom() which would take care of all the extended classes. Then changing the Base class should be relatively easy.
Recently i was asked to prove the power of C# 3.0 in a single line( might be tricky)
i wrote
new int[] { 1, 2, 3 }.Union(new int[]{10,23,45}).
ToList().ForEach(x => Console.WriteLine(x));
and explained you can have (i) anonymous array (ii) extension method (iii)lambda and closure all in a single line.I got spot offer.
But.....
The interviewer asked me how will you convert an anonymous type into known type :(
I explained
public class Product
{
public double ItemPrice { private set; get; }
public string ItemName { private set; get; }
}
var anony=new {ItemName="xxxx",ItemPrice=123.56};
you can't assign product a=anony;
The interviewer replied there is 200% chance to do that
if you have a small work around.I was clueless.
As usual,I am waiting for your valuable reply(Is it possible?).
You're right, you can't make this assignment:
product a=anony;
MSDN: Anonymous Types (C# Programming Guide)
An anonymous type cannot be cast to
any interface or type except for
object.
Maybe something like this:
class Program
{
static T Cast<T>(object target, T example)
{
return (T)target;
}
static object GetAnon()
{
return new { Id = 5 };
}
static void Main()
{
object anon = GetAnon();
var p = Cast(anon, new { Id = 0 });
Console.WriteLine(p.Id);
}
}
Remark: never write or rely on such a code.
May be try the examples shown here..they try to do something similar..
http://www.codeproject.com/KB/linq/AnonymousTypeTransform.aspx
http://www.inflecto.co.uk/Inflecto-Blog/post/2009/11/12/IQueryable-Sorting-Paging-Searching-and-Counting.aspx
var list = anony.Select(x=> new Product {
ItemPrice = x.ItemPrice, ItemName = x.ItemName }).ToList();
How would you refactor these two classes to abstract out the similarities? An abstract class? Simple inheritance? What would the refactored class(es) look like?
public class LanguageCode
{
/// <summary>
/// Get the lowercase two-character ISO 639-1 language code.
/// </summary>
public readonly string Value;
public LanguageCode(string language)
{
this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
}
public static LanguageCode TryParse(string language)
{
if (language == null)
{
return null;
}
if (language.Length > 2)
{
language = language.Substring(0, 2);
}
try
{
return new LanguageCode(language);
}
catch (ArgumentException)
{
return null;
}
}
}
public class RegionCode
{
/// <summary>
/// Get the uppercase two-character ISO 3166 region/country code.
/// </summary>
public readonly string Value;
public RegionCode(string region)
{
this.Value = new RegionInfo(region).TwoLetterISORegionName;
}
public static RegionCode TryParse(string region)
{
if (region == null)
{
return null;
}
if (region.Length > 2)
{
region = region.Substring(0, 2);
}
try
{
return new RegionCode(region);
}
catch (ArgumentException)
{
return null;
}
}
}
It depends, if they are not going to do much more, then I would probably leave them as is - IMHO factoring out stuff is likely to be more complex, in this case.
Unless you have a strong reason for refactoring (because you are going to add more classes like those in near future) the penalty of changing the design for such a small and contrived example would overcome the gain in maintenance or overhead in this scenario. Anyhow here is a possible design based on generic and lambda expressions.
public class TwoLetterCode<T>
{
private readonly string value;
public TwoLetterCode(string value, Func<string, string> predicate)
{
this.value = predicate(value);
}
public static T TryParse(string value, Func<string, T> predicate)
{
if (value == null)
{
return default(T);
}
if (value.Length > 2)
{
value = value.Substring(0, 2);
}
try
{
return predicate(value);
}
catch (ArgumentException)
{
return default(T);
}
}
public string Value { get { return this.value; } }
}
public class LanguageCode : TwoLetterCode<LanguageCode> {
public LanguageCode(string language)
: base(language, v => new CultureInfo(v).TwoLetterISOLanguageName)
{
}
public static LanguageCode TryParse(string language)
{
return TwoLetterCode<LanguageCode>.TryParse(language, v => new LanguageCode(v));
}
}
public class RegionCode : TwoLetterCode<RegionCode>
{
public RegionCode(string language)
: base(language, v => new CultureInfo(v).TwoLetterISORegionName)
{
}
public static RegionCode TryParse(string language)
{
return TwoLetterCode<RegionCode>.TryParse(language, v => new RegionCode(v));
}
}
This is a rather simple question and to me smells awefully like a homework assignment.
You can obviously see the common bits in the code and I'm pretty sure you can make an attempt at it yourself by putting such things into a super-class.
You could maybe combine them into a Locale class, which stores both Language code and Region code, has accessors for Region and Language plus one parse function which also allows for strings like "en_gb"...
That's how I've seen locales be handled in various frameworks.
These two, as they stand, aren't going to refactor well because of the static methods.
You'd either end up with some kind of factory method on a base class that returns an a type of that base class (which would subsequently need casting) or you'd need some kind of additional helper class.
Given the amount of extra code and subsequent casting to the appropriate type, it's not worth it.
Create a generic base class (eg AbstractCode<T>)
add abstract methods like
protected T GetConstructor(string code);
override in base classes like
protected override RegionCode GetConstructor(string code)
{
return new RegionCode(code);
}
Finally, do the same with string GetIsoName(string code), eg
protected override GetIsoName(string code)
{
return new RegionCode(code).TowLetterISORegionName;
}
That will refactor the both. Chris Kimpton does raise the important question as to whether the effort is worth it.
I'm sure there is a better generics based solution. But still gave it a shot.
EDIT: As the comment says, static methods can't be overridden so one option would be to retain it and use TwoLetterCode objects around and cast them, but, as some other person has already pointed out, that is rather useless.
How about this?
public class TwoLetterCode {
public readonly string Value;
public static TwoLetterCode TryParseSt(string tlc) {
if (tlc == null)
{
return null;
}
if (tlc.Length > 2)
{
tlc = tlc.Substring(0, 2);
}
try
{
return new TwoLetterCode(tlc);
}
catch (ArgumentException)
{
return null;
}
}
}
//Likewise for Region
public class LanguageCode : TwoLetterCode {
public LanguageCode(string language)
{
this.Value = new CultureInfo(language).TwoLetterISOLanguageName;
}
public static LanguageCode TryParse(string language) {
return (LanguageCode)TwoLetterCode.TryParseSt(language);
}
}