2009-10-12 64 views
0

寻找关于如何构建/构建应用程序的一些指导,我遇到了一些困难。请不要限制技术细节的答案,因为我不确定我是否以最有效的方式做事。我在VB.NET中给出了例子,但请随意使用c#,因为这是我们的官方目标语言。我只是比较了解vb。此外,我们正在使用Visual Studio 2008.继承/架构

因此,该场景: 我们正在编写一个基于Web的应用程序(希望)可以为几个客户定制。 为了简洁起见,不要放弃农场,我们假设它是一个人员应用程序。

所以,我将要有一个Person基类。这将只有非常一般的方法。 它有一个公共属性 班级Class1中的名称。

为了讨论,下面我将创建一个新的项目/组件 Person.Employee现在

,因为我可能会想这个应用程序出售给模特儿经纪公司或建筑公司,也许我想添加一些非常奇特的属性。 CheekStructure或CanOperateHeavyMachinery

所以,我会创建新的项目工作室称为 Person.Employee.TinasModeling & Person.Employee.TomsConstructionCompany 将包含代码只有一个特定的公司。

您可能会认为每个这些程序集将只包含适用于层次结构中程序集级别的业务逻辑。

请记住,这是针对许多不同公司的自定义应用程序,但都涉及人员。所以这就是为什么我想出这个模型。如果我们发现一个较低级别的错误,我只想修复它,并发送一个dll或2.这个结构非常严重地针对我们,可能有20个或更多的定制应用程序。分销和维护是PARAMOUNT的关注点。开发人员不多。比我多,但少于3格。

现在,问题所在。

为了简单起见,我有Class1。

在我的网络应用程序中,我有一个参考Person.Employee.TinasModeling 此Web应用程序项目仅用于Tinas建模。

如果我有
进口Person.Employee.TinasModeling
...

暗淡这个作为新的Class1
this.Name = “一些价值”

这将无法编译,除非我有也是对Person的引用。

问题1.我是否真的需要向基类Person(也可能是Person.Employee)提供ref,或者在没有它的情况下还有其他方法吗?我不希望任何人无意中在继承链的较低级别创建类。我不确定我想让他们在更低层次上创建它们,但也许我的担心是没有意义的?

问题2:这是架构这个最好的方法吗?请记住,维护和分配是这里的主要关注点。图片发现一个低级别的漏洞,不得不打开20个解决方案,构建每个解决方案,测试(即使是自动化),构建和分发。 我真的希望能够发出1个DLL(或者更新的那个,以及相关的也是?)并完成,如果该低级别的dll通过它的测试

如果我必须有参考所有较低级别的继承树,也许我应该把所有这一切都放到一个不同命名空间下的程序集中?

Cripes,希望这是非常明显的。我一直在搜索谷歌整天的继承样本,试图找到有用的东西。希望这里有人能清除我脑中的雾。

由于提前, 鲍勃

回答

0

作为一般原则,在树的根类都应该是抽象的,因为他们都是不完整的。

当只有具体到个人客户应用类型由混凝土制成,你无意中创建其他类的问题消失。

1

听起来像一个很好的候选人使用依赖注入 - 为了让您一开始采取Spring.NET的网站一看this example。对于简短的回复表示歉意,但我可以在今晚详细阐述一下,当我有更多时间坐下来编一个与你的帖子更相关的快速示例时。

编辑: 好先让引入两个子对象,TinasModeling.Model和BobTheBuilder.Builder

public class Model : IPerson 
{ 
    private bool canAct; 
    public bool CanAct 
    { 
     get { return canAct; } 
     set { canAct = value; } 
    } 

    private double weight; 
    public double Weight 
    { 
     get { return weight; } 
     set { weight = value; } 
    } 

    public Model() 
    { 
    } 

    public bool PayPerson(double Amount) 
    { 
     if (canAct) 
      RequestFilmBoxOfficeRevenue(); 
     Pay(); 
    } 

    public bool NewJobRequest() 
    { 
     SendPhotoPortfolioToClient(); 
     SendJobLocationToModel(); 
     if (canAct) 
      NotifyFilmCrew(); 
     if (weight < 40.00) 
      ContactNutritionist(); 
    } 
} 

