[英]what's the name of this design pattern? (if it is one)
我有一堂课,我们称之为“国家”。 它具有各种属性,例如列表状态,年龄等。
在现实生活中,我正在开发一个ASP.NET应用程序,其中用户注册了我们客户提供的服务的订阅。 他们需要填写的此申请表具有许多属性,并且表示数据模型的主要类之一变得过分膨胀,因此我想通过组合将其分成小类,但子类上的属性仍与父类链接类。
对于本示例,为了使事情保持简单,请参考car示例。 因此,我们有一个名为Country的类,如下所示:
public static class WorldDatabase
{
public static List<Country> Countries {get;set;}
}
class Country
{
public int Age {get;set;}
public string Name{get;set;}
public List<State> States{get;set;}
}
class State
{
public string CountryName{get;set;}
public string Capitol{get;set;}
public List<string> Cities{get;set;}
}
现在,创建设置的快速示例:
var states = new List<States>();
states.Add(new State(){CountryName="United States",
StateName="NJ",
Capitol="Trenton"});
WorldDatabase.Countries.Add(new Country{Age=237,
Name="United States",
States=states});
WorldDatabase.Countries[0].Name="US";
//assert obviously fails because the names are not linked
Assert.IsEqual(WorldDatabase.Countries[0].Name == states[0].CountryName);
因此,我要解决的问题是:链接两个属性的最佳方法是什么? 我想出的方法是将父实例(国家/地区)的实例注入到State类中。 但是我担心孩子在不应该给父母的时候做出改变。 另外,似乎有一种方法可以用我不知道的更少的代码来做到这一点。 这是我想出的两种方法:
//does a one-time 'binding'
class State
{
public void BindFrom(Country country)
{
CountryName=country.Name;
}
public string CountryName{get;set;}
public string Capitol{get;set;}
public List<string> Cities{get;set;}
}
//tracks the parent forever
class State
{
private readonly Country _parent;
public State(Country parent)
{
_parent = parent;
}
public string CountryName
{
get
{
return _parent.Name;
}
}
public string Capitol{get;set;}
public List<string> Cities{get;set;}
}
此模式的名称是什么(如果是一个)? 我想阅读更多有关它的信息。还有其他选择吗?
可以使用父类实现/继承的接口或基类解决您的问题。
接口/基类应仅公开希望孩子能够看到或修改的参数。 只有完整的实现才能允许编写。
class CountryBase
{
public string Name { get; protected set; }
}
class Country: CountryBase
{
public string Name { get { return base.Name;} set { base.Name = value;}
}
Country
现在完全可以控制CountryBase.Name
的设置器。 仅将CountryBase
传递给您的State
实例。
或者,作为界面(我的建议);
class ICountry
{
string Name { get;}
}
class Country: ICountry
{
public string Name { get; set; }
}
我看到的唯一与您的示例接近的模式是“委托模式”(名称的检索委托给该州的父级)。
您的示例使我想起了聚合与构成之间的区别:一个国家有多个州,拥有一个不属于某个国家的州没有任何意义。
我猜这两种解决方案都有其优缺点。 但是我将第一个更改为仅知道CountryName而不是在构造函数中传递国家。 如果在构造函数中更改了国家/地区名称,则使用CountryName的公共设置器破坏数据封装有什么意义?
看起来国家应该提及其所属的国家。 这种模式称为对象组合 。
我不知道这是什么模式,但是在您的示例中,我认为您面临的问题是属性内容可能会更改,而并非所有应该共享相同属性内容的不同对象也会随之更改。 如果我弄错了,请告诉我,我将删除答案,因为以下内容基于此假设。
使用基类或接口可以解决该问题。 只需确保两个属性都具有相同的名称即可。 如果有可能的话。 我会尝试实现不同的模式。
一种实现方法是,您可以创建一个在Country
对象和State
对象中都具有引用的对象。 比创建一个名为Controller
的对象来控制Name
对象的内容。 如果必须更改名称,则会调用控制器,并相应更改内容。 确保将Country
对象和State
对象的属性都设置为Readonly
。
一种更简单但同样有效的方法是创建一个“控制器”,它是唯一可以更改属性的对象。 这两个属性之间不需要引用。 如果控制器是唯一可以更改属性的对象,请在控制器上使用方法将United States
的名称更改为US
。 如果contoller知道所有国家和州的集合,则可以通过查找原始内容并将其更改为新内容来更改属性。 如果有两个控制器,一个用于国家,一个用于州,则可以在另一个控制器上调用方法以进行相同的更改。 (可以通过接口或基类强制使用这种更改方法)
这样想吧。 椅子上有很多腿,但椅子本身并不知道。 这只是一把椅子。 知道它有4条腿的是椅子的使用者或所有者。 它也可以有三条腿。 如果一条腿断了,您会告诉木匠修理椅子的腿。 如果要在三腿椅子上增加一条腿,请告诉木匠而不是椅子。 如果您更改了国家/地区名称,则将其告知国家/地区管理员。 然后,国家名称被更改。 这个国家本身只有一个名字。
该解决方案的问题在于,在一个已经具有大量代码库并且已经为此工作的很多人的项目中,这只是引入了另一种处理方式。 旧代码可能不会遵循您的新工作方式,这使其与其余代码脱颖而出。 此外,在大多数情况下,重构整个代码库既不可行也不可取。 当然,慢慢引入这种新方法可能是一种选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.