处理静态方法时使代码保持在同一级别

发布于 2024-09-14 17:36:38 字数 550 浏览 2 评论 0原文

这可能有点主观,但我想听听您对我目前情况的意见。我有一个类将用于序列化/反序列化对象。

public class MyClass
{
    public static string ToXmlString( MyClass c ) { /*...*/ }
    public static MyClass FromXmlString( string xml ) { /*...*/ }
}

我只喜欢这种方法,因为它使两个功能保持在同一水平。但是,我的目标是避免使用静态方法(如果可行)。我也觉得我可能违反了 SRP,但这个对象的主要目标是它可以从 xml 字符串序列化/反序列化。

对于在这种情况下使用静态方法有什么想法吗?我应该将 ToXmlString 设置为非静态,但将 FromXmlString 保留为静态吗?我应该创建一个仅处理 MyClass 序列化的新类吗?

编辑:

我在这里讨论的类是一个简单的传输对象。它用于从第三方工具保存/恢复值。

谢谢!

This might be a little subjective, but I'd like to get your input on my current situation. I have a class that will be used to serialize/deserialize an object.

public class MyClass
{
    public static string ToXmlString( MyClass c ) { /*...*/ }
    public static MyClass FromXmlString( string xml ) { /*...*/ }
}

I only like this approach because it keeps the two functions at the same level. However, my goal is to avoid using static methods (when feasable). It also feels like I might be vilolating SRP, but the main goal of this object is that it can be seriliazed/deserialized from an xml string.

Any thoughts on the use of static methods in this situation? Should I just make the ToXmlString non-static, but leave the FromXmlString static? Should I create a new class that will only handle serilization of MyClass?

EDIT:

The class that I'm discussion here is a simple transfer object. It is used to save/restore values from a thrid party tool.

Thanks!

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

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

发布评论

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

评论(6

滿滿的愛 2024-09-21 17:36:38

FWIW 我认为序列化是一个问题,应该与班级的其他部分分开,尤其是如果您的班级是业务类型。

开发组件时的一般规则是确保它只解决少数问题,并将业务问题与技术问题分开。

如果以后您需要管理数据库或二进制格式的序列化怎么办?

您可能会以越来越多的技术方法(SaveToDB、LoadFromDB、ToBinaryStream、FromBinaryStream...)结束,这些方法会使您的类变得混乱,使其变得越来越难以维护,隐藏其主要用途(例如业务)。

FWIW I think that serialization is a problematic that should be separated from the rest of your class, above all if your class is a business type.

The general rule when developing a component is to ensure that it only addresses a few concerns and to separate business concerns from technical ones.

What if later you need to manage serialization from a database or a binary format ?

You might end with more and more technical methods (SaveToDB, LoadFromDB, ToBinaryStream, FromBinaryStream...) that would clutter your class and make it more and more difficult to maintain, hiding its primary purposes (business for example).

卖梦商人 2024-09-21 17:36:38

C# 和 Java 的标准库中的约定是,To__ 方法是实例方法,而 From__ 方法是静态的(必然)。例如:ToString() 是一个实例方法。

The convention in the standard libs for both C# and Java is that To__ methods are instance methods and From__ methods are static (by necessity). For example: ToString() is an instance method.

萌无敌 2024-09-21 17:36:38

详细说明Benoit的答案,这里有一个示例,其中正在序列化的类定义了序列化行为(我没有写这个):

// : c12:SerialCtl.java
// Controlling serialization by adding your own
// writeObject() and readObject() methods.
// From 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002
// www.BruceEckel.com. See copyright notice in CopyRight.txt.

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SerialCtl implements Serializable {
  private String a;

  private transient String b;

  public SerialCtl(String aa, String bb) {
    a = "Not Transient: " + aa;
    b = "Transient: " + bb;
  }

  public String toString() {
    return a + "\n" + b;
  }

  private void writeObject(ObjectOutputStream stream) throws IOException {
    stream.defaultWriteObject();
    stream.writeObject(b);
  }

  private void readObject(ObjectInputStream stream) throws IOException,
      ClassNotFoundException {
    stream.defaultReadObject();
    b = (String) stream.readObject();
  }

  public static void main(String[] args) throws IOException,
      ClassNotFoundException {
    SerialCtl sc = new SerialCtl("Test1", "Test2");
    System.out.println("Before:\n" + sc);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    ObjectOutputStream o = new ObjectOutputStream(buf);
    o.writeObject(sc);
    // Now get it back:
    ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
        buf.toByteArray()));
    SerialCtl sc2 = (SerialCtl) in.readObject();
    System.out.println("After:\n" + sc2);
  }
}

