In case you're not sick of hearing about my chat application...
The main part of the application, the piece that does all of the back end work is in the "models" directory. The class is called AEDC_Model_Chat (AEDC is the namespace) but this particular class isn't actually an "object". It is never instantiated, and it only exposes static methods.
So, I am thinking this isn't actually a model, and doesn't really belong in "models".
Any thoughts?
IMO, I think it's fine for static based classes to reside in the /models dir. In working with Propel and Doctrine, they have Peer and Table classes (respectively), that are never meant to be instantiated, instead they are meant to implement business logic upon objects to which they are associated. Example dir listings:
// Propel
/lib/model/mydb
Vehicle.php // Instantiable
VehiclePeer.php // Works with vehicle object(s)
// Doctrine
/lib/model/mydb
Vehicle.php // Instantiable
VehicleTable.php // Works with vehicle object(s)
--Update--
Need to make a correction (doesn't change the answer), with respect to doctrine, the "*Table" classes CAN be instantiated, but they still behave the same as I described above, in that the included methods are meant to work with associated object(s). Your usage of the "static" classes is closer to the way Propel works, and as I mentioned earlier, acceptable to reside in the /model dir.
Related
I am in the process of building a Cocoa app, which is comprised of a window divided in 3 sections. Each section is responsible for its own business and there are around 30 controls in it between table views, pop up buttons etc.
I started with a single Controller but things get messy pretty easily, so I decided to break the logic down in 3 controllers object (one each section of the view). I then created the NSObject reference on Interface Builder and hooked up all the outlets, actions, data sources and delegates. So far so good.
Now, the three sections pass objects to each other and therefore I need a way to set an object from one class to another. The object in question is a class variable, but as I have no reference to the object I don't know how to pass it around.
Is there a way to do this or is this just the wrong approach overall?
Solution:
As Sergio mentioned below in one of the comments, the solution seems to be to create a weak reference to the other controllers inside each controller as IBOutlet and then in the Xcode Interface Builder link the controller objects together. As a result, now each controller can access the exposed methods and variables of the referenced controllers.
Now, the three sections pass objects to each other and therefor I need a way to set an object from one class to another. The object in question is a class variable, but as I have no reference to the object I don't know how to pass it around.
What seems missing in your design is a Model (as in Model-View-Controller). This would be a class encapsulating all the state of your app, even if it is transitory state, so that each affected object have access to it.
One easy implementation for such a model class is a singleton, so that it is readily available in all of your controllers. Have a look here for some thought about the implementation of a singleton in Objective-C.
Once you have your model class, your controllers could access it like this, e.g.:
[MyModel sharedModel].myObject = ...;
This approach is good, IMO, if it makes sense for you to go in the direction of creating a Model for your design. This depends on the semantics of the object that your controllers share. So, there might be alternative solutions better fit for your case. E.g., one controller could be the owner of the shared object, and the other two could receive a reference to the first controller on init so that they can access its public properties.
I'm implementing several classes which does not have data by itself, just logics. These classes implements access control policy to date which depends on several parameters taken from data from other models.
I initially try to find answer to "Where to store such classes?" here, and the answer was apps/models directory. That's ok, but I like to clearly separate these classes from ActiveRecord inherited classes in hierarchy, both as file and class.
So, I created classes inside Logic module, like Logic::EvaluationLogic or Logic::PhaseLogic. I also wanted to have constants which passed between these logics. I prefer to place these constants into Logic module too. Thus, I implemented like this:
# in logic/phase_logic.rb
module Logic
PHASE_INITIAL = 0
PHASE_MIDDLE = 1000
class PhaseLogic
def self.some_phase_control_code
end
end
end
# in logic/evaluation_logic.rb
module Logic
class EvaluationLogic
def self.some_other_code
Logic::PhaseLogic.self.some_phase_control_code(Logic::PHASE_INITIAL)
end
end
end
Now, it work just fine with rspec (It passes tests I wrote without issues), but not with development server, since it can't find the Logic::PHASE_INITIAL constant.
I suspect it's related to the mismatch of the autoloading scheme of Rails and what I wanted to do. I tried to tweak rails, but no luck, ended-up with eliminating module Logic wrap.
Now the question I want to ask: How I can organize these classes with Rails?
I'm using 3.2.1 at this moment.
Posted a follow-up question "How I can organize namespace of classes in app/modules with rails?"
I am not sure whether I really understand your classes, but couldn't you create a Logic module or (I would rather do this:) PhaseLogic and EvaluationLogic objects in /lib directory?
It is not said that "Model" is always descendant of ActiveRecord. If the object belongs to "business logic" then it is a model. You can have models which do not touch database in any way. So, if your classes are "business objects", place them in 'app/models' and use like any other model.
Another question is whether you should use inheritance or modules - but I would rather think about including a module in PhaseLogic, and not about defining PhaseLogic in a module. Of course, all this depends heavily on the intended role of your objects.
Because in Ruby the class of object is not important, you do not need to use inheritance. If you want to 'plug' the logic objects into other objects, just take care that all '*Logic' classes have the required methods. I know that all I said is very vague, but I think I cannot give you some more concrete suggestions without knowing more about the role of these objects.
Ah, and one more thing!
If you find yourself fighting with Rails class autoloading, just use the old require "lib/logic.rb" in all the classes where you are using Logic::PHASE_INITIAL constants.
In this case I suppose that your problem was caused by different order of loading. The logic/evaluation_logic.rb has been loaded before logic/phase_logic.rb. The problem may disappear if you create logic.rb somewhere, where class autoloading can find it, and define these constants in that file.
Don't name your classes or modules Logic use specific names. Start with extracting logic into separate classes and then try to break them into smaller ones. Use namespaces to distinguish them from each other in lib folder, after this steps you would be able to extract some logic parts to separate gems and reduce codebase and complexity of application. Also take a look into presenter pattern.
I have an MVC3 project that uses Unity for dependency injection.
There is a main MVC3 project, a “domain” class library that sits between MVC3 and the data tier, and a bunch of class libraries that make up the data tier.
(MVC3) – (domain) – (data tier)
This is an example of one of the service constructors in the domain class:
public DomainModelCacheServices(
Data.Interface.ICountryRepository countryRepository,
Data.Interface.ILanguageRepository languageRepository,
Data.Interface.ISocialNetRepository socialNetRepository
)
Every time a controller is called that has DomainModelCacheServices in its constructor, a new DomainModelCacheServices object is constructed, plus the three repository classes in the constructor of DomainModelCacheServices.
I cannot believe this is efficient!
What makes this worse is that the class DomainModelCacheServices is a cache class. It loads lists of data that never change, and holds them as statics. But it still needs to construct three repository classes for every reference!
If I give DomainModelCacheServices the lifetime of a singleton (forever), I have to ensure it is thread-safe, and if the day comes when I am getting hundreds of hits, there’s going to be a lot of locking.
I could change the constructor to this:
public DomainModelCacheServices(
IServiceLocator serviceLocator
)
I don’t know why, but this doesn’t look right. The constructor becomes meaningless to the eye, and I have to reference Unity in the domain class and somehow make the domain class aware of the ServiceLocator owned by the MVC3 application. Maybe the loose-coupling can be too loose?
Maybe constructing all these classes is not as inefficient as it looks I shouldn’t worry about it?
What would be nice is if Unity supported “Lazy” constructor parameters. But it doesn’t.
So, any ideas on how to make an MVC3 + Unity project more efficient, specifically in the domain model design?
Thanks for reading!
The cache shouldn't be definied on the domain level but on the repositories implemntation level (so in DAL). So for example ICountryRepository should have two implementations in DAL : CountryRepository and ChachedCountryRepository. These should be wired as decorators in Unity (CountryRepository is inside the ChachedCountryRepository). CachedCountryRepository would check if the data is in the cache and if not it would pass the call to the inner CountryRepository.
Creating objects is not expensive and wouldn't care too much about issues as a caching is correctly definied.
Great reasoning.
However, creating objects is cheap. I would not create a singleton since you already are caching all objects in static fields. The current approach is easy to understand.
I got another question for you:
Why are you not caching in your repository classes?
The repositories are responsible for the data and all data handling should be transparent to everything else. It also makes everything easier since they are responsible of updating the data sources. How do you keep the cache in sync with changes today? Through domain events?
I would create a cache class which I would use as a private field in the repository.
Could somebody explain is it possible to have potected, pivate methods in playfamewok's contolles except:
public static void method-action-name() {}
For example if I would have method like this:
protected static int doSomeWork() {}
and this method would be invoked in method-action-name() ..
public static void method-action-name() {
...
int resul = doSomeWork();
...
}
I do not want to have long action-method, so I would like to split it to smaller ones, and then reuse it in other action-methods.
I mean is it ok (from playframework's point of view) to have such method in controller side instead of having them in domain classes? In Spring Framework, we use BP (business process) beans for that, for example.
Is it ok to have such helper methods for business methods in playframework controllers ?
Added after having answer & comments:
For example if I have SearchController class then for that class would be nice to have methods like preSearch1(), preSearch2() what search() method would use, but if I move these methods (1,2) to another class then it should be class with name like SearchHelper then? in package named /src/helpers.. not very nice because they related to search too. But maybe then into /src/bp/SearchBP (bp=business-process). And then in controllers/Search i use /bp/SearchBP that use some Model object with .save() DAO methods (SearchBP can use Domain methods and Search class can use Domain methods as well)
The question here: what class ant package would be nice for those methods? (i just did watch it in examples - there alway very simple usage of controllers that use domain object that why i ask)
yes, you can. Controllers are normal classes, you can add whatever you want. It may not be recommended to clutter them with helper methods, I personally would move them to another class, but you can do what you say.
ANSWER TO EDIT:
The name of the package is "irrelevant", won't change it too much :). You can put them under controllers.support.search which would mean controllers.support is a package with helper classes and the subpackage search contains helper classes and methods related to search.
One alternative (which I like more) is to create a Service layer for that, in a "services" package. You seem to come from a Spring background, so it should come naturally to you. These services are instantiated in the controller as required, or maybe just used via static methods, and do the main business logic. That way the controller only tackles the "higher level" logic.
Another alternative is to move as much of that logic as possible into the Model (avoidid the Anemic Domain Model), and using the Model classes from the controller.
As most decisions in development, which one is better depends on your experience, possible impact/limitations in the codebase, practices in your project... anyway, you can always refactor. Just choose the one that you are more used to (it seems to be Services approach) and code away :)
Any behaviour that's complicated enough to be described as "business logic" (rather than "presentation logic") belongs in the model, not the controller. If your model does nothing but map to/from a set of database tables, then it isn't doing its job properly. Things like permissions and access control, in particular, should be enforced by the model.
I have two classes that each need an instance of each other to function. Ordinarily if an object needs another object to run, I like to pass it in the constructor. But I can't do that in this case, because one object has to be instantiated before the other, and so therefore the second object does not exist to be passed to the first object's constructor.
I can resolve this by passing the first object to the second object's constructor, then calling a setter on the first object to pass the second object to it, but that seems a little clunky, and I'm wondering if there's a better way:
backend = new Backend();
panel = new Panel(backend);
backend.setPanel();
I've never put any study into MVC; I suppose I'm dealing with a model here (the Backend), and a view or a controller (the Panel). Any insights here I can gain from MVC?
It's time to take a look at MVC. :-) When you have a model-view-controller situation, the consensus is that the model shouldn't be aware of the view-controller (MVC often plays out as M-VC), but the view is invariably aware of the model.
If the model needs to tell the view something, it does so by notifying its listeners, of which it may have multiples. Your view should be one of them.
In a circular construction scenario I'd use a factory class/factory method. I would normally make the construction logic private to the factory (using friend construct, package level protection or similar), to en sure that no-one could construct instances without using the factory.
The use of setter/constructor is really a part of the contract between the two classes and the factory, so I'd just use whichever's convenient.
As has been pointed out, you really should try to find a non-circular solution.
First of all, contrary to what others has said here, there's no inherent problem with circular references. For example, an Order object would be expected to have a reference to the Customer object of the person who placed the Order. Similarly, it would be natural for the Customer object to have a list of Orders he has placed.
In a refernce-based language (like Java or C#) there's no problem, at all. In a value-based language (like C++), you have to take care in designing them.
That said, you design of:
backend = new Backend();
panel = new Panel(backend);
backend.setPanel(panel);
It pretty much the only way to do it.
It's better to avoid circular references. I would personally try to rethink my objects.
panel = new Panel(backend);
You do this in this routine something like
Public Sub Panel(ByVal BackEnd as BackEnd)
Me.MyBackEnd = BackEnd
BackEnd.MyPanel = Me
End Sub
You don't need BackEnd.SetPanel
It is better to use Proxies. A proxy links one object to another through raising a Event. The parent hands the child a proxy. When the child needs the parent it calls a GetRef method on the proxy. The proxy then raises a event which the parent uses to return itself to the proxy which then hands it to the child.
The use of the Event/Delegate mechanism avoids any circular reference problems.
So you have (assuming that the backend is the 'parent' here)
Public Sub Panel(ByVal BackEnd as BackEnd)
Me.MyBackEnd = BackEnd.Proxy
BackEnd.MyPanel = Me
End Sub
Public Property MyBackEnd() as BackEnd
Set (ByVal Value as BackEnd)
priBackEndProxy = BackEnd.Proxy
End Set
Get
Return priBackEndProxy.GetRef
End Get
End Property
Here is a fuller discussion on the problem of circular references. Although it is focused on fixing it in Visual Basic 6.0.
Dynamic Memory Allocation
Also another solution is aggregating Panel and BackEnd into another object. This is common if both elements are UI Controls and need to behave in a coordinated manner.
Finally as far as MVC goes I recommend using a a Model View Presenter approach instead.
Basically you have your Form Implement a IPanelForm interface. It registers itself with a class called Panel which does all the UI logic. BackEnd should have events that Panel can hook into for when the model changes. Panel handles the event and updates the form through the IPanelForm interface.
User clicks a button
The form passes to Panel that the user clicked a button
Panel handles the button and retrieves the data from the backend
Panel formats the data.
Panel uses IPanelForm Interface to show the data on the Form.
I've been delaying implementing the lessons learned here, giving me plenty of time to think about the exact right way to do it. As other people said, having a clear separation where the backend objects have listeners for when their properties change is definitely the way to go. Not only will it resolve the specific issue I was asking about in this question, it is going to make a lot of other bad design smells in this code look better. There are actually a lot of different Backend classes (going by the generic class names I used in my example), each with their own corresponding Panel class. And there's even a couple of places where some things can be moved around to separate other pairs of classes into Backend/Panel pairs following the same pattern and reducing a lot of passing junk around as parameters.
The rest of this answer is going to get language specific, as I am using Java.
I've not worried a whole lot about "JavaBeans," but I have found that following basic JavaBean conventions has been very helpful for me in the past: basically, using standard getters and setters for properties. Turns out there's a JavaBean convention I was unaware of which is really going to help here: bound properties. Bound properties are properties available through standard getters and setters which fire PropertyChangeEvents when they change. [I don't know for sure, but the JavaBeans standard may specify that all properties are supposed to be "bound properties." Not relevant to me, at this point. Be aware also that "standard" getters and setters can be very non-standard through the use of BeanInfo classes to define a JavaBean's exact interface, but I never use that, either.] (The main other JavaBean convention that I choose to follow or not as appropriate in each situation is a no-argument constructor; I'm already following it in this project because each of these Backend objects has to be serializable.)
I've found this blog entry, which was very helpful in cluing me into the bound properties/PropertyChangeEvents issue and helping me construct a plan for how I'm going to rework this code.
Right now all of my backend objects inherit from a common class called Model, which provides a couple of things every backend in this system needs including serialization support. I'm going to create an additional class JavaBean as a superclass of Model which will provide the PropertyChangeEvent support that I need, inherited by every Model. I'll update the setters in each Model to fire a PropertyChangeEvent when called. I may also have JavaBean inherited by a couple of classes which aren't technically Models in the same sense as these but which could also benefit from having other classes registered as listeners for them. The JavaBean class may not fully implement the JavaBean spec; as I've said, there are several details I don't care about. But it's good enough for this project. It sounds like I could get all this by inheriting from java.awt.Component, but these aren't components in any sense that I can justify, so I don't want to do that. (I also don't know what overhead it might entail.)
Once every Model is a JavaBean, complete with PropertyChangeEvent support, I'll do a lot of code cleanup: Models that are currently keeping references to Panels will be updated and the Panels will register themselves as listeners. So much cleaner! The Model won't have to know (and shouldn't have known in the first place) what methods the Panel should call on itself when the property updates.