public class Builder : IPerson 
{ 
    private bool canOperateDigger; 
    public bool CanOperateDigger 
    { 
     get { return canOperateDigger; } 
     set { canOperateDigger = value; } 
    } 

    private double certifiedBuilder; 
    public double CertifiedBuilder 
    { 
     get { return certifiedBuilder; } 
     set { certifiedBuilder = value; } 
    } 

    public Builder() 
    { 
    } 

    public bool PayPerson(double Amount) 
    { 
     ReuqestTimeSheet(); 
     Pay(); 
    } 

    public bool NewJobRequest() 
    { 
     SendBluePrintsToBuilder(); 
     if (!certifiedBuilder) 
      RequestLegalAdvice(); 
     if (canOperateDigger) 
      RequestDrivingPermit(); 
    } 

两个类都在不同的项目中实现 - 他们没有要,但他们是我将在稍后解释的原因。正如你所看到的,他们都以不同的方式做事,但有一个共同点,那就是他们实现了IPerson接口。

public interface IPerson 
{ 
    bool PayPerson(double Amount); 
    bool NewJobRequest(); 
} 

此接口实现的,同样,在超过两个上述目标,因此我们的子对象的引用该装配一个单独的程序,让我们把它叫做BOL(业务对象层)。在BOL中,我们实现了另一个类叫PersonController

public class PersonController 
{ 
    private IPerson thePerson; 
    public IPerson ThePerson 
    { 
     get { return this.thePerson; } 
     set { this.thePerson = value; } 
    } 

    public PersonController() 
    { 
    } 

    public bool PayPerson(double Amount) 
    { 
     return this.thePerson.PayPerson(Amount); 
    } 

    public bool NewJob() 
    { 
     return this.thePerson.NewJobRequest(); 
    } 
} 

关于PersonController最重要的是要注意ThePerson属性。这将成为我们的依赖注入点。在这个阶段值得指出的是BOL层与任何子对象完全分离。这是一个非常重要的功能,它将为部署和维护时间带来很大的灵活性。

现在我们使用和配置我们迄今建造的。我们的应用程序仅引用BOL层(也将我们的主应用程序与任何子对象解耦)。在我们的主应用程序,我们使用Spring.NET Spring.Core组装和在app.config文件添加下面的(为便于阅读,我省略了configSections标签)

<spring> 
<context> 
    <resource uri="config://spring/objects"/> 
</context> 
<objects xmlns="http://www.springframework.net"> 
    <description>An example that demonstrates simple IoC features.</description> 
    <object name="Person" type="BOL.BOL.PersonController, BOL.BOL"> 
    <property name="ThePerson" ref="Person"/> 
    </object> 
    <object name="Person" type="BobTheBuilder.BobTheBuilder.Builder, BobTheBuilder.BobTheBuilder"> 
    </object> 
</objects> 

好希望大家都到目前为止 - 第一个对象元素是指需要依赖注入的类,在我们的例子中是PersonController。子属性元素引用PersonController中的依赖注入点,或者在我们的例子中是ThePerson属性。这个元素的ref属性指向我们的第二个对象元素。

第二个对象元素我们设置了我们希望在运行时注入的子对象(即TinasModeling.Model或BobTheBuilder.Builder)。

最后将所有这些一起

static void Main(string[] args) 
    { 
     IApplicationContext ctx = ContextRegistry.GetContext(); 
     PersonController person = (PersonController)ctx.GetObject("Person"); 

     // Ready to use person with implementation specified in config 
     person.NewJob(); 
     person.PayPerson(); 
    } 

因此,这将基于我们如何在我们的app.config配置的“人”实例PersonController的代码。

因此,问题一的答案是否定的(至少如上所述) - 完全分开您的基本实现。

回答问题2(这是架构这个的最好方法)可能是有点主观的 - 但分发和维护是在我看来,你的主要关注上面的设计满足您的需求,因为组件是实际上是为了举重而完全解耦。

希望我已经很好地解释了我自己。