在不破坏封装的情况下公开对象数据

发布于 2025-01-02 21:37:07 字数 549 浏览 4 评论 0原文

良好的面向对象设计表明,对象不应暴露其内部结构。鉴于这种情况,显示数据的最佳方式是什么?

例如,在控制台应用程序中调用 DoSomethingToData 后,您将如何显示数据字段?

public class Foo {
    string data;

    public void DoSomethingToData(string someParam) {
        .....
    }
}

class Program {
    static void Main(string[] items) {
        var foo = new Foo();
        foo.DoSomethingToData("blah");
        ..... // how do we write data field to console without breaking encapsulation?
    }
}

更新: 我认为维护封装的最佳方法是使用观察者模式(事件),但没有人提到它。这是比公开属性或方法结果更好的解决方案吗?

Good object-oriented design says that objects should not expose their internals. Given this is the case, what is the best way to display data?

For example, how would you go about displaying the data field after calling DoSomethingToData in a Console application?

public class Foo {
    string data;

    public void DoSomethingToData(string someParam) {
        .....
    }
}

class Program {
    static void Main(string[] items) {
        var foo = new Foo();
        foo.DoSomethingToData("blah");
        ..... // how do we write data field to console without breaking encapsulation?
    }
}

Update:
I thought the best way to maintain encapsulation would be to use an observer pattern (events), but no one has mentioned it. Is this a better solution than exposing a property or method result?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

苯莒 2025-01-09 21:37:07

这取决于;

  • 如果该值仅与方法相关,则将其作为该方法的返回值
  • 如果该值与对象相关,则通过属性公开它

我怀疑是后者,所以:

 public string Data { get { return data; } }

这只是一个访问器 - 相当于getData()。这不会公开字段,但最终您的对象应该向信息公开某些 API。这并不意味着是一个完全的秘密。

It depends;

  • if the value relates only to the method, make it a return value of the method
  • if the value relates to the object, expose it via a property

I suspect it is the latter, so:

 public string Data { get { return data; } }

Which is simply an accessor - the equivalent of getData() in java, for example. This isn't exposing the field, but ultimately your object should expose some API to the information. It isn't meant to be a complete secret.

红焚 2025-01-09 21:37:07

您可以添加 ToString 方法(或类似方法)来提供适合登录到控制台的字符串表示形式。

public class Foo
{
    private string data;

    public void DoSomethingToData(string someParam) {
        .....
    }

    public override string ToString()
    {
        return string.Format("Foo data: {0}", data);
    }
}

这使类的客户端清楚地知道,除了调试/日志记录之外,数据字段的内容不打算在类外部使用。


或者,您可以私有一个公共 getter 属性,该属性允许直接(只读)访问私有字符串,但请注意,以这种方式提供此类属性可能会导致该类的客户端使用 Data 字段用于除日志记录之外的更一般目的。

public string Data { get { return data; } }

最后一个选项是使用自动实现的属性并完全删除该字段(自动实现的属性将使用其自己的支持字段):

public string Data { get; private set; }

You can add ToString method (or similar) to provide a string representation suitable for logging to the console.

public class Foo
{
    private string data;

    public void DoSomethingToData(string someParam) {
        .....
    }

    public override string ToString()
    {
        return string.Format("Foo data: {0}", data);
    }
}

This makes it clear to clients of your class that the contents of the data field are not intended to be used outside the class except for debugging/logging.


Alternatively you could private a public getter property that allows direct (read-only) access to the private string, but notice that providing such a property in this way may result in clients of the class using the Data field for more general purposes other than logging.

public string Data { get { return data; } }

A final option is to use an auto-implemented property and remove the field completely (the auto-implemented property will use its own backing field):

public string Data { get; private set; }
预谋 2025-01-09 21:37:07

一些常见的方法:

  • 重写 ToString() 以获取实例的某些通用文本表示形式(这可能反映您想要的内部数据或不反映您想要的内部数据,取决于细节和上下文)
  • 如果计算是根据某些特定的内部数据执行的,则公开方法
  • 将 getter 公开为不可变暴露内部数据
  • 如果您只需要在调试时检查内部行为,请使用调试器并“监视”类实例

Some common approaches:

  • Overriding ToString() for some general textual representation of an instance (this may reflect your desired internal data or not, depends on details and context)
  • Exposing a method if calculation is performed from some specific internal data
  • Exposing a getter to immutably expose internal data
  • Use debugger and 'watch' on class instance if you only need to inspect internal behavior when debugging
