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!
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).
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.
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.
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.
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.
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.
Related
I'm trying to work Domain Specific Language constructs into my api. What I would really love to do is be able to add a static method to a class via extension, but i have researched that this is not possible from this site. So let's talk about what i really want to do by example.
Say you have some class that serves as a data service (could be a database, or rest or whatever).
The class requires you to initialize it with some, let's say, location data so that it knows where to point. This location information is not going to be known till runtime.
Normally you would do . . .
DataService service = new DataService( locationData );
Order = service.getOrderDetails( orderId );
However, in almost all cases, the user will just need to ask on question of the DataService and then move on, close scope. I would like some idiom that makes this friendlier to the user. When I learned of extension methods by wish was to do this . . .
Order = DataService.at(location).getOrderDetails(orderId);
This, of course, is also possible, but I would like to put this pattern/idiom on to many classes that have this notion of a location. I have tried extension methods (cant be static). I have tried inheriting from a GenericClass that provides an at method:
public class DSL<T>
where T : new()
{
public T at( Location location )
{
return new T(location);
}
}
you can not pass args to a constructor for a variable type :(
I dislike doing the following:
public class DSL<T>
where T : ILocationable, new()
{
public T at( Location location )
{
T result = new T();
result.setLocation( location );
return result;
}
}
because i do not like classes that can be instantiated and not initialized.
What alternatives do you guys have out there, either to add this "at" method or to provide a better idiom for handling this type of api.
UPDATE:
I came up with a mechanism that does what I need:
First I have this in a file in my library/tools area. The file is called DSL.cs
contents below:
namespace R3
{
static public class DSL
{
static public Services.CloudConnection Cloud( string cloud )
{
return Services.CloudFactory.get(cloud);
}
}
}
When I declare a method I want to use this with technique
static public void fixSequenceError(this CloudConnection cloud, OrderId id )
{
if( inSequenceError(cloud, id ) )
{
cloud.db.setOrderStatus(id, BLAH);
cloud.db.setOrderItemsStatus(id, BLAHBLAH);
}
}
then in any file i want to use this idiom in I need to do something funky instead of a standard include:
using static R3.DSL;
Now I can type stuff like:
Cloud( locationData ).fixSequenceError
or
Cloud(orderInfo.cloudLocation).db.changeAppOrderStatus
For efficiency, the CloudFactory is returning a statically allocated object that is associated with that cloudLocation, think many different singletons hashed to identifier. When Cloud( location ).foobar(orderId) is invoked I'm calling foobar using the object specific to that location. I'm doing so without having to prepend every action with Cloud cloud = CloudFactory.getCloud(location)
You could use reflection like this:
public static class DSL
{
public static T at<T>(Location location)
{
return (T)typeof(T).GetConstructor(new[]{typeof(Location)})?.Invoke(new object[] {location});
}
}
This method tries to get a ConstructorInfo and invokes it with the provided Location argument.
When the type T does not have a constructor taking only a Location argument, at will return null.
UPDATE: Decided to make the class static, so you don't need to create an instance when you just want to call it like this:
Order order = DSL.at<DataService>(location).getOrderDetails(orderId);
You could adopt a builder pattern perhaps to avoid classes which are constructed but not valid (although the builder itself might fall into this category):
Order order = new OrderBuilder().using(dataService).at(location).getOrderById(id).Build();
This gives the sort of fluent api you're looking for. I have recently used this for a project.
I would like some idiom that makes this friendlier to the user.
In your case it appears you don't want to use the Object Oriented Programming the way it was designed in c# but would rather use any a Fluent that allows for friendlier code for another programmer (not user).
In this case it seems your only solution would be to use the factory pattern. It's typically used to validate parameters as they are passed in, but in this case can be used to encapsulate the creation of a class to prevent uninitialized classes.
(I'll also mention that lowercased methods are against Microsoft guidelines for naming conventions, so I'll be using Pascal casing in my code.)
DataService.at(location).getOrderDetails(orderId);
Could be coded like:
public class DataService
{
private DataService(Location location)
{
//
}
public static DataService At(Location location)
{
var result = new DataService(location);
return result;
}
public Order GetOrderDetails(int orderId)
{
}
}
Then the code would look exactly like your example:
DataService.At(myLocation).GetOrderDetails(1);
This is only good assuming DataService does not derive from IDisposable.
Sorry for the unlearned nature of this question. If there's a simple answer, just a link to an explanation will make me more than happy.
After 6 months programming I find static classes to be somewhat useful for storing routines that apply to many different classes. Here's a simplified example of how I use static classes, it's a class for parsing text into various things
public static class TextProcessor
{
public static string[] GetWords(string sentence)
{
return sentence.Split(' ');
}
public static int CountLetters(string sentence)
{
return sentence.Length;
}
public static int CountWords(string sentence)
{
return GetWords(sentence).Length;
}
}
And I use this in obvious ways like
class Program
{
static void Main(string[] args)
{
string mysentence = "hello there stackoverflow.";
Console.WriteLine("mysentence has {0} words in it, fascinating huh??", TextProcessor.CountWords(mysentence));
Console.ReadLine();
}
}
My question is: Why is it necessary to wrap these static methods in a static class?
It seems to serve no purpose. Is there a way I can have these methods on their own not wrapped in a class? I know encapsulation is beneficial but I don't see the use for static methods wrapped in static class. Is there something I am missing stylistically or otherwise? Am I completely barking up a silly tree? Am I thinking too much?
In C#, any method has to be declared inside a class. That's just how the language is specified.
A static class is actually more akin to a module than a class, so I too think you should be able to either:
define a function outside a class or;
import a module the same way you import a namespace (with using)
VB.NET, F# and Nemerle actually allow you to declare modules and import them; what allows you to use their methods unqualified.
This is valid Nemerle:
using System.Console; // import static methods in the Console class
class Hello {
static Main() : void {
WriteLine("Hello, world!"); // unqualified access!
}
}
Also, take a look at extension methods, they might allow you to "solve" this in a different way. The methods in your TextProcessor are begging to be string extension methods.
This post by eric lippert gives a pretty detailed explanation. I'm not sure if this guy "eric" knows what he's talking about or not though ;-)
It would be somewhat awkward to have methods just dangling around in a random namespace.
I suspect the answer is to provide "scope". Just because a method is static, doesn't mean it doesn't have a scope. It can still access other static private methods or member variables - and the class provides a "home" for these things to live in.
Static classes can also have static constructors that get called the first time a static method is used, so this provides the ability to set stuff up as needed.
It's more of an organizational design than anything to due with technical limitations.
A static method is a method called in a single instance of a class that is created at run-time.
I am developing C# and asp.net web application.
I have general class called utilities, I have lot of public and static variables in this public utilities class.
Since this number is gradually increasing, I want to know is it good practice to store utilities methods and variable as public static.
Example of my code
public class utilities
{
public static string utilVariable1 = "Myvalue";
public static string utilVariable2 = "Myvalue";
public static string utilVariable3 = "Myvalue";
:
public static string utilVariableN = "Myvalue";
public static string UtilMethod1()
{
//do something
}
public static string UtilMethod2()
{
//do something
}
public static string UtilMethodN()
{
//do something
}
}
There's nothing inherently wrong with static classes, although they should typically not have state (fields). Your use of public static fields indicates that this is not the case, so it seems like you are using abusing the static keyword slightly. If your class needs to have state, then it should be a normal, non-static class, and you should create instances of it. Otherwise, the only public fields visible on the class should be const (consider the Math class, with constants such as Math.PI - a good use of static methods and fields).
Another consideration is cohesion. Methods typically exist grouped in one class because they are closely related in one way or another. Again, the Math class is a good example; everything in there has to do with maths. At some point, you would want to split your global utility class into multiple smaller, more focussed ones. See Wikipedia for some examples on cohesion, it sounds like your usage falls under "Coincidental cohesion (worst)".
There's nothing wrong with this approach for methods, but variables should really be const if they're going to be static and public. If they are subject to change then you should look at a different structure for variables that are being manipulated by more than one component.
Personally, I'm a fan of the Singleton pattern.
static is not a bad thing per se. Methods that don't need to access any member variables or methods should always be declared static. That way the reader of the code sees immediately that a method won't change member variables or methods.
For variables the situation is different, you should avoid static variables unless you make them const. Public static variables are globally accessible and can easily raise issues if multiple threads access the same variable without proper synchronization.
It is hard to tell for your case if it's a good or a bad idea to use statics, because you didn't provide any context information.
Creating one class to do it all is not a good practice, and it's recommended to structure your project, and keep stuff that belongs to each other separated from the randomness.
A great example of this was a project I took over from a co-worker. There was 1 class, called Methods. It contained over 10K lines of methods.
I then categorized them into approx. 20 files, and the structure was restored.
Most of the methods from that project were validating user input, which can easily be moved into a static class Validation.
One awful thing I notice is the mutable public and static variables. This is bad for several reasons:
Incorrect behavior, because if some method changes this, while it isn't supposed to do that, it causes other methods to behave improperly, and it's really hard to track down/debug.
Concurrency, how are we going to ensure thread safety? Do we let it over to all methods that work with that? Say if it's a value type, what will we let them lock on? What if some method forgets to make it thread safe?
Expand-ability (I hope you understand what I mean with that), if you have for example a static class data that stores all these public static variables, that you shouldn't have. It can store that once, if for example you might change your application structure a bit, and say want to make it possible to load two projects in the same screen, then it's very difficult to make that possible, because you can't create two instances of a static class. There is only one class, and it'll remain like that.
For number 3 a cleaner solution would be to store either a list of instances of a data class, or to store a reference to the default and/or active data class.
Static member, and private static members (or protected) are a good practice, as long as you don't make huge classes, and the methods are related.
Public and static variables are okay if they're not really variable.
The two ways to do this is by marking them constant (const modifier) or readonly (readonly modifier).
Example:
public class UtilitiesClass
{
internal UtilitiesClass() { }
public void UtilityMethod1()
{
// Do something
}
}
// Method 1 (readonly):
public static readonly UtilitiesClass Utilities = new UtilitiesClass();
// Method 2 (property):
private static UtilitiesClass _utilities = new UtilitiesClass();
public static UtilitiesClass Utilities
{
get { return _utilities; }
private set { _utilities = value; }
}
The advantage of method 1 is that you don't have to worry about thread-safety at all, the value can't change.
Method 2 is not thread-safe (though it's not difficult to make it that), but it has the advantage of allowing the static class itself to change the reference to the utilities class.
No, it is not a good practice for large applications, especially not if your static variables are mutable, as they are then effectively global variables, a code smell which Object Oriented Programming was supposed to "solve".
At the very least start by grouping your methods into smaller classes with associated functionality - the Util name indicates nothing about the purpose of your methods and smells of an incoherent class in itself.
Second, you should always consider if a method is better implemented as a (non-static) method on the same object where the data that is passed as argument(s) to the method lives.
Finally, if your application is quite large and/or complex, you can consider solutions such as an Inversion of Control container, which can reduce the dependency on global state. However, ASP.Net webforms is notoriously hard to integrate into such an environment, as the framework is very tightly coupled in itself.
Let's say I wanna create a ReadFile method which will accepts either
http://.../url
or
c:...\localfile
What I want is Expressiveness for User of my method (even if it happens to be myself in the first place) which should be the purpose of a modern programming language.
At the same time I don't want the procedural if in implementation but something more OOP with type checking at compile time like for a true type.
So would be nice if I could somehow define a "string" subtype http or c:...
Instead of
ReadFile(String aString)
and test String to be of type http or local
I could use polymorphism and define
ReadFile(SubtypeString1 aString)
ReadFile(SubtypeString2 aString)
where ReadFile would continue to accept normal string but would trigger in background by the .net runtime the checking of 2 class associated with the definition above.
Is there a way to do this somehow in C# or Java ?
Well, you can't subclass String in either C# or Java. It's final (Java) and sealed (.NET) to prevent subclassing.
You could create your own class to wrap a string, of course, and then create your overloads. However, overload resolution is generally performed at compile time rather than execution time, so it wouldn't do what you wanted it to ("triggering in background"). The closest equivalent would be to use dynamic typing in C# 4 to perform overload resolution at execution time... but I still don't think that's a good idea.
It's not really clear exactly what you're trying to do. You might want to create some sort of Resource base type, a factory method to create a Resource from a String, and then two subclasses - e.g. FileResource and WebResource to represent local files and web resources respectively. You would then put appropriate abstract methods in the base class and implement them in each subclass.
EDIT: Your question asked for an answer which is expressive - and that's what this is. You're separating the "work out what this string means" from "read data from the resource", allowing you to pass resources around your API, expressing the meaning clearly. Passing a bare string, it could be anything - including something which is neither a filename nor a URL.
I imagine that you want a factory that would analyse your input string and then create the file reading object based upon what your string looks like:
class FileReader { }
class UrlFileReader : FileReader { }
class LocalFileReader : FileReader { }
class FileReaderFactory
{
public FileReader Create(string uri)
{
if(IsUrl(uri))
{
return new UrlFileReader();
}
if(IsLocalFile(uri))
{
return new LocalFileReader();
}
return FileReader();
}
}
Or following Jon's idea, you could return a Resource that could be passed to your reader class.
No, except:
DIY polymorhism:
public void readFile(String s) {
if( s.matches(HTTP_REGEXP) ) readFileFromHTTP(s);
else if( s.matches(FILE_REGEXP) ) readFileFromLocal(s);
else ...
}
private void readFileFromHTTP(String s) {...}
private void readFileFromLocal(String s) {...}
You can use the String wrapper classes that are supposed to be used for this particular purpose and that will likely make your implementation easier and less error prone as well.
In Java this would be classes java.io.File and java.io.URL:
public void readFile( URL url )
{
...
}
public void readFile( File file )
{
...
}
We have a Student class in our business model. something struck me as strange, if we are manipulating one student from another student, the students private members are visible, why is this?
class Program {
static void Main(string[] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.SeePrivatePropertiesAndFields(s2);
}
}
public class Student {
private String _studentsPrivateField;
public Student() {
_studentsPrivateField = DateTime.Now.Ticks.ToString();
}
public void SeePrivatePropertiesAndFields(Student anotherStudent) {
//this seems like these should be private, even from the same class as it is a different instantiation
Console.WriteLine(anotherStudent._studentsPrivateField);
}
}
Can i have some thoughts on the design considerations/implications of this. It seems that you can't hide information from your siblings. Is there a way to mark a field or member as hidden from other instances of the same class?
There's an easy way to ensure this:
Don't mess around with private members of other instances of the same class.
Seriously - you're the one writing the Student code.
The easiest way to ensure this is to program to an interface, such as:
class Program
{
static void Main(string[] args)
{
IStudent s1 = new Student();
IStudent s2 = new Student();
s1.ExamineStudentsMembers(s1);
}
}
public interface IStudent
{
void ExamineStudentsMembers(IStudent anotherStudent);
}
public class Student : IStudent
{
private string _studentsPrivateMember;
public Student()
{
_studentsPrivateMember = DateTime.Now.Ticks.ToString();
}
public void ExamineStudentsMembers(IStudent anotherStudent)
{
Console.WriteLine(anotherStudent._studentsPrivateMember);
}
}
This will no longer compile due to ExamineStudentsMembers trying to access a private field.
If you are writing the class, you have complete control over it, so if you don't want one object to be able to modify another, don't write in that functionality.
Classes will often use private variables in other instances to implement efficient comparison and copy functions.
Private just means that the member (field/method/etc.) can be accessed only from the within the code of the parent type. From CSharpOnline
Private members of multiple instances are visible and can be invoked. This comes in handy when you are implementing a "copy constructor" or a "clone" method on your type, where the argument is an instance of the same type. If the designers would have made private fields inaccessible, then you may have to create a bunch of getter methods just for clone/copy to get at them. IMHO, I like it better the way it is. Within the same type, Reading another object's state isn't that bad as writing to it though (which could be a DONT-code-convention for you/your team.)
Accessing a sibling's private data may seem wrong when phrased like:
public void ExamineStudentsMembers(Student anotherStudent) {
//this seems very wrong
Console.WriteLine(anotherStudent._studentsPrivateMember);
}
However, it doesn't seem so odd for methods which require this sort of functionality. What methods require accessing a sibling's private data? Comparison methods (in particular equals) and objects in a data structure (say a tree or linked list).
Comparison methods often compare private data directly rather than just the public data.
For a class of nodes that make up a linked list, graph or tree, being able to access a sibling's private data is exactly what is needed. Code in the know (part of the class) can tinker around with the data structure, but code outside of the data structure cannot touch the internals.
It is interesting to note that these two cases are less common in day-to-day programming than when this language feature were first developed. Back in 1990s and early 2000s, in C++ it would have been much more common to build custom data structures and comparison methods. Perhaps it is a good time to reconsider private members.
i like the second point, you can look, but dont touch those private members.
it's funny you should say that, i knew a teacher once and he said he often had a problem deciding what classes it was ok to look at the members and which ones he could actually have a play with.
An object is just a piece of data; the class contains the functionality. A member method is just a nice trick the compiler plays; it's really more like a static method with an implied argument (sort of like extension methods). With that in mind, protecting objects from each other doesn't make any sense; you can only protect classes from each other. So it's natural that it works that way.
No, this is necessary, the method code is not specific to the instance, it is only specific to the type of the object. (virtual methods) or the declared type of the variable (for non-virtual methods). The non-static fields, on the other hand, are instance specific... That's where you have instance-level isolation.
The only difference between a static method and a non-static method is that the static method is not allowed to access other instance based (non-static) methods or fields. Any method that CAN be made static without modification will not be affected in any way by making it static, except to force compiler to throw errors anywhere it was called using instance-based syntax.
If you intend to examine a given student's information then I would change the method to be static:
public static void ExamineStudentsMembers(Student student)
{
Console.WriteLine(student._studentsPrivateMember);
}
You would then use Student.ExamineStudentsMembers(s1). Using s1.ExamineStudentsMembers(s2) would be invalid.
If this isn't the intended purpose I would rewrite the method as:
public void ExamineStudentsMembers()
{
Console.WriteLine(_studentsPrivateMember);
}
The above would then be used by writing s1.ExamineStudentsMembers()
Private members are to hide implementation details from clients. The clients should only see the interface (public methods / fields / properties).
The purpose is not to protect the programmer from himself.
This is also NOT a security feature because you can always access private fields via reflection.
It's really to separate interface & implementation (black box design), and clients programming against a contract (all public fields).
For example if you have a public get property, it could access some private field directly, or it could calculate the value from some other fields.
The purpose is, the client only knows the contract (the public property) and the implementation can be changed without affecting the client
Object scope does not ever imply security - ever! It is role of the OS to provide runtime security. It is a bug to design a system that relies on language specific object scope to limit runtime object instance data access. If this were not the case, then all non OO languages are, by definition, not secure.