I've been designing quite a few Windows Forms applications lately (data-entry apps, office integration, etc), and although I've always designed with logical tiers in mind, the "middle tier" business logic layer has always been hosted on the desktop PC (i.e. physical client-server).
As I approach more complex applications, I find myself yearning for a physical middle tier instead, with the desktop client passing requests back to an application server to process business logic (which may change regularly) and interfaces. It feels like I'm missing out on factors such as scalability and maintainability that are more native to Web apps.
I'm curious to know how far other WinForms developers have taken their middle-tier separation:
How much processing (if any) do you perform on a middle-tier server?
What communication method are you using - WCF, remoting, web services, etc?
How much is performance a factor, and how often do you roundtrip to the server?
Is there are a benefit in moving business logic onto a separate tier, or is it more practical to host components locally on a PC (and just make sure you have a good deployment model to push out regular releases as business rules change)?
Alternatively, should I be guiding customers away from WinForms completely if these factors are involved? With alternatives such as Silverlight and even ASP.NET w/ AJAX, the reasons to choose a WinForms client seem to be shrinking.
What is important to keep in mind is that there is a trade-off between the ease of development with a seperate middle tier vs all of the scalability benefits etc. What I mean by this is that you have to refresh interface mappings etc in your code, you have to deploy a middle tier somewhere for your testers to use, which needs to be refreshed etc. Furthermore, if you are lazy like me and pass your Entity Framework objects around directly, you cannot serialise them to a middle tier, so you then need to create DTO's for all of your operations etc.
Some of this overhead can be handled by a decent build system, but that also needs effort to set up and maintain.
My preferred tactic is to keep physical seperation in terms of assemblies (i.e. I have a seperate business logic / data access assembly) and to route all of the calls to the business layer through an interface layer, which is a bunch of Facade classes. So all of these assemblies reside within my windows app. I also create interfaces for all of these facades, and access them through a factory.
That way, should I ever need the separation of a middle tier, and the trade-off in terms of productivity is worth it, I can separate my business layer out, put it behind a WCF service (as that is my preferred service platform) and perform some refactorings in terms of what my facades hand out, and what they do with what they accept.
This is one example of why I tend to always do work in a web environment. If the network is available to your client application for service calls, it's certainly available to send and retrieve data from a web server.
Certainly, client restrictions can alter your final path, but when given the chance to influence the direction, I steer towards web-based solutions. There are deployment technologies available that give you an easier upgrade path than a traditional desktop package, but there's no real substitute for updating a server-based application.
Depending on your application, there are several performance issues to keep in mind.
If your work is very similar between various clients (shared data), then doing the processing on a middle tier is better because you can make use of caching to cut down on the overall processing.
If your is different between clients (private data), then you won't have much gain by doing the processing at a middle tier.
Related
I have a question regarding best practices with containers. Is it an anti-pattern to have a database in a container?
I've seen implementations of DBs in containers a couple times now and I'd love to get y'all's thoughts on it. From my understanding, containers should be lightweight and effectively stateless. They should also operate as cattle, not pets (as in, easily destroyed and you don't rely on one container staying to perform business functions).
From what I know of DBs, they aren't usually cattle, and depending on the application they aren't lightweight. They're also pretty much inherently stateful.
It's pretty clear that I'm skeptical of DBs being hosted in containers, but I'd really love to hear what y'all think. I'm not too familiar with DBA work so hearing from those with more experience (especially if you've implemented it and have experiences you can talk to) would be great.
Its a great question, though its a bit broad. It completely depends on what exactly you are running and how you plan your workloads.
The thing to keep in mind about containers is that there really isnt any magic here. Containers ultimately boil down to kernel level (cgroup) limits imposed on a process and the orchestration layer (eg Kubernetes or CloudFoundry Diego) are responsible to reacting to when the container is killed off for crossing these limits (eg out of memory).
In general, there are a number of high level factors to keep in mind
What are the data durability requirements for this project
What are the workloads (eg hourly spikes, unpredictable load, etc)
What is your uptime SLA and can you clients handle failing over to new masters in your data tier gracefully
Most importantly, is containerization the right pattern for what your project's data tier is trying to achieve.
Beyond this, you have to look at characteristics of your orchestration environment. If you need to be able to persist disk contents, you need to make sure you pick a container orchestrator that is able to fill this requirement.
You may have something like a sharded MongoDB cluster using the In-Memory engine for a caching layer that requires a bit more capability than a typical key value store like memcache (eg ability to query/filter the cache itself). Depending on your project's requirements, it may be perfectly fine to lose this "cache" layer and rebuild it on demand.
In other workloads. You could run something like enterpriseDB ARK to provide clustered, highly available, containerized PostgreSQL deployments on top of Kubernetes. This comes with its own challenges, but it enables you to implement a service broker model in your micro services architecture to deploy and persist the data tier for each of your micro services in a way that mitigates a monolithic data tier which is prone to chatty neighbor problems in this type of architecture.
I am using MVC architecture.My Question what are the advantages and dis advantages in running client and server in different ports or different servers
Your question refers to the separate development of two different aspects of the application and these are: the backend API and the front-end. Its more of an architectural choice
Having APIs built separately from UIs, achieves:
Less coupling. This way one can expand/upgrade/enhance both apps independently and flexibly, that too in different technologies.
Extending the above point, APIs also provide the option of universal connectivity from various consuming clients such as mobile/web/IoT thereby giving the developer greater ingress across the spectrum. This helps in gaining business advantages over the competitors
Complex business processes can also be composed by way of stitching together (orchestrating) atomic API endpoints
Security: Putting everything up into one client facing application, including backend functionality raises obvious security red flags.
Scalability: Both the apps (UI and API) can be scaled independently and elastically depending on their usage
One obvious drawback, if you will, is the "overhead" associated with the separate implementation of both sides and it can be an overkill if the use case is quite simple and the potential consumers of the app's functionality are quite less and its meant to be used/accessed in a secure environment (let's say on the internal network in a given corporate).
Like all design considerations, the above are also circumstantial as there is no one silver bullet but at the very least these are some considerations on which the design of the given app depends on.
HTH
I'm curious how you would handle following Database access.
Let's suggest you have a Computer which Hosts your database as part of his server work and multiple client PC's which has some client-side-software on it that need to get information from this database
AFAIK there are 2 way's to do this
each client-side-software connects directly to the Database
each client-side-software connects to a server-side-software which connects to the Database as some sort of data access layer.
so what i like to know is:
What are the pro and contra's of each solution?
And are other solutions out there which maybe "better" to do this work
I would DEFINITELY go with suggestion number 2. No client application should talk to a datastore without a broker ie:
ClientApp -> WebApi -> DatabaseBroker.class -> MySQL
This is the sound way to do it as you separate concerns and define an organized throughput to the datastore.
Some benefits are:
decouple the client from the database
you can centralize all upgrades, additions and operability in one location (DatabaseBroker.class) for all clients
it's very scaleable
its safe in regards to business logic
Think of it like this with this laymans example:
Marines are not allowed to bring their own weapons to battle (client apps talking directly to DB). instead they checkout the weapon from the armory (API). The armory has control over all weapons, repairs and upgrades (data from database) and determines who gets what.
What you have described sounds like two different kind of multitier architectures.
The first point matches with a two-tier and the second one could be a three-tier.
AFAIK there are 2 way's to do this
You can divide your application in several physical tiers, therefore, you will find more cases suitable to this architecture (n-tier) than the described above.
What are the pro and contra's of each solution?
Usually the motivation for splitting your application in tiers is to achieve some kind of non-functional requirements (maintainability, availability, security, etc.), the problem is that when you add extra tiers you also add complexity,e.g.: your app components need to communicate with each other and this is more difficult when they are distributed among several machines.
And are other solutions out there which maybe "better" to do this work.
I'm not sure what you mean with "work" here, but notice that you don't need to add extra tiers to access a database. If you have a desktop application installed in a few machines a classical client/server (two-tier) model should be enough. However, a web-based application needs an extra tier for interacting with the browser. In this case the database access is not the motivation for adding this extra tier.
Should we use webservices or do direct database access. Ofcourse direct DB access is relatively faster and also with webservices it is good if we have to make for multiple platforms.
is the time significantly high in case of accessing data through a webservice as against a DB call or is it marginally high ?
I would have to disagree with TruthOf42 in that web services are best practices for data access. There is certainly a big shift towards that approach these days, but I don't think common use is the same as best practice. Just because something is common/popular doesn't mean it's the best fit for all situations.
Why use web services?
If you plan on having more than one application use a generic data access layer.
If you plan on exposing your data to external clients.
If you want to draw some hard physical lines between your application and the database.
I would argue making web service calls will always be slower than just writing queries against the database. But you can mitigate the issues with wise network planning and caching.
I agree with Aphelion in that if it's a simple application, then keep it simple.
A good idea would be to make an interface in your code that gets data and you start with a database implementation. If you find you'd like to introduce web services later, then you can keep the same interface and just implement a version that makes web service calls instead of directly dialing the database.
Don't try to optimize something you haven't even written yet. It's best practices to use web services. Doing direct calls to the database just opens you to more security issues.
The most important thing when writing software is writing it well, speed is usually of last concern.
Please I need help.
I have project in which I need application which communicates with local DB server and simultaneously with central remote DB server to complete some task(read stock quotas from local server create order and then write order to central orders DB,...).
So, I don`t know which architecture and technology do this.
Web application, .NET WinForms client applications on each computer, or web services based central application with client applications?
What are general differences between this approaches?
Thanks
If you don't want to expose your database directly to the clients, I'd recommend having a web service layer in between. Depending on the sensitivity of your data and the security level of your network, I'd recommend either a web service approach (where you can manage the encryption of data yourself, and without need for expensive ssl certificates) or a web interface (which might be easier to construct, but with limitations in security).
I agree with Tomas that a web service layer might be good. However, when it comes to choosing between webforms or winforms I don't think your question includes enough information to make the choice.
I'd say that if you want a powerful and feature rich user interface and want to make development easy, Winforms is probably the way to go. But if you need it to be usuable from a varied array of clients and want easier maintenance and deployment, a web app might be best.
First, focus on the exact relationship between these databases. What does "local" mean. Right there on the user's desktop? Shared between all the users in their office? Presumably the local quotes (you do mean stock quotes and not quotas?) could potentiually be a little out of date relative to the central order server's view of the world. Does that matter? I place an order for 100 X at price 78.34, real price may be different. What is the intended behaviour.
My guess is that there is at least some business logic and so we need to decide where that runs. One (thick client) approach is to put that logic on the desktop, the desktop app then might write directly to the central DB. I don't tend to do this for several reasons:
Every client desktop gets a database connection. Scaling is not good, eventually the database gets unhappy when the number of users gets very large.
If we need a slightly different app, perhaps exposed to a different set of users via the Web or whatever, we end up reproducing that business logic.
An alternative approach (thin or browser based) keeps the UI on the desktop, but puts the logic on the server. The client can then invoke some kind of service. Now there's lots of possible ways of doing that, a simple Web Service or Rest Service will do the job. I hope it's clear that this service-based appraoch addressed my two points above.
By symmetry I would treat the local databases in the same way, wrap them in services. However it's possible that some more complex relationship between the databases exists and in which case you might need the local service layer to interact with the central service layer.
I'm touting the general pronciple of Do Not Repeat Yourself, implement each piece of business logic once.