处理静态方法时,将代码保持在相同级别
-
29-09-2019 - |
题
这可能有点主观,但是我想了解您当前情况的投入。我有一个类,该类将用于序列化/应对对象。
public class MyClass
{
public static string ToXmlString( MyClass c ) { /*...*/ }
public static MyClass FromXmlString( string xml ) { /*...*/ }
}
我只喜欢这种方法,因为它将两个函数保持在同一级别。但是,我的目标是避免使用静态方法(可行时)。感觉我可能正在探索SRP,但是该对象的主要目标是可以从XML字符串中序列化/应对序列化。
在这种情况下使用静态方法的任何想法吗?我应该只是做 ToXmlString
非静态,但离开 FromXmlString
静止的?我应该创建一个只能处理myclass序列化的新课程吗?
编辑:
我在这里讨论的课程是一个简单的转移对象。它用于从thrid party工具中节省/还原值。
谢谢!
解决方案
FWIW我认为序列化是一个有问题的问题,应该与您的其他班级分开,如果您的班级是业务类型,则最重要的是。
开发组件时的一般规则是确保它仅解决一些问题,并将业务问题与技术问题分开。
如果以后您需要从数据库或二进制格式管理序列化怎么办?
您可能会以越来越多的技术方法(SavetoDB,LoadFromDB,TobinaryStream,FrombinaryStream ...)结束,这会使您的班级混乱,并使其越来越难以维护,从而隐藏其主要目的(例如,业务)。
其他提示
C#和Java标准LIB中的约定是 To__
方法是实例方法和 From__
方法是静态的(必要)。例如: ToString()
是实例方法。
详细说明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);
}
}
请注意,瞬态的使用描述了不会序列化的字段。
如果您想要标准序列化(XML与否),则两种序列化/验证方法都不应为静态。
在MyClass中,您应该重新定义“ WriteObject”和“ ReadObject”,以替换您的默认序列化方法。这里有一个 太阳教程 关于这些方法。
如果您不想要“标准序列化”,则使用静态方法对我来说看起来不错。静态的UTIL方法不是异端。
PS:这不是问题,但是如果您想要WML序列化,则可以使用 Xstream API.
您可以定义一个构造函数,该构造函数(如果您真的坚持使用)(如果您确实坚持)。这样做的主要优点是,它允许您在班上拥有更强大的不变性,并通过使用任何不变的成员明确说明 readonly
.
我认为,对于静态与实例,互补方法不太可怕,因为该框架偶尔会这样做(例如,string.split / join)。
但是话虽如此,我认为最大程度地减少静态方法的目的不是一个好主意。要避免的事情是静态可变状态,而不是静态方法。仅根据其参数而不是静态变量运行的静态方法是纯粹的惊人。
纯静态函数可以比实例方法更可维护,因为实例方法没有以明显的方式传达其可能突变的实例字段。通过遵循没有任何静态状态的规则,可以依靠静态方法来对其参数进行操作,因此可以更好地预测该方法在应用程序中的作用。多线程尤其重要。
由于将TOXMLString方法应用于定义的类的实例,因此其中一些考虑不适用。它可以轻松地以不足的方式更改传递给它的对象的状态,因为它可以访问实例的所有私人成员。但是我只是想说,作为一般规则的静态方法不是问题。