ההיררכיה שציירת היא היררכיית מופעים, לא מחלקות. ייתכן שיש בחלה גם היררכיית מחלקות, אבל בא נניח שאין.
במקרה כזה אתה צריך לעבוד כמו שהעלית את האפשרות עם מאפיינים המצביעים על האב/ילדים/אחים.
הנה דוגמה בסיסית:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var israel = new State();
var Jerusalem = new City (israel);
var Yafo = new Street(Jerusalem);
var MyHome = new Home(Yafo);
Console.WriteLine("My Home is: {0}", MyHome);
Console.WriteLine("My Street is: {0}", MyHome.Street );
Console.WriteLine("My City is: {0}", MyHome.Street.City );
Console.WriteLine("My State is: {0}", MyHome.Street.City.State);
}
}
class State { }
class City
{
public State State { get; set; }
public City(State state)
{
State = state;
}
}
class Street
{
public City City { get; set; }
public Street(City city)
{
City = city;
}
}
class Home
{
public Street Street { get; set; }
public Home(Street street)
{
Street = street;
}
}
}
בשביל לשלוט על אוספי המדינות וכו' כמו שאמרת למנוע יצירת כפולים וכדומה הרעיון של סינגלטון דומה למה שצריך לעשות. צריך לעשות אוסף פנימי של כל המדינות, ויצירה של מדינה חדשה היא רק ע"י פונקציה סטטית שחברה במחלקת המדינות. הנה הצעת הגשה:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var state = State.GetState("israel");
...
}
}
class State
{
private State() {} //בנאי פרטי מונע יצירת חדשים בדומה לסינגלטון
//אוסף פנימי מסוג המופע עצמו - אוסף מדינות
static Dictionary<string, State> StateCollection = new Dictionary<string, State>();
//פונקציה ציבורית לקבלת מדינה (קיימת או לא)
public static State GetState(string name)
{
State result;
if(StateCollection.TryGetValue(name, out result) == false)
{
result = new State(); //מתוקף היות הפונקציה בתוך המחלקה היא רשאית לבנות חדש
StateCollection.Add(name, result);
}
return result;
}
}
}
כמובן שבמקרה אמיתי נכלול במדינה מאפיין עבור שמה ("Israel") ולא נסתמך על הKEY שמחזיק אותה (או שם המשתנה כמו בדוגמאות שלי...).
היררכיית ירושה לא משקפת כלל את הקשר בין המופעים, אלא את הדימיון/נגזרות בין הג'ובים של כל חלק (מחלקה) בתוכנה. מאוד ייתכן (ממש לא מוכרח) שתהיה כאן איזושהי היררכיית ירושה, אבל ממש בלי קשר להיררכיית המופעים. כלומר ייתכן שדוקא מדינה תירש מרחוב - הכל לפי המאפיינים והמתודות האופייניים למחלקות אלו. זה בעצם היררכיית זמן עיצוב. נניח בדוגמה האחרונה גם לרחוב יפו וגם לבית שם יש אותה מדינה בזמן ריצה, אבל אין להם משותף כלל מבחינת זמן העיצוב. הדמיון שכן אפשר למצוא ביניהם, זה למשל שלשתיהם יש מאפיין של מיקום במפה.
אם רוצים שלכל ההיררכיה יהיו מאפיינים ישירים לסבותיהם (אולי זה מה שהתכוונת, סליחה שלקח לי זמן להבין), אז יש כאן מקום להיררכיית זמן עיצוב: גם למחלקת רחוב וגם למחלקת בית יש מאפיין בשם מדינה. אפשר לחסוך את החזרה על הלוגיקה של הצהרת המאפיין ואתחולו גם ברחוב וגם בבית. משהו כזה:
class City
{
public State State { get; set; }
public City(State state)
{
State = state;
}
}
class Street : City
{
public City City { get; set; }
public Street(City city) : base (city.State )
{
City = city;
}
}
class Home : Street
{
public Street Street { get; set; }
public Home(Street street) : base (street.City)
{
Street = street;
}
}
ואז כשיש לנו ביד בית, ואנו רוצים לדעת את מדינתו, במקום לכתוב כמו למעלה ככה:
Console.WriteLine("My State is: {0}", MyHome.Street.City.State);
נוכל לכתוב ישירות:
Console.WriteLine("My State is: {0}", MyHome.State);
על אף שלא כתבנו מאפיין State במחלקת Home, וזה אודות לירושה.
סליחה על הדרשה, ובהצלחה!
פורסם במקור בפורום CODE613 ב13/05/2014 15:26 (+03:00)