【问题标题】:Public static data used throughout program整个程序使用的公共静态数据
【发布时间】:2011-11-08 23:19:22
【问题描述】:

代码示例是 C#,但这是一个一般的 OO 问题。

我知道根据 OO 规则,应尽量减少类耦合,成员应尽可能保持私有,等等。

考虑这个例子:

您正在编写一个深奥的程序,该程序具有某种数据集(我不是在谈论 System.Data.DataSet),该数据集实际上用于程序的各个方面。事实上,程序的存在基本上只是为了加载、显示、操作和保存数据集。此外,任何时候都只能加载一个数据集,并且在程序打开时加载。

如果我们严格遵守 OO 规则,我们就会有

public void ShowSomeGraphs(IData data)
{
  // do stuff with data which implements IData
}

但是,例如,我们可能会将public static Data 成员存储在Program 中。

public void ShowSomeGraphs()
{
  // do stuff with Program.Data
}

一方面,我们用更短的函数签名换取了大大增加的类耦合。另一方面,我们不再将 Data 参数传递给实际上 every 函数,everywhere

正确的答案可能是:尽可能避免类耦合。本地 Data 变量只是指针,因此内存开销可以忽略不计,而且由于类是解耦的,它们可以在以后在其他地方使用。

虽然现实地说,Data 类的结构在不同的应用程序中可能会有显着的不同,因此您不能直接从该程序中提取一个类,然后将其放到其他地方而不做任何调整。以一种可以直接加入的方式编写类所需的额外时间和精力可能很难向利益相关者证明是合理的。

我现在正在开发这种程序,并且我使用了 OO-canon 方法:在需要的地方传递数据参数我已经最小化了与 IData 接口的类耦合,以便为将来的代码重新概括数据集利用。鉴于应用程序,我几乎可以肯定这段代码永远不会被重用。如果没有这些额外的接口和抽象,就最终用户而言,该程序的工作方式将完全一样,但对我来说会大大减少头痛和开发时间。

您对此有何看法?您认为花费所有额外时间编写接口和泛化以确保类在可能的情况下解耦是否合理,尤其是当您以后看不到在其他地方使用的类时?

【问题讨论】:

  • 这真的是见仁见智。这是代码风格与时间的问题。程序应该工作,并且尽可能少的错误。代码风格旨在降低复杂性,使代码更易于理解,更适合项目之间的更改和可重用。真的取决于你决定做什么
  • @Ozzah:我在我的答案中添加了一个代码示例,以展示实现单例解决方案是多么快速和轻松,允许您松散耦合以及从客户端代码轻松访问数据接口。跨度>

标签: oop decoupling coupling


【解决方案1】:

不要为此烦恼。严重地。

软件范例/模式可以帮助我们,而不是教条地遵循。

您在问题中明确表示您认为松散耦合过大了,您可以证明原因。因此,不要使用它。

【讨论】:

  • “痛苦”这个词有点强。我一直对这些严格的规则有自己的看法,这些规则在很多情况下可能有意义,但不一定在所有情况下都有意义。作为我部门唯一的程序员,我与同类接触不多,我只是好奇其他有经验的人的看法。
【解决方案2】:

使用singleton pattern 提供方法或只读属性来获取IData 接口怎么样?这样,您只需要耦合到一个非常薄的单例类,并且您与数据集的所有交互都是通过 IData 接口完成的。

(我肯定会避免紧密耦合。即使您不打算对这个应用程序做太多事情,您也可能会在开发过程中遇到问题,这将迫使您接触比访问通过接口获取数据。)

上面提出的单例解决方案的代码示例:

using System;

public class MyClass {
    public static void Main() {
        // simple usage:
        Console.WriteLine("From Main: " + Singleton.Instance.IMyData.GetData());
        // client code from another type:
        new ClientObj().DoWork();
        Console.ReadKey();
    }
}

public sealed class Singleton {
    // standard singleton stuff:
    private static readonly Singleton _instance = new Singleton();
    private Singleton(){}
    public static Singleton Instance {get { return _instance; }}
    // data interface stuff:
    private MyData _myData = new MyData();
    public IData IMyData {get { return _myData; }}
}

// the interface:
public interface IData {
    string GetData();
}

// concrete implementation of the data class
public class MyData : IData {
    public string GetData() {return "Hello World!";}
}

// example of a type using the singleton and the IData interface
public class ClientObj {
    public void DoWork() {
        IData data = Singleton.Instance.IMyData;
        string str = data.GetData();
        Console.WriteLine("From other obj: " + str);
    }
}

一些注意事项: 上面的代码示例完全是为了展示单例和共享接口的概念。没有实现线程安全,没有数据对象的初始化等。

【讨论】:

    【解决方案3】:

    好吧,您的文本中有一个很大的假设:程序中始终只有一个数据集。你确定这个条件会一直存在吗?曾经有一段时间,文字处理器一次只能保存一个文本。今天,能够同时打开多个文件已成为标准。如果第一个网络浏览器一次只能打开一个网页,我也不会感到惊讶。今天没有人会使用不能同时打开多个页面的网络浏览器。我认为那种你可以说在程序中肯定只有一个的对象是非常罕见的。事实上,我唯一会制作全局对象或单例的就是对象工厂。

    另一方面,为每个函数调用传递对象对我来说似乎也有点过头了。因此我会选择中间立场:让对象记住那个“全局”对象,所以你只需要通过构造函数传递它。这将每个单个对象限制为一个 Data 对象,但如果您决定要在程序中轻松拥有多个 Data 对象,仍然可以。

    【讨论】:

    • 您说的是公用软件。每个人都使用文字处理器,因此使用方式千差万别。我的程序只供我公司的两个人使用,其他任何地方都没有。我非常确定永远不会需要一个以上的数据集。我为公司编写的很多程序都是这样的,所以我想这并不罕见。
    猜你喜欢
    • 2010-10-19
    • 2012-11-29
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多