请注意使用瞬态来描述不会被序列化的字段。

Elaborating on Benoit's answer, here's an example where the class that is being serialized defines the serializing behavior (I did not write this):

// : c12:SerialCtl.java
// Controlling serialization by adding your own
// writeObject() and readObject() methods.
// From 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002
// www.BruceEckel.com. See copyright notice in CopyRight.txt.

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SerialCtl implements Serializable {
  private String a;

  private transient String b;

  public SerialCtl(String aa, String bb) {
    a = "Not Transient: " + aa;
    b = "Transient: " + bb;
  }

  public String toString() {
    return a + "\n" + b;
  }

  private void writeObject(ObjectOutputStream stream) throws IOException {
    stream.defaultWriteObject();
    stream.writeObject(b);
  }

  private void readObject(ObjectInputStream stream) throws IOException,
      ClassNotFoundException {
    stream.defaultReadObject();
    b = (String) stream.readObject();
  }

  public static void main(String[] args) throws IOException,
      ClassNotFoundException {
    SerialCtl sc = new SerialCtl("Test1", "Test2");
    System.out.println("Before:\n" + sc);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    ObjectOutputStream o = new ObjectOutputStream(buf);
    o.writeObject(sc);
    // Now get it back:
    ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
        buf.toByteArray()));
    SerialCtl sc2 = (SerialCtl) in.readObject();
    System.out.println("After:\n" + sc2);
  }
}

Note the use of transient to describes fields that will not be serialized.

明天过后 2024-09-21 17:36:38

如果您想要标准序列化(无论是否为 XML),则序列化/反序列化方法都不应该是静态的。

在MyClass中,您应该重新定义“writeObject”和“readObject”以替换您的默认序列化方法。这是关于这些方法的 Sun 教程

如果您不想要“标准序列化”,那么使用静态方法对我来说看起来不错。静态 util 方法并不是异端邪说。

PS:这不是问题,但如果您想要 WML 序列化,您可以使用 XStream API

If you want a standard serialization (XML or not), both serialize/deserialize methods should not be static.

In MyClass, you should redefine "writeObject" and "readObject" to replace the default serialization methods by yours. Here is a Sun tutorial about theses methods.

If you don't want a "standard serialization", using static methods looks fine for me. Static util methods are not an heresy.

PS : it is not the question, but if you want WML serialization, you can use the XStream API.

℉絮湮 2024-09-21 17:36:38

您可以定义一个采用 XMLReader(如果您确实坚持的话,也可以采用字符串)的构造函数。这样做的主要优点是,它允许您在类中拥有更强的不变量,并通过使用 readonly 明确任何不可变成员。

You could define a constructor that takes an XMLReader (or a string if you really insist). The main advantage of this is that it allows you to have stronger invariants in your class, and to be explicit about any immutable members through the use of readonly.

庆幸我还是我 2024-09-21 17:36:38

我认为将静态方法与实例方法分开并不是太糟糕,因为框架偶尔会这样做(例如 String.Split / Join)。

但话虽如此,我认为最小化静态方法的使用的目标并不是一个好主意。要避免的是静态可变状态,而不是静态方法。仅对其参数而不是静态变量进行操作的静态方法真是太棒了。

纯静态函数比实例方法更易于维护,因为实例方法不会以明显的方式传达它可以改变哪些实例字段。通过遵循不维护任何静态的规则,静态方法可以仅对其参数进行操作,因此可以更好地预测该方法在应用程序中的作用。这在多线程时尤其重要。

由于 ToXmlString 方法应用于定义该方法的类的实例,因此其中一些注意事项不适用。它可以轻松地以不正当的方式更改传递给它的对象的状态,因为它可以访问实例的所有私有成员。但我只是想说,作为一般规则,静态方法不是问题。

I don't think it's too terrible for complementary methods to be separated with regard to static vs. instance, since the Framework does this occasionally (String.Split / Join, for example).

But having said that, I think the goal of minimizing the use of static methods is not a good idea. The thing to avoid is static mutable state, not static methods. A static method that only operates on its parameters, rather than static variables, is pure awesomeness.

A pure static function can be more maintainable than an instance method, since the instance method does not communicate in an obvious way which instance fields it can mutate. By following the rule that no static state whatsoever is maintained, a static method can be relied upon to only operate on its parameters, and thus the method's role in the application can be better predicted. This is especially important when multi-threading.

Since the ToXmlString method is being applied to an instance of the class in which it is defined, some of these considerations don't apply. It could easily change the state of the object that is being passed to it in underhanded ways, since it can access all the private members of the instance. But I just mean to say that as a general rule static methods are not a problem.

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