|
jesarg wrote: As smart as we might be, the cold reality is that no one is smart enough to make an initial design up front for a complex application until they've actually built something similar to verify that the design was, indeed, a good design. Just about any design can look good on paper to an entire review committee, but only designs that are based off past successful implementations of similar ideas can really be confidently considered "good".
Has anyone else ever been forced to come to this conclusion before?
That's happened to me in nearly every project that I've worked on, and so far, the only consistent design principle that seems to make the most sense is to keep it simple. Good design comes from continuous refactoring, and by the end of a project, a lot of my designs tend to be emergent rather than something intentional. More often than not, I usually prototype my ideas using standard structured programming techniques (without using any OOP mechanics, such as inheritance).
At first, the idea starts of as a very long and ugly static method in a single class, and then I usually use Fowler's classic Refactoring techniques to cut the size of the method down until it's broken down into static methods. At that point, it's still fairly useless since my code is still written to work with a particular prototype case, so the next thing I do is I refactor the static methods into interface dependencies and move the static implementations over to classes that serve as default implementations of those particular interfaces. The idea is to take the most straightforward approach to writing an application, and then refactor and generalize it so that you can extend it. TDD takes the same approach with its "test first" mantra, and this style of development has yet to fail me. (BTW if you want to look at some samples of my design work, click here.[^])
Now that I think about it, writing good code and having good design principles is like trying to sculpt a melting ice block in the middle of the desert. If you spend too much time thinking about what the design should look like, you'll end up with nothing but a puddle of water. If, on the other hand, you know exactly what you need to chip away in order for the ice sculpture to take shape, then all you have to do is constantly reshape it until the sculpture emerges from the ice block, and hopefully you can get it done before the ice melts...
|
|
|
|
|
jesarg wrote: "Although we agree that good design might be necessary for good code to be produced, good code is necessary for good design to be produced as well".
"A chain is only as strong as its weakest link."
|
|
|
|
|
I've been going around in circles trying to design a new toolkit to create a certain kind of application with. What I think I'm realizing is that it's sometimes best to design classes in such a way so that they make the fewest assumptions about the environment in which they will be used.
What this means from a design standpoint is that when designing a class to represent a specific concept, you do so in isolation; you make the class as cohesive as possible as a standalone entity.
So where do you go once you have your finely crafted class? How do you integrate it into a context in which you are working?
I think the adapter design pattern is the answer. Adapt the class so that it's interface is fitted to the rest of the application.
This is a kind of bottom-up approach. And it may not seem sensible at first. But I have repeatedly found myself getting entangled in too many details when I try to consider the overall picture when designing a specific class. I'm having better luck designing classes so that they make sense on their own without any scafolding to support them. I leave the other details for later.
|
|
|
|
|
In situations like this, I would tend to look at using something like Test Driven Development and Inversion of Control and not actually design my classes in isolation - this is just acting for trouble.
|
|
|
|
|
Pete O'Hanlon wrote: In situations like this, I would tend to look at using something like Test Driven Development and Inversion of Control and not actually design my classes in isolation - this is just acting for trouble.
Thanks, I've never given TDD a very close look.
I agree that designing in isolation is not a good approach generally speaking. It may be that what I'm learning, though, is that if you have a set of low-level classes, it may be better if you can design them to make the fewest assumptions possible about the higher-level classes that will use them. Kind of postponing dealing with certain details for as long as possible. This may help reuse.
What I'm struggling with is keeping higher level policies from getting entangled with the low-level algorithms that do the work.
Anyway, just thinking out loud.
|
|
|
|
|
What I'm struggling with is keeping higher level policies from getting entangled with the low-level algorithms that do the work.
if higher level polices are dependent on low-level algorithm and if low-level algorithm are changing...or if you want to make higher level polices independent of low-level algorithm then go for Strategy or Template Method.
|
|
|
|
|
I am looking for componet library in C# vb.net for grnral business development.
All pointers will be appreciated.
Tapas Shome
System Software Engineer
Keen Computer Solutions
1408 Erin Street
Winnipeg, Manitoba
Canada R3E 2S8
http://www.keencomputer.com
|
|
|
|
|
Take a look at Rocky Lhotka's CSLA toolkit.
|
|
|
|
|
Is there any good documentation, except his books, on that? I built my first (and only) nation wide client server system based on the original CSLA, from the "VB6 Business Objects" book. I came short with child objects having child objects, but he has long since addressed that, and I am more than willing to give CSLA a try.
Pits fall into Chuck Norris.
|
|
|
|
|
He keeps his website up to date - has a very active forum on it, and (if you use CodeSmith) you can get fairly up to date CSLA templates to generate your code.
|
|
|
|
|
Hi,
Anybody please help me with this issue,
i am having two list views. Both these are having scroll bars.
What i want is that, i have to make only one scroll bar for both the listviews, so that if i am scrolling the scroll bar of the first listview, both should get scrolled...
i have seen in one application that its possible, that is not in c#, its purely VC++.
So please i need a help for this.
Thanks in Advance,
Roger
|
|
|
|
|
|
|
|
Pete O'Hanlon wrote: The C# forum.
And if that doesn't work, you can go here[^].
|
|
|
|
|
As in I have always worked on CRUD systems. I have googled for a list of systems but haven't been able to find much. I guess i'm just getting bored of the usual n-tier front end to a DB stuff, and want to know what else is going on.
Any help much appreciated.
Cheers.
|
|
|
|
|
Are you looking for types of software not like a business application using Database I/O as a main part of the system? So something like a Game or a Missile Guidance System? Are you looking for work in a different sector of the industry? I find your post rather unclear.
led mike
|
|
|
|
|
Mike thanks for your reply. I guess i'm interested in different architectures. Not looking for another job, just want to expand my knowledge. I guess a 3-tier archictecture is popular for DB storage and retrieval. What about when banks go mental processing stuff at night, batch processing etc - output of one app becoming input to another. Is there a name for a system (CRUD) or architecture (n-tier) like that? Do you know what i'm getting at? When you say missle guidance system i think of embedded C or something, but am interested more in higher level langauges. Maybe i need to check out design patterns more. Maybe a Model View Controller is another kind of system?
Wow big ramble. Probably best to just smile and nod.
|
|
|
|
|
Well I highly recommend everyone study Software Design Patterns but they have little to do with architectures and specifically Model-View-Controller is a design not a different kind of system. CRUD isn't really an architecture it's just an acronym describing basic Database operations. N-Tier is an architecture concept. It's not all that complex conceptually and it seems you might be over complicating this issue for yourself.
Systems design and architecture should be based on requirements. Systems should, although don't always, have an architecture that meets the needs of the use model and any enterprise/network/platform that they are required to operate within.
If you are having trouble consuming all these different terms and understanding them I highly recommend Wikipedia for introductory high level definitions of things like Design Patterns and N-Tier and CRUD etc.
led mike
|
|
|
|
|
I'm designing a class library to facilitate communications over TCP/IP. It has ease of use in mind and is event-oriented. Despite the departure from the base class library's way of exposing the networking functionality (synchronous and asynchronous methods), the class library I’m writing is based on a couple of classes from the base class library—the TcpListener and TcpClient classes in particular. It doesn't derive from it, but the API is very similar:
public class CorruptDataException : ApplicationException- public CorruptDataException()
- public CorruptDataException(string message);
- public CorruptDataException(string message, Exception innerException)
- protected CorruptDataException(SerializationInfo info, StreamingContext context)
public sealed class ConnectCompletedEventArgs : EventArgs- internal ConnectCompletedEventArgs(object userToken)
- public object UserState { get; }
public sealed class DisconnectedEventArgs : EventArgs- internal DisconnectedEventArgs(DisconnectReason reason, object userToken)
- public DisconnectReason Reason { get; }
- public object UserState { get; }
public enum DisconnectReason : int- DisconnectCall = 1
- None = 0
- RemoteDeviceDisconnected = -1
public sealed class ReceiveCompletedEventArgs : EventArgs- internal ReceiveCompletedEventArgs(Exception ex, IList<byte[]> data, object userToken)
- public IList<byte[]> Data { get; }
- public Exception Error { get; }
- public object UserState { get; }
public sealed class SendCompletedEventArgs : EventArgs- internal SendCompletedEventArgs(Exception ex, object userToken)
- public Exception Error { get; }
- public object UserState { get; }
public sealed class SlipClient : IDisposable- public SlipClient()
- public void Connect(EndPoint remoteEP)
- public void Connect(IPAddress[] addresses, int port)
- public void Connect(IPAddress address, int port)
- public void Connect(string host, int port)
- public void ConnectAsync(EndPoint remoteEP, object userToken)
- public void ConnectAsync(IPAddress[] addresses, int port, object userToken)
- public void ConnectAsync(IPAddress address, int port, object userToken)
- public void ConnectAsync(string host, int port, object userToken)
- public void Disconnect()
- public void DisconnectAsync(object userToken)
- public override void Dispose()
- public IList<byte[]> Receive()
- public void ReceiveAsync(object userToken)
- public void Send(IList<byte[]> data)
- public void SendAsync(IList<byte[]> data, object userToken)
- public event EventHandler<ConnectCompletedEventArgs> ConnectCompleted
- public event EventHandler<DisconnectedEventArgs> Disconnected
- public event EventHandler<ReceiveCompletedEventArgs> ReceiveCompleted
- public event EventHandler<SendCompletedEventArgs> SendCompleted
- public bool Connected { get; }
- public EndPoint LocalEndPoint { get; }
- public bool NoDelay { get; set; }
- public int ReceiveTimeout { get; set; }
- public EndPoint RemoteEndPoint { get; }
- public int SendTimeout { get; set; }
public sealed class SlipClientAcceptedEventArgs : EventArgs- internal SlipClientAcceptedEventArgs()
- public SlipClient Client { get; }
- public Exception Error { get; }
- public object UserState { get; }
public sealed class SlipListener- public SlipListener(IPEndPoint localEP)
- public SlipListener(IPAddress localaddr, int port)
- public void AcceptSlipClientAsync(object userToken)
- public bool Pending()
- public void Start()
- public void Start(int backlog)
- public void Stop()
- public event EventHandler<SlipClientAcceptedEventArgs> SlipClientAccepted
- public bool Active { get; }
With the exception of CorruptDataException, which happens to be under the first level (root) namespace, all the other classes are under a third level namespace company.Net.Sockets. As you can see, the two main classes are SlipListener and SlipClient. "SLiP" happens to stand for serialized list protocol. In its current incarnation, it only serves to facilitate the transmission of messages with parameters. I won’t get too deep into the format of the byte stream right now. I’ll save that for an upcoming article.
Okay, I’ve been babbling on long enough. Now for the questions (which concerns the SlipClient class for the most part):
- The SlipClient class has two internal AutoResetEvent fields. One controls access to the send methods, and the other controls access to the receive methods. In effect, one send method must return (or the SendCompleted event raised) before another send method can proceed. The logic is similar for the receive methods. Should I scrap the wait handles and allow calls to the send and receive methods to be uncontrolled by the class?
- For the SlipClient class, the synchronous Receive method returns null if the remote machine disconnects before all the necessary bytes (the ones needed to reconstruct the IList<byte[]> that was sent) are received. In conjunction, it raises a Disconnected event using a ThreadPool thread (so the event handler can’t block the rest of the Receive method from executing). Should I throw an exception instead of returning null?
- All the networking-related classes are sealed because I’m not sure how to open up the classes to extension. If you were extending the class, what would you like to be able to do?
- You’ll notice that the ReceiveCompletedEventArgs class has a Data property that returns an IList<byte[]>. Yet, I’d like to be able to add other classes like SlipClient and SlipListener, but have them work with something other than IList<byte[]>. In other words, I might have other classes sharing the same namespace. I’m aware of four options I can go along with:
- Return an Object object for the Data property so all my other classes can use it.
- Create another class to encapsulate the data to be sent and work with that class instead of IList<byte[]>. The class will have the necessary properties and methods to allow for flexibility.
- Rename the class to something like SlipClientReceiveCompletedEventArgs so it is exclusive to the SlipClient class’s events. I think it’s a bit long, but I could deal with that.
- Scrap the current class and make a new one that can work for any new classes. I’m not sure how to go about this route, but it sounds nice.
- Should I have the Receive and ReceiveAsync methods at all? I mean, I could have the class automatically fire events as the data comes in, but I feel this will make it very chaotic. Besides, SlipClient is returned by SlipListener, and if the SlipClient class starts firing events before the application can add its event handler, data will be lost. I already know what to do to solve it, but the ideas seem very inelegant, and I’m left thinking it’s better to keep the Receive and ReceiveAsync methods there so the application can control when and how fast it receives data.
It’s been a long message and a big headache trying to make the API conform to .NET standards and conventions—even more so than writing the actual code. I’d be very grateful for input.
|
|
|
|
|
Hi,
I am not going to study and comment on your protocol, but I have one remark:
there already is a SLIP protocol[^], you may consider choosing a different name.
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
That's disappointing.
So the creationist says: Everything must have a designer. God designed everything.
I say: Why is God the only exception? Why not make the "designs" (like man) exceptions and make God a creation of man?
|
|
|
|
|
Hello
Is there a way to change the order of the components in the container.
I know that components follows the order of when it is added in the container.
But is there a way to rearrange the component in the container.
Thanks.
|
|
|
|
|
Which container, which language are you working with ??
|
|
|
|
|
Sorry for being unclear,
Im working with c# in vs2005.
Im pertaining to the IDesignerHost.Container.
I'm looking for example on how to rearrange the components in the container.
thanks
|
|
|
|
|