Is model injection on the fly possible? In other words, if I ask for a model of the type IPhotoModel, I should get one of its implementations based on the current state of the view. If I am looking at a UserPage, I should get a user-specific implementation of that model. If I am looking at a LocationPage, I should get a location-specific implementation.
Currently, the only way that I see is introducing a command that specifies the model mapping, with a concrete one based on the current view state ...
something like...
injector.mapValue(IPhotoViewModel, injector.getInstance(UserPhotoViewModel)) or
injector.mapValue(IPhotoViewModel, injector.getInstance(LocationPhotoViewModel))
is this the best way possible? I do not really want to introduce much coupling logic outside of the context, but ...
That's how I do it, and I believe that this is the recommended way. In fact, I think that many advanced RobotLegs users will break out most of the mappings into Commands for convenience, reuse, and to make it easier to read the program--even if the Command is only run once at startup. I've used it for things like swapping out mock services for real services--the Command that maps the dependencies is different, but everything else is the same.
I don't see this as "that much" coupling logic. The Command is merely setting up the program based on current Application state. There's not really that much difference between using a Command to change Injector state vs your own custom Model state.
You may even find that you can reuse your injection mapping Commands across Applications, whereas you might not be able to reuse the entire Context.
HTH;
Amy
Related
I'm looking for suggestions regarding implementing process flow / work flow management in a PureMVC based application.
Our Flex application includes a number of processes such as account creation, payment processing, etc.
Within our team, there is some discussion of how rigidly we should adhere to the PureMVC model.
Within the PureMVC model, it seems reasonable that the current state in the process could be managed in a Proxy.
Commands are clearly responsible for processing the actions required of each node and for node transitions.
Mediators for managing the UI.
However, I think that there is an important bit still missing here: a ProcessController.
The approaches we've reviewed all seem to either violate the PureMVC model (even just slightly) or make unreadable code.
A proxy would maintain the state of the process. As such, it seems to be an appropriate way to implement the controller. However, this is putting a lot of business logic into the proxy.
The Mediator space makes more sense, but the controller in that space would not necessarily directly interact with any particular UI element but would instead coordinate/delegate to dedicated Mediators.
Yet another model would have us put process transition information into Commands. While this seems to be the best place for that work (given the role of commands relative to proxies and mediators), this approach looks to make some particularly heinous looking code with process transition logic distributed among scores of commands.
So how have others handled this problem?
Thank
Curtis
This is exactly the problem that PureMVC StateMachine Utility (and Finite State Machines in general) are meant to solve.
In a simple XML format, you can define states, valid transitions to other states, and the actions that trigger those transitions.
It is all notification-based, so you send StateMachine.ACTION notifications that cause the StateMachine to execute any entering/exiting guard logic that may be necessary (e.g., only allow exiting the FORM_ENTRY state if all the data valid, or only allow entry into the FORM_PROCESSING state if the user has admin rights, etc.). If a state change occurs, notifications are sent that can be used to organize the view or execute logic upon entering the new state.
Here is a StateMachine Overview presentation that will give you a better idea
http://puremvc.tv/#P003/
I think your idea of 'ProcessController' is probably the better way of doing it. Personally, I'm not a fan of PureMVC and don't use it because it doesn't allow enough flexibility or extension points to help with such problems.
Frankly, it's hard to advise on your issue because I don't know exactly what you're trying to accomplish. I do agree that the concern needs to be handled by one object. If you can, try to create a model that can store the data for the process and have another class just manage it throughout. Not sure if that makes sense, but then again, your problem isn't very clear either.
As an added extra, I would look into Dependency Injection. I'm trying to remember if PureMVC does it (I don't think it does), but with DI it would of been a fairly simple problem to solve. Frameworks like Parsley and Robotlegs are really good at that.
In pureMVC the State Machine Utility is probably the best choice for a process controller - and btw, according to the Implementation Idioms & best Practices doc. for PureMVC, it's perfectly fine to have mediators that don't manage a visible component
I have a view, which wants to consume information from a presentation model. This model contains among other things, a collection of ActiveRecord objects.
I would like to not expose the entire collection to the models consumers, but instead wish to only expose the 'data' part.
I expect that I can write a method to create a data-only copy of this complex object, but I'll be honest, I don't really want to.
Is it a terrible idea for me to just expose the entire collection object (yeah, along with all its extra methods and properties...and potential for badness)?
Or, maybe, there's a better approach to dealing with this kind of scenario? I'm sure I'm not the first guy to run into this.
--Brian
I do not think exposing control calls to a view is always bad. Here is sounds like it would be a simpler solution to do so than creating the data proxies (data proxies can have errors, get out of date, and create code duplication).
I am working on maintaining an ASP.NET website, and I've noticed the business layer and other supporting libraries make heavy use of HttpContext.Current.Session. This makes it hard to keep track of session variables, to determine what they're used for and why they even exist.
Is it considered bad practice to use the session in the business layer? And would it be wise to start moving all code that uses the session into the code-behind?
It's almost never a good idea. There's lots of reasons, but here's a couple:
you'll never be able to use business layer code in anything other than ASP.NET
Unit Testing becomes much more of a pain or even impossible.
We ran into huge headaches with this exact same situation when we started to build services that utilized common business layer code.
I follow this rule - any class in System.Web namespace (javax.servlet package in Java) should not be present in your business layer.
Yes - the BL should not have any knowledge about the Session. Its a dependency that you don't need.
make a class that is an indirection, in which case on the web it may return values from HttpContext.Current.Session, and in other areas would resolve that from somewhere else. IE have an interface ISessionStore and have concrete classes WebSessionStore and WindowsFormsSessionStore, etc.
this will make your code easier to test and also gives you expansion paths when say, you now want x business logic to run in a windows service where it can run x piece of code every y minutes.
In my opinion it is bad practice.
It makes it pretty hard to dissociate that business layer from the environment. If you expect to unit test the thing for example, you're out of luck.
One way to take care of that simply would be to insulate this into an abstraction for now, so that you can pass a "state cache" around and not refer to HttpContext. That will take you at least to some degree of abstraction.
Another more interesting question is, why does the business layer need to refer to that?
its always better to have a centralized Cache/Session manager which encapsulates the complete interaction with session/cache or whatever persistence method you use. having your BL to interact with sessions is definitely a very bad practice and in a way defeats the purpose of the tiered architecture altogether.
I am working on some code coverage for my applications. Now, I know that code coverage is an activity linked to the type of tests that you create and the language for which you wish to do the code coverage.
My question is: Is there any possible way to do some generic code coverage? Like in, can we have a set of features/test cases, which can be run (along with a lot more specific tests for the application under test) to get the code coverage for say 10% or more of the code?
More like, if I wish to build a framework for code coverage, what is the best possible way to go about making a generic one? Is it possible to have some functionality automated or generalized?
I'm not sure that generic coverage tools are the holy grail, for a couple of reasons:
Coverage is not a goal, it's an instrument. It tells you which parts of the code are not entirely hit by a test. It does not say anything about how good the tests are.
Generated tests can not guess the semantics of your code. Frameworks that generate tests for you only can deduct meaning from reading your code, which in essence could be wrong, because the whole point of unittesting is to see if the code actually behaves like you intended it too.
Because the automated framework will generate artificial coverage, you can never tell wether a piece of code is tested with a proper unittest, or superficially tested by a framework. I'd rather have untested code show up as uncovered, so I fix that.
What you could do (and I've done ;-) ) is write a generic test for testing Java beans. By reflection, you can test a Java bean against the Sun spec of a Java bean. Assert that equals and hashcode are both implemented (or neither of them), see that the getter actually returns the value you pushed in with the setter, check wether all properties have getters and setters.
You can do the same basic trick for anything that implements "comparable" for instance.
It's easy to do, easy to maintain and forces you to have clean beans. As for the rest of the unittests, I try to focus on getting important parts tested first and thouroughly.
Coverage can give a false sense of security. Common sense can not be automated.
This is usually achieved by combining static code analysis (Coverity, Klockwork or their free analogs) with dynamic analysis by running a tests against instrumented application (profiler + memory checker). Unfortunately, this is hard to automate test algorythms, most tools are kind of "recorders" able to record traffic/keys/signals - depending on domain and replay them (with minimal changes/substitutions like session ID/user/etc)
What are the downsides to using static methods in a web site business layer versus instantiating a class and then calling a method on the class? What are the performance hits either way?
The performance differences will be negligible.
The downside of using a static method is that it becomes less testable. When dependencies are expressed in static method calls, you can't replace those dependencies with mocks/stubs. If all dependencies are expressed as interfaces, where the implementation is passed into the component, then you can use a mock/stub version of the component for unit tests, and then the real implementation (possibly hooked up with an IoC container) for the real deployment.
Jon Skeet is right--the performance difference would be insignificant...
Having said that, if you are building an enterprise application, I would suggest using the traditional tiered approach espoused by Microsoft and a number of other software companies. Let me briefly explain:
I'm going to use ASP.NET because I'm most familiar with it, but this should easily translate into any other technology you may be using.
The presentation layer of your application would be comprised of ASP.NET aspx pages for display and ASP.NET code-behinds for "process control." This is a fancy way of talking about what happens when I click submit. Do I go to another page? Is there validation? Do I need to save information to the database? Where do I go after that?
The process control is the liaison between the presentation layer and the business layer. This layer is broken up into two pieces (and this is where your question comes in). The most flexible way of building this layer is to have a set of business logic classes (e.g., PaymentProcessing, CustomerManagement, etc.) that have methods like ProcessPayment, DeleteCustomer, CreateAccount, etc. These would be static methods.
When the above methods get called from the process control layer, they would handle all the instantiation of business objects (e.g., Customer, Invoice, Payment, etc.) and apply the appropriate business rules.
Your business objects are what would handle all the database interaction with your data layer. That is, they know how to save the data they contain...this is similar to the MVC pattern.
So--what's the benefit of this? Well, you still get testability at multiple levels. You can test your UI, you can test the business process (by calling the business logic classes with the appropriate data), and you can test the business objects (by manually instantiating them and testing their methods. You also know that if your data model or objects change, your UI won't be impacted, and only your business logic classes will have to change. Also, if the business logic changes, you can change those classes without impacting the objects.
Hope this helps a bit.
Performance wise, using static methods avoids the overhead of object creation/destruction. This is usually non significant.
They should be used only where the action the method takes is not related to state, for instance, for factory methods. It'd make no sense to create an object instance just to instantiate another object instance :-)
String.Format(), the TryParse() and Parse() methods are all good examples of when a static method makes sense. They perform always the same thing, do not need state and are fairly common so instancing makes less sense.
On the other hand, using them when it does not make sense (for example, having to pass all the state into the method, say, with 10 arguments), makes everything more complicated, less maintainable, less readable and less testable as Jon says. I think it's not relevant if this is about business layer or anywhere else in the code, only use them sparingly and when the situation justifies them.
If the method uses static data, this will actually be shared amongst all users of your web application.
Code-only, no real problems beyond the usual issues with static methods in all systems.
Testability: static dependencies are less testable
Threading: you can have concurrency problems
Design: static variables are like global variables