繁体   English   中英

这种设计模式的名称是什么? (如果是一个)

[英]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.

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