From: Dieter W. <wi...@oe...> - 2001-10-23 19:07:20
|
Hi Kelvin, Well I have also to get back to some real work, as I am up to do an exam tomorrow :) However, here some explanations on the questions you had: 1. Why not reading frames from the ASCIIInputStream? Well this is easily answered, as this is the only way to make use of the structure as it is in my package. The message implementations can keep reading what is in their responsibility themselves, as the stream can be passed on without problems. The Transport class has the responsibility of knowing frames, and handling frames as such. This means you could simply pass on the : character and the CRLF character (anything outside 0-9 A-F) should do the job. The transport should read from the stream, check for the start character and the address (if it is addressed, and we need to think about where this address comes from :) etc.... 2. Why producing the LRC byte for byte? Well this is not much of an issue, if you check out the sources of the I/O streams of the Java API, you will realize that at the end of the day all your reads end up in native public int read() somewhen. Despite that your code will loop over the byte array too, so performance of the one byte at a time is probably even better then looping. I am still not exactly sure however if the LRC is performed on each raw byte (i.e. still encoded) or on the decoded ones. I will check this out when I find time again, i.e. after my exam. 3. Why using a FilterInputStream? The use of FilterInputStream is for model reasons as it does exactly what is stated also in the API, it transforms the raw data exposing a standard interface. All reads in Java are blocking, and I do not exactly understand what you mean with "byte banging", probably you can explain this term to me. I guess I have to code this out to see what it does and whether it works out :) 4. Why the Modbus interface? This interface is solemnly serving the purpose of holding globally accessible constants. I have realized that it does not make any difference if you use a class or an interface with constants, despite that the class needs extra care to prevent instantiation (i.e. a private constructor). I am not even sure, but I think the compiler makes the same out of it (got to check the bytecode specs once to know). The use is Modbus.CONSTANT_NAME in any case from anywhere in the rest of the code as it is completely public. 6. Why the ModbusTransaction interface? This is one of the contracts I have been talking about. I think it is reasonable to go like this, as for example a Transaction for ModbusASCII transported messages might have to be implemented differently. The rest of the code using transactions can be coded against the interface, and would not realize any difference :) 7. Why the ModbusMessage interface? This is probably the only place where it is not so necessary to make such a construct. However, if you want to optimize or make a different implementation of ModbusMessage then the one given by ModbusMessageImpl) you could go ahead without the need to change certain other parts of your code (e.g the transports for example). All this depends on how good your model and your abstraction/specialization was :) 8. What is a Singleton? Well this is a Pattern that serves the purpose of having only one instance at runtime. Basically there are different approaches to this in Java, however, the way I implemented it, is stemming from a very good book on object oriented programming/design patterns. This "bible" is Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. 1995. Design Patterns. Addison-Wesley. Reading,Mass. There are entries in the code snippets for Java, with some changes, even done by people that are a bit strange, just overwriting parts and not even documenting what they exactly did ;) Regards, Dieter |