|
you're welcome.
|
|
|
|
|
Well I am sad to say that I have usually avoided inheritance because I don't have a full understanding of it and/or I haven't yet found a good use for it.
So my newest learning project is a client / server (have been posting about it you may notice alot). A brief overview of what I have been doing is passing my custom object over TCP. My custom object is a seperate DLL project.
Erik didn't like it but to be honest I haven't came up with a better way or fully understood. AFter reviewing hie article that he pointed me to I'm just wondering if I should be using a interface and/or inheritance.
Here is my Commons object:
[Serializable]
public class Commons
{
public Commons()
{
TimeStamp = DateTime.Now;
}
public enum Tasks
{
CHECKIN,
DISKDRIVE,
DRIVEINFO,
FAN,
MESSAGE,
PHYSICALMEMORY,
PRINTERS,
PROCESSES,
REGISTER,
SERVICES,
SOFTWARE,
ADD_CMD,
CLOSECD,
GET_ALL,
REBOOT,
OPENCD,
SHUTDOWN
}
public Tasks Task { get; set; }
public Tasks AddTask { get; set; }
public DateTime TimeStamp { get; set; }
public string AgentId { get; set; }
public string Netbios { get; set; }
public string IpAddresses { get; set; }
public string PhysicalAddresses { get; set; }
public string Message { get; set; }
public int LocationID { get; set; }
public Software[] Software { get; set; }
public Services[] Services { get; set; }
public DiskDrive[] DiskDrive { get; set; }
public DrivesInfo[] DriveInfo { get; set; }
public Memory[] Memory { get; set; }
public Printers[] Printers { get; set; }
public Processes[] Processes { get; set; }
public Fan[] Fan { get; set; }
}
Now those other classes look like this:
[Serializable]
public class Printers
{
public string PrinterName { get; set; }
public string PaperSizes { get; set; }
public string PrinterResolutions { get; set; }
public bool SupportsColor { get; set; }
public bool IsDefaultPrinter { get; set; }
public bool CanDuplex { get; set; }
public bool IsPlotter { get; set; }
}
So getting an idea of what I'm trying to do, I am wondering if a situation like this will best serve using a interface and/or inheriting a class? I get the idea, you implement a interface, you inherit a class.. but like I said I haven't put together a good use for something I'm trying to do.
Now what I am doing with this data once it reaches the server is inserting it into SQL. If a client gets the TASK == PRINTERS, then it will perform a lookup using WMI of all local printers, poopulate the Printers[] array and send back to the server. So server gets the TASK == PRINTERS and see the Printers[] array is populated and proceeds to insert that data into SQL.
Sorry if this question is kind of broad.
|
|
|
|
|
Jacob D Dixon wrote: I get the idea, you implement a interface, you inherit a class..
So you understand more than many here.
In most cases, I define an interface and an abstract class to act as a base for other classes. However, maybe you don't need a hierarchy of classes at all. I was playing with WCF last spring and didn't need a hierarchy of classes. With a Web Service, your client usually makes calls to different methods of the server, rather than sending different commands to one method.
I guess I'd need a higher-level overview of what you're trying to accomplish to give a better answer. The big question is... Is this an actual thing you need? Or merely an exercise to learn new things?
|
|
|
|
|
PIEBAL,
Everything I do is just an exercise to learn new things. I'm not currently a programmer or in school for doing this stuff. (I am in school for programming but they teach you very basic crap, and nothing like this... at least the school I'm in).
I'm currently a Network Engineer and setup this software called LabTech. It is a remote monitoring / control application. You have your server out on the internet, and install agents to different locations (different networks). They report stuff like hardware, processes, services, and more. I know that it is made with VB.net and possibly some C#.
Anyways I just wanted to try to make my own applicaton that was similiar. So far I have my server and agent. They communicate and transfer data (my Commons object) over TCP (Socket Class).
The server holds in memory "pending commands". With each Commons object is arrays, Agent ID, and other things (you can see this class in the first post). So basically we are just transferring that back and forth. So when the agent checks in, the server looks in memory (a List<commons>) to see if there are any Commons object that pertains to that agent (by AgentID.. GUID).
So lets say I want a certain agent to get a list of processes and return to server. I manually add (for right now) a commons object to the List on the server.
The agent checks in.
Server queries the List<commons> object for objects that match that Agent's ID.
Server returns array of Commons[] object (because it might have more than one command) to client
Client performs the commands
Client returns array of Commons[] object to server
Server loops through and inserts the data into SQL.
So if we are wanting the agent to get its Services and send to data we will set the Commons Object TASK to Services and the client will populate the Services[] array (Which is just another class that holds stuff like ServiceName, Status, etc).
For this exercise I rather not use a web service. I wanted to learn more about TCP protocol. The server is using the Socket class asyncronous and the client is not. Here is a post where Luc helped me out with my server's Socket implementation:
http://www.codeproject.com/Forums/1649/Csharp.aspx?fid=1649&fr=151#xx0xx[^] (this is working fine).
Hope that helps you understand more of what I'm doing
Note:
And of course I can always send you my project if you wanted lol.
modified on Saturday, December 4, 2010 11:22 PM
|
|
|
|
|
Oh, yeah, OK. Personally I'd use WCF, but learning sockets can be good too (I have done very little of it). A more advanced technique would be to have the communication layer abstract, perhaps with a plug-in*, so the client and server don't actually know or care how the communication is performed (as long as they are both configured the same).
I'll re-read the other post and see if I can think of anything else.
* Which also usually uses an interface and maybe an abstract base class.
|
|
|
|
|
I think using a web service would make the task easier. I just want to get a handle on Sockets and a good "design" of a client / server model. Erik also suggested the same thing as you about the communication layer. Saying that the server should handle anything thrown at it pretty much. I just haven't been able to wrap my head around his suggestions on how to make it work for me for this particular project. I mean technically right now it does handle everything. It detects if it is a Commons[] object, and if it is then does something with it. If it isn't a Commons[] object then it just does nothing with it.
But the way I have it designed.. any future updates would require the server to be updated (which would mean the agents couldn't check in at that time), and the agents to be updated depending on what is being added. Like if I wanted to make v2 be able to reboot the agents to safe mode, then most likely it would require a server & agent upgrade. I just don't see how to get around doing this task without an upgrade later on.
I hope that makes sense. I guess I'm just looking for pointers on making my classes more "professional" and easier to manage. I mean I think they are easy to manage because I built them lol.
|
|
|
|
|
The socket-oriented communication to a third-party system that I had to do on my last job was very simplistic (circa 1980s?). It was strictly ASCII text -- the first two characters were the number (type) of message, the next four characters were the length of the message, followed by the data of the message. I used an enumeration (as you did) to hold the message types, but I had no need of defining a hierarchy of message classes.
I just took a quick look at my code and I see that I defined one class, which derives from EventArgs; it is used for sending and receiving the messages. Received messages are passed up the chain by events. Sent messages are passed along to the log via events. Otherwise I probably wouldn't defnie a class at all. The Windows Service that performs this communication merely reads new messages from a table, sends them, and marks them as sent; and reads messages from the socket and inserts them into the database (marked as received). Other Services handle entering messages to send and dealing with responses.
|
|
|
|
|
I've been thinking a lot about this and looking at some of the other post. In my situation I am leaning towards leaving it the way it is. (As in not using inheritance). I mean if you really think about it, any update would require the server to be updated along with the agent on the systems. I don't see a way around this.
I do like the idea of sending the four characters to specify the type of message that was being sent.
|
|
|
|
|
Have your client code use reflection and generics to dynamically invoke your object's methods:
<br />
#region Libraries<br />
using System;<br />
using System.Collections.Generic;<br />
using System.Reflection;<br />
#endregion<br />
<br />
namespace Utilities<br />
{<br />
public class DynamicMethodInvocation<T, R><br />
{<br />
public R Invoke(string MethodName, IDictionary<string, object> methodParameterValues)<br />
{<br />
return Invoke(MethodName, methodParameterValues, null);<br />
}<br />
<br />
public R Invoke(string MethodName, IDictionary<string, object> methodParameterValues, object[] constructorParameters)<br />
{<br />
T instance = (T)Activator.CreateInstance(typeof(T), constructorParameters);<br />
MethodInfo mi = instance.GetType().GetMethod(MethodName);<br />
if (methodParameterValues != null)<br />
{<br />
ParameterInfo[] parameters = mi.GetParameters();<br />
object[] values = (object[])Array.CreateInstance(typeof(object), parameters.Length);<br />
foreach (ParameterInfo parameter in parameters)<br />
{<br />
values[parameter.Position] = methodParameterValues[parameter.Name];<br />
}<br />
return (R)mi.Invoke(instance, values);<br />
}<br />
else<br />
{<br />
return (R)mi.Invoke(instance, null);<br />
}<br />
}<br />
}<br />
}<br />
Kevin Rucker, Application Programmer
QSS Group, Inc.
United States Coast Guard OSC
Kevin.D.Rucker@uscg.mil
"Programming is an art form that fights back." -- Chad Hower
|
|
|
|
|
Hello ,
While I use a different coding platform, I've worked a bit with inheritance and client/server applications. The examples described below is pseudocode (okay, I lie, it's a hack of mostly Delphi mixed with pseudocode, so sue me :P), so you should be able to make a decision as to whether you would want to use inheritance or not.
Your particular scenario involves transporting data between a client and a server. What data is being transported (for argument's sake) isn't actually what's important, how you *interpret* the data, on either side of the protocol, is. The core functionality of your base class involves just putting the data into a stream and reading the data from a stream. Nothing else. You don't want your objects to do more than it needs to. The specialisation of each (derived) class will contain the specific enhancements that you would want from it. So for my example, you have your class defined like so:
TYourBase = class(TObject)
protected
procedure WriteToStream(AStream : TMemoryStream); virtual;
procedure ReadFromStream(AStream : TMemoryStream); virtual;
public
function ToStream : TMemoryStream;
procedure FromStream(AStream : TMemoryStream);
end;
With your implementation for this class looking something like this:
procedure TYourBase.WriteToStream(AStream : TMemoryStream);
begin
end;
procedure TYourBase.ReadFromStream(AStream : TMemoryStream);
begin
end;
function TYourBase.ToStream : TMemoryStream;
begin
Result := TMemoryStream.Create;
WriteToStream(Result);
end;
procedure TYourBase.FromStream(AStream : TMemoryStream);
begin
ReadFromStream(AStream);
end;
Now for the inheritance part. Let's say that your derived class needs to contain a few accessors (a string, an integer and a float). You would define it something like this:
TSomeDescendant = class(TYourBase)
protected
procedure WriteToStream(AStream : TMemoryStream); override;
procedure ReadFromStream(AStream : TMemoryStream); override;
public
SomeString : String;
SomeInteger : Integer;
SomeFloat : Real;
end;
With the implementation looking something like this:
procedure TSomeDescendant.WriteToStream(AStream : TMemoryStream);
begin
inherited WriteToStream(AStream);
AStream.WriteString(SomeString);
AStream.WriteInteger(SomeInteger);
AStream.WriteFloat(SomeFloat);
end;
procedure TSomeDescendant.ReadFromStream(AStream : TMemoryStream);
begin
inherited ReadFromStream(AStream);
SomeString := AStream.ReadString;
SomeInteger := AStream.ReadInteger;
SomeFloat := AStream.ReadFloat;
end;
Now, when you want to read or write from a stream, all you will need to do is something like this:
var
LSomeObject : TSomeDescendant;
LStream : TMemoryStream;
begin
LSomeObject := TSomeDescendant.Create;
LSomeObject.SomeString := 'test';
LSomeObject.SomeInteger := 1;
LSomeObject.SomeFloat := 5.5;
LStream := LSomeObject.ToStream;
FreeAndNil(LSomeObject);
LSomeObject := TSomeDescendant.Create;
LSomeObject.FromStream(LStream);
end;
This is just one way in which you can use inheritance to simplify your streaming of data. To put this into an even broader context. You can define virtual methods in your ancestor class(es), to do things like validate the class or anything you want. Bearing in mind your example, you could define a virtual method to persist the data. That way you can define descendants that don't necessarily persist your data to SQL server, it could persist to anything you like: XML, Excel, [insert your favourite persistance flavour here].
I hope this helps you understand a bit more about how inheritance can help you build your class(es) to do as little as it possibly needs to do, while still allowing it to function correctly. By defining virtual and abstract functions and methods, you allow your derived classes to do what it needs to do, specific to itself. Where you define your printer class, you can specifically stream your data for that class. If you define several other classes, you can define specific reading and writing to the stream. This is how you provide polymorphic behaviour to your objects.
My example of writing and reading from a memory stream may not pertain to your example specifically, so I'll leave you with this final story: One of the more classic 'real life' examples of polymorphic behaviour is the question "What makes a saw a saw?". Programmaticaly, If you define a class called TSaw with a (virtual) method called Cut. The TSaw object itself does not know what to do when it needs to Cut. But you can define TRipSaw and THackSaw descendants which overrides the Cut method. They are still both TSaw descendants (and for all intents and purposes, they are still both saws), but they Cut differently. You wouldn't use a THackSaw to Cut wood, nor would you use a TRipSaw to Cut metal, but they both Cut and they are both saws... ...
Okay, I'd better stop this monologue and let you decide from there ...
Cheers,
Glen Vlotman
|
|
|
|
|
Inheritance should be used sparingly in business applications. In reality, in terms of these applications, inheritance has limited value compared to the internals, military, and scientific sectors.
Developers who use inheritance for the most part use it unnecessarily add a lot of ambiguity to the systems they are working on. Nonetheless, there are reasonable situations where inheritance can be of value; the most important being where you have numerous different types of constructs that basically belong within a same set of data (ie: security types; employee types).
That being said here are a few axioms that you should always follow when using inheritance as described by Tom Patton a number of years ago in his second edition of his COM+ Component programming manual:
1) Never use more than three levels of inheritance. Once this rule is broken inheritance hierarchies tend to become too complicated for easy maintenance.
2) Never use a "Protected" access modifier for a variable or method implementation. This attribute has been the bane of many inheritance hierarchies causing
them to fail. The reason being is that they tend to break such hierarchies when updated during maintenance.
3) Test your inheritance hierarchy thoroughly to make sure that it works in all scenarios as expected.
4) Test your inheritance hierarchy for its level of "black-box reuse". The more an inheritance hierarchy can be used without any understanding of anything
but the public API, the more concrete your structure will be. Most inheritance hierarchies tend to fall in the "white-box reuse" range meaning that there
are higher levels of maintenance required, which is not what you want.
5) If you find that your hierarchy is causing more issues than warranted either redesign it or drop the implementation all-together. It will only get worse as
it enters a production mode.
Steve Naidamast
Black Falcon Software, Inc.
blackfalconsoftware@ix.netcom.com
|
|
|
|
|
Err ... I could go a lot about the pros and cons of inheritance and interfaces. Good and bad design is all a matter of taste anyway. Or to put it another way, no two programmers will ever agree. What I will say is it is important to be consistent, at the very least, and if you find you are posed with these types of questions then in all likelyhood you haven't done enough preparation in your design.
I'll point you in the direction of a book called "Head First Design" patterns. It is easy to read and gives you a good understanding of the issues involved in OOP&D. At least, it helped me bridge the gap between structured/procedural programming and OOP.
|
|
|
|
|
Hi mbb01,
I totally agree with you there. In programming we have the gift (or curse - whichever way you look at it) of a plethora of implementations that will provide you with a multitude of solutions to your given scenario. The real test of a good developer is to select the solution/implementation which is not necessarily the 'best' solution, but the one that is the most correct given the tools that you have at your disposal.
What I've found through my years of coding, as I'm sure most of the people here have, is that the solution which usually ends up being used, is a cross between 2 or more methodologies meshed into a symbiotic balance of using the pros from them to the solution's advantage, while mitigating the cons of these methodologies. The bottom line is: there is no "silver bullet".
Wrt books, my poison of choice is "Design Patterns: Elements of Reusable Object-Oriented Software" by TGoF, with ISBN-10: 0201633612 or ISBN-13: 978-0201633610. This book provides a overall approach to understanding in (relatively simple) laymen's terms the bulk of the most popular design patterns that are out there.
Cheers,
Glen Vlotman
|
|
|
|
|
Thanks guys! I really didn't plan any of this to be honest. I was just trying to learn and figure out Sockets. Either way I would like to design a product like the LabTech software I was speaking of, but like you mentioned I should plan it out before trying such a project.
|
|
|
|
|
Jacob, there is nothing wrong with using inheritance. This is one of the pillars of OOD/OOP. Through inheritance, you also get polymorphism, one of the other pillars. You want to use an interface vs. a base class. An interface is a "base class" in theory, but has no definition. Rather it is a contract. The interface you derive your class from says that the derived class will define (host) these methods. A true base class (even abstract base class) holds common methods and data that derived base classes use. Think back to biology, when they discussed about the various classes, species, etc. of plants and animals. We all know that dogs and monkeys are types of mammals. This signifies inheritance, since mammals have certain attributes common to both dogs and monkeys. Then both dogs and monkeys have their differences. (And C# and Java can only have a single base class makes it easier.) The fact that both dogs and monkeys are mammals signifies polymorphism. This also signifies the "is a" relationship. A dog is a mammal. Therefore, the dog inherits traits and attributes (methods and data) from the mammal.
There is also the "has a" relationship where the class contains (encapsulates) a data item. Much like your Commons class contains two Task objects. A dog has four paws instead of hands and feet. Of course, these could be specialized derived objects in the base mammal object.
In the case of your Commons and Printers classes, it can stand as it is, since all it carries is data. If your properties are going to do more processing with the internally stored data, then an interface would be good if you plan to have other ways of holding your Commons data.
The main arguments for using inheritance that I have run up against is the "has a" vs. "is a" relationship. If your class "is of" another class, then use inheritance. If you class contains another class/object, then add that object as a data object.
I have also found that as I create objects/classes, sometimes I find that two or more of the objects have similar methods and data. That is a good place to use inheritance. Take the common methods and data and re-factor them into a base class and have both the old classes inherit from the base class. Also, if I find that I do need to inherit from two or more classes (as back in the old C++ days), see which one is the best choice to inherit from and encapsulate the others.
|
|
|
|
|
|
Hi,
I'm not sure what it is you want, not even what platform you are using: DirectX, XNA, WinForms, ...?
If it is WinForms, you might want and read this little article[^].
FYI: There are quite a number of articles about games here on CodeProject.
|
|
|
|
|
ok sorry, erm... what i want is to scrool the grid as the player moves from the right to the left so that the player can proceed through the level and it isn't all displayed at once
i am using winforms to make my game
|
|
|
|
|
OK, read the article I provided a link to. Then whenever the grid has to move (by user action or timer), change your relevant data values and call Invalidate to get everything repainted.
If everything is linked to a grid, and only part of that is visible, have a Location variable (i.e. a Point with X and Y) that holds the distance from your grid's top left corner to your visible area's top left corner, and offset everything inside your Paint handler by that distance. Graphics.TranslateTransform() could do all that for you.
BTW: if you haven't already, I suggest you make your painting area double-buffered to reduce or avoid flicker.
|
|
|
|
|
|
Please don't delete your questions. Now it's impossible to follow the context of this question, and it could have been something useful to others. You've been a poster long enough to know that you shouldn't be doing this.
|
|
|
|
|
Yes, there already is another guy asking basically the same thing, it is a bit harder now to convince him the subject got handled here.
|
|
|
|
|
how we can make an windows forms with own codes?
tanks!
|
|
|
|
|
Hi,
A bit of a broad answer, but I'm having trouble trying to figure out what you're trying to do, and how.
nasis1 wrote: how we can make an windows forms with own codes?
Using Visual Studio? Start a new project of the type "Windows Application". That should open a new template for a Windows-Application, including a single form that you can edit to your liking.
If you're on a different system, or don't have Visual Studio, you'd create a new project, add the reference to "System.Windows.Forms.dll", add the "using System.Windows.Forms" on top of your file, and then you can declare new forms;
class MyForm: System.Windows.Forms.Form
{
}
static class Program
{
static void Main (String args[])
{
System.Windows.Forms.Application.Run (new MyForm);
}
}
There's a lot of information to be found on MSDN[^], if you scoll halfway the page you'll find some common walkthroughs.
Hope this helps a bit
I are Troll
|
|
|
|
|
The same way you get to Carnegie Hall.
|
|
|
|
|