|
Hi all:
I have inherited a web application that's used for reporting. Each report has three main sections: Input section where the users select dates and other info, Summary screen where a summary of the data is shown, and a Detail screen where detailed data is shown.
I don't think it makes sense to create a new Input, Summary, and Detail page when a user asks for a new report. Too much duplication!
Is there a pattern I can use to simplify this? Let me know if you need more details.
Thanks!
Nick
|
|
|
|
|
First suggestion is, don't be afraid of "duplication". For one, Input, Summary, and Detail views, while they may all work with the same data, have distinct purposes, and will have distinct functionality that drive them. While you could probably merge all that functionality into a single glob, from a maintainability perspective...isolation of purpose (called separation of concerns and single responsibility in architect-speak) can offer you a lot in terms of long-term maintainability.
My recommendation is this. Even if you need the Input, Summary, and Detail views to be represented as a single thing to the user...develop them as individual components that make use of a core, shared set of objects. Input should be a view component that encapsulates the logic required to display a form to the user and process that input. Summary should be a view component that takes the processed input and renders the summary. Detail should be a view component that takes the processed input and renders the full detailed report. Since each one is its own, isolated component, they can be maintained individually. That doesn't preclude them from being rendered into a larger composite view, so you still achieve what you want for the user (a single "page" from which a report can be queries, previewed, and rendered in full detail).
If there is some duplication of code between the three components...that is ok. If you can centralize any common logic into a helper class that can be shared accross all three, great. If the logic is similar, but can't really be normalized, thats ok too. The key thing is that Input, Summary, and Detail are independant components that can be maintained, updated, and modified (i.e. with new functionality) independant of each other, which will improve your long term maintenance and product flexibility. Regardless of up-front costs...long term maintenance is by far the greatest cost of any project.
|
|
|
|
|
Thanks for the response Jon!
|
|
|
|
|
hii all..i got a problem regarding to convert the requested memory address to bus address..as we know, for the CPU to access a memory (doing transaction) it must go to bus address first..txx
|
|
|
|
|
|
Hi,
what is your application, why would you need this? Are you going to write a device driver that services a DMA device? Normally all addresses handled by code running on the CPU will get translated from logical to physical addresses automatically by the built-in MMU; you should not worry unless you dive into the kernel, the drivers and/or your own hardware...
Luc Pattyn [Forum Guidelines] [My Articles]
- 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 the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
|
|
|
|
|
oke,let me explain to you..i need to convert the requested memory addressto bus address.. because for a CPU to do a transaction such as I/O Read, I/o Write ,interrupt and others memory transaction, the CPU need to got through the front-side bus for it to access to requested memory in the DDR or in the Memory Controller Hub (MCH).By the way thanks for your help. i will try my best!
|
|
|
|
|
Hi there,
I am seeking help for building a document-centric application. More specifically, handling extensions and icons for the different file types the application is going to manage. I know how to register extensions within windows, I'm just unsure how to do it inside my own application!
My current design is something like this:
Each document has it own class (the documents are actually just the objects serialized, gzipped and stored on the disk). Those can be extended through a plugin system (with external dlls being loaded during runtime), so the number of file types may be extended at will. Each file type should have its own extension and can have its own icon. I'm using multidotted extensions to keep the naming scheme sane.
To define a new document, thus a new file type, one has to implement a interface, lets say, IDocument, which has common properties like Name, Description and Remarks, and then define what his document will contain.
Now, the problem is: Where should I specify which will be the default extension and icon for a particular document class I'm writing? At first I thought about adding static properties to the interface in order to ensure its implementation, but I know interfaces cant have such things. I also need to be able to, given an extension, return the System.Type of the related document, or given a Type, return its extension. I could write a table of extensions and related types, but then how could I enforce every class that inherits from IDocument will register itself into this table?
It should be mandatory for a document to have a extension, but I can not think of a way to enforce this rule. Sorry for the long question, but I hope I could explain what I'm trying to achieve.
Thanks in advance,
C
|
|
|
|
|
Well, you could always implement an abstract base class that your document classes must inherit from, and put rules inside here to ensure that a document has an extension and icon.
|
|
|
|
|
Hi, thanks for replying.
Its a nice sugestion, but then to retrieve this information I'd have to create an instance of the class, wouldn't I? If I have to look for a particular extension, I'd be instantiating several classes, one for each document, only to check the overriden methods.
If there was a way to enforce a inherited class to have a particular static method, then it would be easy, but there isn't. At least none that I'm aware of.
I think its possible to create a mechanism to register this information in a static structure somewhere based on overriden virtual methods, but I would have to instantiate the class at least once for this.
|
|
|
|
|
There's no easy way to do this internally. You could always store the extension and the type it relates to in a database/config file and then perform the instantiation based on that.
|
|
|
|
|
Where should I specify which will be the default extension and icon for a particular document class I'm writing?
I would consider that these defaults are the defaults of the context or system in which they are used. That is, the default is not of the document, but of the system its saved in. Moving a document from System A to System B may mean a different default icon, so information on defaults does not need to be part of the document.
|
|
|
|
|
Hello Friends,
How to create DFD for my project documents.
My project definition is Inventory System.
Please help me.
Thanks in advance.
Pin
|
|
|
|
|
Member 4679436 wrote: Hello Friends,
Unlikely. I've never met you before.
Member 4679436 wrote: How to create DFD for my project documents.
Any text editor will do - you could always use Notepad.
|
|
|
|
|
Pete O'Hanlon wrote: you could always use Notepad.
Real programmers would use vi
|
|
|
|
|
led mike wrote: Real programmers would use vi
Did he strike you as a real programmer?
|
|
|
|
|
Ohhhh, did I ever walk right into that one!
|
|
|
|
|
I would like to hear comments and suggestions on the proper way to avoid circular references between projects.
Consider an app with the following assemblies:
- UI
- BusinessLogic
- DAL
- Common
So typically, the dependencies would look like this:
UI >> BusinessLogic >> DAL
and all 3 above depend on Common
So far, so good, but... lets say that I have a common collection of data that is required to be used in all 3 of the main assemblies, such as a list of supported cultures.
So I create a static helper class in the Common assembly and this gives me access to the shared singleton collection from all 3 main assemblies.
However, to populate that singleton collection when the app starts, I need to hit the database once. To do this right, I would load the collection from the database using my BusinessLogic layer.
But I cannot do this because doing so would cause a circular reference between Common and BusinessLogic.
What is the best architecture to avoid/work around this problem?
Thanks.
|
|
|
|
|
Leftyfarrell wrote: What is the best architecture to avoid/work around this problem?
Model-View-Controller[^]
led mike
|
|
|
|
|
Thanks for the suggestion. I simplified the example in hopes of not boring readers with details.
Our current architecture currently uses MVP pattern for the UI layer. The presenters make use of a Business Service Client Adapter assembly that provides data from our Business Service layer through WCF.
The heart of my question really has to do with cross cutting concerns like Logging, Exception Handling, Validation, Instrumentation etc. We are implementing the use of MS Application Blocks.
If the cross cutting concerns are encapsulated in accessor classes within the Common assembly. How do you handle cross cutting concerns that require database access?
Should they have their own encapsulated DAL making them like a standalone service?
If they try to use the existing Business Logic layer (and DAL) this will create a circular reference.
A concrete example could be Validation, where the validation error messages must be localized and loaded from a database.
|
|
|
|
|
Extract the API for your cross-cutting concerns from the implementation, say by creating interfaces for the public types. Your API project can be used by your DAL, and anything else, without those other projects needing to have direct references to the implementation project. Just use some kind of IoC and a Factory in your API project to inject the implementations. That will solve the direct dependency cycle...however it will still exist in an indirect fasion.
|
|
|
|
|
Thanks Jon, was hoping to get your opinion.
I considered that, but worried that it wasn't the "best" or "proper" solution, since the circular reference would technically still be there right? It would just be hidden on one side by the interface.
So the Common API would still reference and call the Business Layer for data.
All other assemblies would reference an Common Interfaces project and their Common instance would be provided by Unity.
Something like that? Again, each one still references the other directly or indirectly and that is what I wasn't sure about.
|
|
|
|
|
I see John has already replied. If you look at the patterns you are using you will notice they all use interfaces to avoid the coupling issue you are dealing with, just as John points out. Interfaces eliminate coupling, take a look at the mediator pattern. Organizing libraries / assemblies requires similar structure to avoid dependencies between the modules.
led mike
|
|
|
|
|
led mike wrote: Interfaces eliminate coupling
I just thought I would point out something important. Contrary to common opinions, interfaces do not really "eliminate" coupling. Coupling exists, and its such a thing that can't really be eliminated. It can be mitigated, and interfaces can help mitigate coupling. When we directly create and use a concrete implementation class, we are "tightly coupled" to an implementation (the consumers tightly couple with their provider), because we are bound not only to an API but a specific implementation. Interfaces allow us to reduce the degree of coupling, since when we create an interface, we are "loosely coupled" through the interface to an implementation. So long as the interface doesn't change, we can modify the concrete class, replace it with another, etc. without requiring modification of the code that uses the interface. We can gain the same thing with abstract classes (technically speaking, an abstract class with zero implementation is an interface). But its important to note...you ARE "tightly coupled" to the interface.
Coupling also comes in a variety of forms, and can be encountered at different levels of a project as well. One class can be coupled to another (tightly via direct instantiation, or loosely via interface/abstract). One assembly can be coupled to another assembly. A layer in an architecure is coupled to another layer, as well as to cross-cutting concerns. Services can be coupled to other services. Code can be coupled in time to the running length of other code. Coupling is a very broad issue for software architecture, and new aspects of coupling are always being discovered as we discover new ways to write software and solve other problems.
Key thing though...coupling can never really be eliminated. Your always coupled to something, but what that something is determines whether the coupling is manageable or not. Thats why most (if not all) problems in software architecure can generally be solved by abstracting another degree...separating one thing from another via an API of some kind increases independant variability and reduces coupling.
|
|
|
|
|
Jon Rista wrote: Key thing though...coupling can never really be eliminated.
Yes, bad choice of words "eliminate", loose coupling is the proper description. On this site I have not run into a lot of people that understand terms like that. I guess I have started dumbing down my replies, which is really dangerous since I'm already dumb enough to be dangerous.
led mike
|
|
|
|
|