|
For an application like this OO concepts will only take you so far. Effectively what you are looking at building is an extensible framework that allows third-party customizations without the need to change code. Systems like this can be built but they are not trivial.
You need to start at the framework level and build your core framework in a very well structured way. Even though your core components are related to one another, I would build them as separate pieces as much as possible and provide the hooks necessary for them to interoperate. You also want to make sure that you have a robust data layer.
One approach that I have used in the past is to build things up in layers. I had a data layer that understood XML (and XML only). The data layer had the responsibility of parsing that XML and inserting data into the database and also taking data out of the database and putting it back into XML. My business objects were effectively specialized dictionaries.
The flexibility in the user interface is also going to be a challenge, although if you can guarantee that certain elements will always be there (and in the same layout) you can take advantage of the visual inheritance capabilities offered through Visual Studio. (This is nothing more than regular inheritance where your base class is a visually designable "thing" (like a form or user control). As long as that base class is not abstract you can visually design the derived class in VS just like you normally would.)
As for distribution of changes/fixes, you need to make sure everything is built in a very modular fashion (separate DLLs or assemblies for each component). That will allow you to update specific portions as needed.
If you want to go beyond this and actually implement a system that allows for this without code changes you need a lot more work and design as it will require publishing type services to update the database, which will also require conflict resolution to ensure that you don't remove user-made customizations with an update. From there the problem gets more complex as your business objects must be written in such a way as to be able to expose an unknown number of properties and metadata. The UI then needs to know how to render those objects in a completely dynamic fashion, with rules that govern how that layout works in the face of an unknown number of properties. All of that is possible, but definately not trivial.
Scott.
—In just two days, tomorrow will be yesterday.
—Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
[ Forum Guidelines] [ Articles] [ Blog]
|
|
|
|
|
Hi Scott,
Thank you for your explanation, I think that's exactly what I'm looking for. But now I realize the challenges for creating an extensible framework, are much more than creating the core functionallity. The core should be aware of the possiblity to be extended, and also my business layer should be totally decoupled. I'm wondering I'll need to create a lot of interfaces or abstract classes to allow the interoperabilty between the different objects. In my system there is a lot of interaction between classes, they're tight coupled and I should separate them.
I guess I should create a prototype or look for some extisting model in order to evaluate if the effort in design and decoupling the objects worths it or if I should stay with my current model.
Thank you for your ideas!
Best Regards
|
|
|
|
|
ruben ruvalcaba wrote: think that's exactly what I'm looking for. But now I realize the challenges for creating an extensible framework, are much more than creating the core functionallity.
You're welcome. Yes, creating systems like this is possible but not simple. (I'm involved in building one at work now and it's been a very long road and a lot of work involved.)
ruben ruvalcaba wrote: I'm wondering I'll need to create a lot of interfaces or abstract classes to allow the interoperabilty between the different objects
We are doing things with a combination of interfaces, abstract classes, and generics from the framework layers.
ruben ruvalcaba wrote: In my system there is a lot of interaction between classes, they're tight coupled and I should separate them.
You should look at doing this no matter what. The more tightly coupled your objects are the harder they become to maintain. Generally you want a loosely coupled but highly cohesive system. (http://en.wikipedia.org/wiki/Coupling_(computer_science)[^]).
In the long run, making sure you have a solid and well-thought-out architecture is always worth it as it leads to code that is more easily maintained and extended in the future. It all depends on where you want to spend your time/effort/money - up front in the design or afterwards in the maintenance phase.
Scott.
—In just two days, tomorrow will be yesterday.
—Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
[ Forum Guidelines] [ Articles] [ Blog]
|
|
|
|
|
My users need to be able to specify their own formatting preferences for string output.
So, either in Settings or the database or wherever, they specify a format string: "%lastName% can be reaced at %mainPhone% or %email%" to control the output of this class:
class Person
{
string nameFirst;
string nameLast;
string eMail;
List<Phone> phones;
}
(which is strictly by example - the real object network will be much larger/complicated)(and tokenizing the format string is no problem for me)
I'm wondering how to best produce the final string at runtime in a reasonably efficient manor. It's doubtful there will be more than a few hundred of these items at a time (less than a dozen most likely) and this string will be produced for tooltips, columns in grids, reports, etc. Still - while I don't have to worry about this being executed 1,000 a second - I'd like for it not to be too much of a pig. Maintainability is more of a concern.
It seems to me this is a good use for codeDOM and generating a dynamic method. When the app is loaded, it reads the configuration string and generates a method that looks
string DisplayAs()
{
string fmt = "{0} can be reached at {1} or {2}";
string[] args = { nameLast, SomeMethodThatKnowsHowToDetermin_MAIN_PhoneFromList(), eMail };
return string.Format ( fmt, args );
}
I've never used the codeDOM but I think I can manage something like this. But is this overkill or maybe there's a better way?
I could take a brute force approach and loop through whatever format string the user supplies doing string substitutions based on my list of 'keywords' (i.e. %mainPhone%) but there could easily be a dozen or so of those keywords. That seems painfully inefficient to me - but maybe not to the extent I should worry about it.
Thanks,
Dan Holt
|
|
|
|
|
HoltDan wrote: But is this overkill or maybe there's a better way?
Well it does seem overkill since string.Format(...) will do the trick.
However I am wondering about the larger problem of letting users supply things like format strings. How do they test them, debug them and what mechanisms to you use to guard against runtime errors like mismatching arguments?
led mike
|
|
|
|
|
I guess I could take their input string ("%A% something %M% - %B% @ %T%" - or whatever) and transform it into a format string "{0} something {1} - {2} @ {3}" and load up a list of delegates to return the corresponding args. Kind of like what I'd do preparing to generate the dynamic method in my original example. However, I'd still have to do it per-instance or per-invocation of the method that calls string.Format.
I just don't have a good feel for how efficient something like that is. Plus I'll probably never get the chance to measure in any meaningful context.
Or maybe I'm being dense and there's a design pattern or technique for doing this sort of thing. I looked into IFormatProvider(?) which might be helpful once the code gets down to the nuts 'n bolts of formatting each piece of text, but not in assembling the parameters at run time.
The error handling isn't much of a concern. I simplified the example: in reality, this product gets installed at various customer sites and configuring the display strings to their specifications is something that will be part of the setup. There will be error checking and it will be done infrequently and then by 'qualified' professionals (that's a good one!).
Dan
|
|
|
|
|
HoltDan wrote: The error handling isn't much of a concern.
Ok, good luck
led mike
|
|
|
|
|
Nice selectional quoting there
|
|
|
|
|
HoltDan wrote: The error handling isn't much of a concern. I simplified the example: in reality, this product gets installed at various customer sites and configuring the display strings to their specifications is something that will be part of the setup. There will be error checking and it will be done infrequently and then by 'qualified' professionals
The error handling should be a concern as this can lead to all sorts of unpredicatable input which will have a considerably "higher than average" chance of breaking your application.
You may also want to have a look at the IFormattable[^] interface.
Scott.
—In just two days, tomorrow will be yesterday.
—Hey, hey, hey. Don't be mean. We don't have to be mean because, remember, no matter where you go, there you are. - Buckaroo Banzai
[ Forum Guidelines] [ Articles] [ Blog]
|
|
|
|
|
I'm working on a project that receives GPS pings from multiple sources and locations.
Basically I have to create GPS pings with xy/timestamp/etc from different pieces of data.
One ping might come down from a vendor like "234,345,truck1, s456" through a tcplistener while another I have to fetch from a webserver and comes down in xml <ping><x>234.33.
My question is what type of code pattern or architecture would be best for this solution?
I'm reading about the Strategy pattern and think that would be a good fit.
Like I have a GPSPing class that has a Validate method which invokes the correct strategy for each different vendor I receive pings from.
The validate methods looks at a rawdata property of the GPSPing, then transforms that into the required GPSPing properties I need to finally save it.
Am I way off base here? I'm inexperienced with OO design patterns and OO in general so any help is appreciated?
|
|
|
|
|
turnergg wrote: Am I way off base here?
No. Many patterns have overlapping applications. I have found that using one at all reduces your technical debt significantly. Unless peoples lives hang in the balance I don't waste a lot of time worrying over which pattern is the absolute best to use in a specific scenario.
led mike
|
|
|
|
|
chain of responsibility is one possibly.
for your GPSPing class so that you can add new GPS inputs easily
Tim Yen
|
|
|
|
|
Hi,
How can i declare a global variable in VBA editor.
I have tried with global and public key words. It is throwing error.
Can any one help me.
~Raja Baireddy
|
|
|
|
|
I must not be sarcastic.
I must not be sarcastic.
I must not be ....
Ok - now that I've got myself into my happy place, please don't post things in the wrong forums. You'll only set off the attack hamsters. This is the Design and Architecture forum, not the mucking around in a sh!tty VBA forum. Now please, pick a more appropriate one. Oh wait, if I follow your name around am I going to find that you've cross posted? I hope not.
|
|
|
|
|
Pete O'Hanlon wrote: This is the Design and Architecture forum, not the mucking around in a sh!tty VBA forum.
LMAO Thanks for that early Monday morning laugh Pete!
led mike
|
|
|
|
|
Hi,
A Filling Station manager wants me to build an application that will track/record the sales of fuel(preferably, as entered by the staff) from the electronic fuel meter pump machines. He wants the tracking to be indicated LIVE in the application which is hosted by a computer remotely(in the same station).
To handle this, what should be the design architecture, development strategy, deployment process and security considerations I should implement?
I will appreciate any ideas and help rendered. Thanks in advance.
|
|
|
|
|
First, they don't already have that? WTF
Second, how can a Filling Station manager afford to pay to have a system like that built?
As for strategy I would start with finding out what interface the pumps have.
led mike
|
|
|
|
|
Thats right led mike. And thanks alot for the vital information.
But I have also had a thought for it in terms of strategey and it only involves building a custom fuel pump that is (say 80%) controlled the application based on the given specifications. This is my greatest worry because it solely depends on my filling station manager's pocket as you've said. Well, keeping that aside, check out my drafted solution case study...
There is already an existing digital pump that works in a way such that the attendant enters the volume value or cash value of fuel to be pumped from a digital numeric pad and completes entry by pressing a button in that pad which raises an event to send instruction of what is to be displayed on the pump screen (lets say INST-D), and another instruction to start pumping (lets call that INST-P) and lets call the process on sending instruction as INST-S.
For INST-P, I want to assume that volume of fuel pumped is determined by time given for pump pressure allowed e.g if at a certain pressure, it takes 2 seconds to pump 1 litre, then pressure time allowed to pump 10 litres will be 20 seconds. I'm not sure of this specification but I believe this INST-P is specific to pump manufacturers. Lets just use my speculation for this case study.
For INST-D, I guess that the voume to be pumped is written on a memory from which it is read for display. And for INST-P, the calculated time value required for pumping is also written to another memory in order to know when to stop pumping.
Now, I want to take advantage of the INST-S, INST-D and INST-P because they are already existing(to aid pump manufacturers) and event driven(to aid my application call) Throughout this study, application calls on any of these 3 instruction calls will raise their corresponding event which also uses their existing corresponding memories; as if it were from the attendant. I ONLY just need the custom pump to be built in such a way to fit the whole solution.
So, if the fuel pump manufacturers COULD build a custom fuel pump having the following extra features...
a) an in-built pump ID which is manufacturer generated and written to device-slot A which is readonly (see sixth feature).
b) an in-built container or vessel(say 23 litres for this case study) that is connected directly to fuel source.
c) a redirected pipe/pump that connects the container to the attendant's output fuel nozzle.
d) a sensor/detector attached to container that determines the volume left in the container; or that gets the current container weight(from which the volume can be calculated). e.g digital/electronic scale or something else suitable for the manufacturer. Let me call that "volume detector"(VOL-DET). This value could be read by the PC via another means but for the purpose of this case study lets assume it should continuously write its value to device-slot C(see sixth feature).
e) 3 pump screen displays-1(top), 2(middle), 3(bottom).
f) a PC-accessible read/write memory device(similar to K74), having full capability of the existing INST-S, INST-D and INST-P, along with 1 readonly memory and 5 read/write memories. This device will be in-built with the pump. Its access mode could be wireless but I prefer it to be serially connected like the K74, wired out via underground and then to the PC, so as to avoid wave obstruction and improve optimization. The memory names and functions are:
slot A = pump ID(which manufacturer generated and readonly).
slot B = litre value to be pumped
slot C = value of VOL-DET
And the whole process action goes like this...
1) after Application(App) startup, designated pump ID modules are opened which does a previous transaction check(not discussed here) and then listens to their respective slot B(continuous reading of slot B).
2)now attendant enters 25 litres for sale and presses button to instruct fuel pump...
--> instead of instructing the fuel pump to pump 25 litres directly, 25 is written to slot B using INST-S. And display-3 is then made to display "SALE IN PROGRESS..." using INST-D.
3)App detects change in slot B, gets value(25), disable entry for another sale and determines phases for the current sale. In this case, it will be 2 phases because of the container size.
4)App uses INST-P to fill container with 20 litres(first destination). And display-2 is made to display "PUMPING 1/2" for example.
5)App now uses INST-P to empty container by pumping from the container to the attendant's output fuel nozzle(second destination). Display-2 is made to display "NOW SELLING..." for example, and display-1 is made to dispaly the litres pumped using INST-D.
6)Once slot C reads value indicating supposed zero value or INST-P finishes(end of step 5), App uses INST-P to fill container with 5 litres while Display-2 is made to display "PUMPING 2/2" afterwhich, step 5 is repeated.
7)Display-3 or both Display-2 and 3 is now made to display "SALE
COMPLETED" for example using the regular INST-D. Other instruction clean-ups for the current transaction will now be performed before enabling entry for the next sale.
Thats it! I know there are observations and questions for this case study. For instance, each sale now takes double the time of regular sale, but that can be relatively beaten by increasing the pressure rate to fill the container as desired by the manufacturer.
Ok, so far, have I been making sense? or what do you think?
|
|
|
|
|
I didn't read much beyond the instructions to start-pumping and end-... *crash*, still pumping
Generally the POS machine would authorise a certain maximum, and send this to the pump (in a prepay scenario). The hardware in the pump will handle limits, and also "nicetys" like "stop pumping when the tank is full" or "the user has pulled the hose out".
To be honest, the command set, and state diagrams for this sort of setup will be quite simple. If you are having trouble getting your head around those, then I definitely wouldnt recommend implementing a control system for volatile fluids until you have accumulated some experience with PLCs, realtime control and fail-safe design. Otherwise I can see huge explosions in your future...
|
|
|
|
|
God Bless u Mark Churchill.
U are damn right and u have just saved someone from a burning station! Thanks a lot and more thanks for the information shared.
Now, to have my major worry settled, I just need to know how to connect to the POS machine in the fuel pump from a C# application and get the litre or cash values so that I can at least, record the sales of fuel for a prepay scenario. I have heard of WEPOS and POS for .NET but I don't know if that will do. I will appreciate any assistance or walk around rendered.
Just to add, secondly(minorly), I've observed something during prepay sale which i want to bring to your notice. While fuel is pumped into the vehicle, if the user holds down the inner holder of the hose nozzle at intervals, the volume of fuel released after pump or sold will be reduced! Suprisingly, I've confirmed this with sale measurements to fuel galloons. Perhaps, nozzle manufacturers might be able to build hose nozzle models that can't interrupt the volume to be dispensed. What do you think?
Anyway, thats by the way, my concern right now is how to solve my major worry as stated above. Many more thanks in advance as I look forward to hearing from soon.
|
|
|
|
|
Hi Guys,
I've been working on a system for a while now, and it initially started off with a handful of functions that could be applied to it. This increased over time to around, and i split them up and put related functions into appropriate classes. These classes are now exhibiting the same problem i had initially with 100 methods in the same class. (Messy and poor cohesion)
* I Have a set of low level classes that expose all the fine grain detail.
* I have a set of high level classes that contain complex functions that manipulate the low level classes.
* The high level functions are largely simple [void Function()]. Some with a few Private utility methods.
* The high level functions generally do not call one another in the same class.
* The high level functions DO call one another in different classes.
* All High level function calls are made through a HUGE case statement atm, that is wrapped in a Logging exception handler.
Many of these functions are invoked from Menu or Hotkeys or other argument free events such as Button press.
I get the impression that this lends itself to a Command Pattern, but while i understand the concept, i can't get my head around how to implement it. (Factory? Pre-loaded Command Dictionary?)
Also, how would i go about implementing a Command Tree? i.e. where one command calls another, and so on and so forth? And would this be a reasonable thing to do?
Any Ideas?
Cheers
Tris
-------------------------------
Carrier Bags - 21st Century Tumbleweed.
modified on Friday, May 16, 2008 11:35 AM
|
|
|
|
|
Tristan Rhodes wrote: Also, how would i go about implementing a Command Tree? i.e. where one command calls another, and so on and so forth? And would this be a reasonable thing to do?
From my memory I think I used Observable Pattern rather than a tree. It is also possible factories were involved.
led mike
|
|
|
|
|
Hi Mike,
Thanks for the reply.
I do have a number of observable components in the application and their events are handled in a centralized controller class. This class then runs the appropriate command / functionality.
(Yes i do have a factory in there as well somewhere, but it's not related to the Command chain )
My concern is what to do to manage this large collection of functions and what options are available. Does the Command Pattern seem to be the way to go with this?
While i am familiar with the pattern, i'm somewhat perplexed as to how to fit it into the application. I'm not interested in commands for the purpose of Undo / Redo which is the only implementation i am familiar with.
Any further advice?
Cheers
Tris
-------------------------------
Carrier Bags - 21st Century Tumbleweed.
|
|
|
|
|
Tristan Rhodes wrote: I'm not interested in commands for the purpose of Undo / Redo which is the only implementation i am familiar with.
Not sure how to help you here. The implementation of a specific command like Undo/Redo have nothing to do with the Command Pattern. Probably the most significant benefit of the pattern is the isolation of the implementation of the commands from the implementation of the invokers. If that would be helpful to your project then you should consider using it, however:
Tristan Rhodes wrote: I do have a number of observable components in the application and their events are handled in a centralized controller class. This class then runs the appropriate command / functionality.
That sounds like you have already centralized the implementation of your commands. Sometime interpreting design from someone else's point of view presented in text messages is not easy.
led mike
|
|
|
|
|
Need a UML comment type.
-------------------------------
Carrier Bags - 21st Century Tumbleweed.
|
|
|
|
|