洒一地阳光 2025-01-09 21:37:07

在 Foo 类中创建属性

    public string Data
    {
        get{return data;}
        set{data = value;}
    }

Make property in Foo class

    public string Data
    {
        get{return data;}
        set{data = value;}
    }
度的依靠╰つ 2025-01-09 21:37:07

将数据视为属性。数据是一种属性,不需要按照分配的方式存储。可以通过从/到其后备存储的转换来获取/存储属性。通过对私有存储变量的内部结构进行转换的组合可以获得多个属性。

private double booTheBackingStore;
private int myfactor;

public String data{
  get{
    return "<data>"+booTheBackingStore*booTheBackingStore+"</data>";
  }

  set{
    String boo = parselTheXml(value);
    double booger;
    Double.tryParse(boo, out booger);
    booTheBackingStore = Math.sqrt(booger);
  }
}


public double dada{
  get{
    return exoTransform(booTheBackingStore, myfactor);
  }
  set{
    booTheBackingStore = endoTransform(value, myfactor);
  }
}

更多信息:

假设您的类是一个网页视图,它具有编辑、浏览、插入、删除模式。对于每种模式,您的视图都必须重新实例化/重新排列小部件。此外,您还必须重新应用样式。

从 MVP 的角度来看,您需要将您的演示文稿与您的视图解耦。该视图需要在公共属性方面暴露自己。因此,设置/获取模式属性将封装需要在 UI 上执行的所有内部结构。演示者不应该关心视图如何自行排列。并且视图不应该有任何流程或数据控制逻辑。

公共属性是促进封装的重要组成部分,以便仅公开视图和呈现者之间的契约。

健壮的 UI 设计将具有服务器端状态机,它与客户端状态机进行通信,客户端状态机依次对表示代理进行排序,而表示代理又要求显示 UI-View 属性。您的服务器根本不应该直接访问客户端视图。您的客户端状态机也不应该。您的演示者根据客户端的状态来提出 UI 视图的要求。演示者仅发出对例如编辑模式的需求。它不会干扰 UI-View 编辑模式的实现方式。 UI-View 不应该维护 UI 的状态。

这种解耦是为了促进单元测试,最重要的是,促进组件的模块化交换。这样,在您将浏览器 UI 更换为移动设备 UI 后,您的演示序列也能正常工作。由于移动 UI 会以不同于浏览器 UI 的方式实现各种模式。或者桌面用户界面。

您需要进一步阅读基于组件的设计和“封装”的概念。

Treat data as a property. Data is a property that does not need to be stored the way it was assigned. A property can be obtained/stored thro transformation from/to its backing store. More than one property can be obtained from a combination of transformation of the innards of your private stored variables.

private double booTheBackingStore;
private int myfactor;

public String data{
  get{
    return "<data>"+booTheBackingStore*booTheBackingStore+"</data>";
  }

  set{
    String boo = parselTheXml(value);
    double booger;
    Double.tryParse(boo, out booger);
    booTheBackingStore = Math.sqrt(booger);
  }
}


public double dada{
  get{
    return exoTransform(booTheBackingStore, myfactor);
  }
  set{
    booTheBackingStore = endoTransform(value, myfactor);
  }
}

Further information:

Let's say your class is a web page view, which has edit, browse, insert, delete modes. For each of these modes, your view has to reinstantiate/rearrange widgets. Further more, you would have to reapply styles.

From the perspective of MVP, you need to decouple your presentation from your view. The view needs to expose itself in terms of public properties. So that set/get mode property would encapsulate all the innards that need to be performed on the UI. The presenter should not care how the view arranges itself. And the view should not have any process or data control logic.

Public property is an essential part to facilitate encapsulation in order to expose only the contracts between the view and the presenter.

A robust UI design would have a server-side state-machine, which communicates with the client-side state-machine, which in turn sequences the presentation agents, which in turn demands the exposition of UI-View properties. Your server should not reach out to the client view directly at all. Neither should your client state-machine. Your presenter, is directed by the state of the client to make demands of the UI-View. The presenter merely issues the demand for, say, the EDIT mode. It will not meddle with the UI-View how that EDIT MODE is implemented. The UI-View should not maintain the state of the UI.

This decoupling is to facilitate unit testing, and most importantly, modular swapping of components. So that your presentation sequence would work just as well after you have swapped your browser UI with a mobile one. Since the mobile UI would implement the various modes differently from that of the browser UI. Or the desktop UI.

You need to read up further on the concepts of component-based design and "encapsulation".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文