Could someone share the way how this should be designed:
Let's say I have some data model, which is built using Entries.
Basically, I have one abstract class Entry (or interface IEntry - that's not so important for the case) and have several implementations of this class - MovieEntry, SoundEntry, FoodEntry, whatever...
Each of those is a wrapper for some data (url, description, number of calories, etc) and this data is grouped together in each corresponding class.
Now - if I wish to display the data for the entries on the screen (let's say movie posters and annotations for the MovieEntry) - how should I design that?
Obviously I could provide another interface / abstract class and call it DrawableEntry (and it would inherit Sprite) and then build a bunch of classes like DrawableMovieEntry and DrawableSoundEntry which could look like:
class DrawableMovieEntry extends DrawableEntry { // which also extends 'Sprite'
private movieEntry:MovieEntry;
public override function draw(backend:*) {
// Draw everything using the 'movieEntry' reference
// stored.
};
But this seems to be kind of an overkill for a small application.
Another approach is to make the MovieEntry, SoundEntry, ... extend sprite and provide the drawing implementations themselves - but this is obviously bad, because data becomes strongly coupled with it's visualization routines.
So - how should this be done? Maybe MVC approach has something to offer for this case?
Your use case seems to be the perfect example for the Strategy pattern or the Command pattern.
Strategy being the simpler one, here is an example:
Create an IDrawStrategy interface like this:
package {
public interface IDrawStrategy {
function draw( obj:Object ) : void;
}
}
Implement several DrawStrategies:
package {
public class SoundEntryDrawStrategy implements IDrawStrategy {
public function draw (obj:Object) : void {
// cast obj to SoundEntry and do all the drawing necessary,
// or fail if obj is null or not a SoundEntry
}
}
}
package {
public class MovieEntryDrawStrategy implements IDrawStrategy {
public function draw (obj:Object) : void {
// cast obj to MovieEntry and do all the drawing necessary
// or fail if obj is null or not a MovieEntry
}
}
}
etc.
Then add a new member to your base Entry class:
private var _drawStrategy:IDrawStrategy;
and create a setter:
public function set drawStrategy ( strat:IDrawStrategy ) : void {
_drawStrategy = strat;
}
and a draw method:
public function draw () : void {
_drawStrategy.draw( this );
}
You can now assign and execute the fitting strategies to each of your entries:
var mov:MovieEntry = new MovieEntry();
mov.drawStrategy = new MovieEntryDrawStrategy();
mov.draw();
BTW the Sprite you draw the information in can, but doesn't have to, be a member of the DrawStrategy class, but if you wanted to add a clear() method later, it would be better to keep a reference ;).
The entries you build your data model with are, among others, referred to as value objects (VO) or data value objects (DVO). To answer your last question first, I'd never have a VO extend something other than a base VO class, so don't extend Sprite, you'll regret it later.
Over to the hierarchy. You're extending the abstract class Entry to create concrete subclasses, but since you also mention a possible interface, I'm not sure you should use extend. Only use a common base class if your value objects actually share common properties. If every entry has a title property, fine, put that one in Entry and subclass it. If your abstract would be empty, I'd recommend using a marker (=empty) interface instead.
I have a common marker interface for value objects, that have more specific subinterfaces to add features like xml parsing or composition. Once you start using interfaces for this, it's easy to enhance.
Then the displaying. There's not one right answer to this one, the more because your example is still pretty broad. But I'd pass the VO to the object as a whole, through a method that states that it's going to store the VO and redraw itself.
interface IEntryDisplay {
redrawWithEntry(entry:IEntry):void;
}
Use the IEntry interface to pass the object as a whole. In your implementation, use an if cascade with is Type conditions to do the drawing.
public function redrawWithEntry(entry:IEntry):void {
this.entry = entry;
if (entry is MovieEntry) {
title.text = MovieEntry(entry).title;
} else if (entry is SoundEntry) {
title.text = "(Sound) "+SoundEntry(entry).fileName;
}
}
If you decide to use a base class for the Entry hierarchy, use that one instead of the interface. You want your methods asking for the value object type that is as close to the needed object as neccessary.
Because you store the entry in your display class, it's easy to pass along some time later when you click the display or when you want to have it do something else.
Does this help?
Related
I would like to represent a kind of class table (CT) as a singleton in Rascal, so that some transformations might refer to the same CT. Since not all transformations need to refer to the CT (and I prefer not to change the signature of the existing transformations), I was wondering if it is possible to implement a kind of singleton object in Rascal.
Is there any recommendation for representing this kind of situation?
Edited: found a solution, though still not sure if this is the idiomatic Rascal approach.
module lang::java::analysis::ClassTable
import Map;
import lang::java::m3::M3Util;
// the class table considered in the source
// code analysis and transformations.
map[str, str] classTable = ();
/**
* Load a class table from a list of JAR files.
* It uses a simple cache mechanism to avoid loading the
* class table each time it is necessary.
*/
map[str, str] loadClassTable(list[loc] jars) {
if(size(classTable) == 0) {
classTable = classesHierarchy(jars);
}
return classTable;
}
Two answers to the question: "what to do if you want to share data acros functions and modules, but not pass the data around as an additional parameter, or as an additional return value?":
a public global variable can hold a reference to a shared data-object like so: public int myGlobalInt = 666; This works for all kinds of (complex) data, including class tables. Use this only if you need shared state of the public variable.
a #memo function is a way to provide fast access to shared data in case you need to share data which will not be modified (i.e. you do not need shared state): #memo int mySharedDataProvider(MyType myArgs) = hardToGetData();. The function's behavior must not have side-effects, i.e. be "functional", and then it will never recompute the return value for earlier provided arguments (instead it will use an internal table to cache previous results).
I wanted to write a simple behavior in Dart to be used by a custom element.
#behavior
abstract class AlignmentBehavior implements PolymerBase {
#Property()
bool alignTop = false;
// more properties ...
ready() {
updateAlignment();
}
#reflectable
updateAlignment([_,__]) {
// reference to the element the Behavior is attached to.
// 1) Is that the correct way?
var ele = Polymer.dom(root);
// We need to inherit from PolymerBase to access set(...)
// 2) Is that the correct way?
set('alignTop', aTop);
// .. to more stuff
}
}
My first two questions are already written in the code. How do I access the element the behavior is attached to? What's the proper way of doing this? I currently use Polymer.dom(root) but I don't know if that even works since I have some runtime errors which I am going to explain later in this post. What is the official way of accessing the underlying element? Is it using the JsObject? Is it calling a Behavior function from the parent PolymerElement and pass this, or should you not access it at all?
Another question is whether I have to inherit from PolymerBase or not. The Behavior example at the Github wiki doesn't do so, but in order to access methods such as set to modify a #Property I have to inherit from it. What's the proper way of doing so?
My last two questions are about errors I get. One error asks me to implement getters and setters for my properties, such as adding a getter and setter for alignTop.
And last but not least, I cannot invoke updateAlignment() from my custom element. It says Class 'MainApp' has no instance method 'updateAlignment'.
1)
var ele = Polymer.dom(root);
If you want to access the DOM of the element, this fine.
Just root gives you the same AFAIK.
If you want to access the elements class instance, there is nothing to do. It's this but that is implicit in Dart anyway.
You can only access what is known in the mixin. To make "things" known to the mixin you can create an interface class.
abstract class MyComponentInterface {
void someFunction();
int someField;
String get someValue;
set someValue(String value);
...
}
Then implement the interface in the mixin and the element class and you have a shared contract.
abstract class AlignmentBehavior implements MyComponentInterface, PolymerBase {
The mixin can now access the members because the implementsMyComponentInterface` claims they will exist and
class MyComponent extends PolymerElement with AlignmentBehavior {
will force you to implement it to fulfill the contract of the mixin.
2) looks fine
3)
Another question is whether I have to inherit from PolymerBase or not.
Is basically the same as 1) Any Polymer element in Dart has to extend PolymerBase. To be able to access the members of PolymerBase from within the mixin it has to implement it as well. This doesn't result in any limitations because the classes that the mixin will be applied to, will fulfill that contract anyway.
If you don't need to access any members provided by PolymerBase there is no need to implement it.
I'm trying to get my head around DI. Am I doing it correctly for classes that follow DI pattern?
class Boo
{
public $title = 'Mr';
public $name = 'John';
protected $deps;
public function __construct($deps)
{
$this->deps = $deps;
}
public function methodBoo()
{
return 'Boo method '.$this->deps;
}
}
class Foo
{
private $objects;
public function __construct()
{
}
// Set the inaccessible property magically.
public function __set($name, $value)
{
$this->$name = $value;
}
// Set the inaccessible $class magically.
public function __get($class)
{
if(isset($this->objects[$class]))
{
return $this->objects[$class];
}
return $this->objects[$class] = new $class($this->deps);
}
public function methodFoo()
{
return $this->Boo->methodBoo();
}
}
$Foo = new Foo();
$Foo->deps = 'says hello';
var_dump($Foo->methodFoo());
result,
string 'Boo method says hello' (length=21)
I don't want to use construction injection in some cases because not all methods in Foo rely on the same injections. For instance,methodFoo()in Foo relies on Boo only, while other methods rely on other classes/ injections.
Also, I don't want to use setter injection either because I might have to write lots of them in Foo, like
setBoo() {}
setToo() {}
setLoo() {}
... and so on...
So I thought using the magic method __get and __set could save me from ending up writing a long list of them. With this, I only 'inject' the dependency when it is needed by a method in Foo.
Is this correct way of doing it? I haven't done any test with an unit test before. Can this solution be tested?
Or any better solutions you have got?
Don't Use Magic Methods If Possible...
Don't use magic methods if possible as it can make it very difficult for yourself or anyone else to come back at a later date and understand where and how certain objects were injected (even when using a good IDE). These __set and __get magic methods are not a long term solution to your problem and will only add confusion in the long run.
As you already know you can use 'constructor' injection for setting properties and injecting objects that are 'required' during instantiation of your object.
Alternatively, if you have dependencies that are 'optional' then use setter / getter methods. That way you 'know' what objects your class uses to perform it's function.
If your class needs say 5 or more dependencies (required or optional) than perhaps your class is try to do to much. Break it down into smaller classes that require less dependencies and you will find your code not only becomes more readable / understandable but also more modular and reusable. (Separation of concerns, etc.)
Regarding testing of a class that uses magic methods, I'm sure it can be done but at much more pains than if one didn't use magic methods.
Google 'Design Patterns'. What you find and learn about design patterns will improve the way you 'join' or 'wire' your classes together.
What I mean by this is: suppose there are IsCompliant and ShowWarning properties on the ViewModel. The UI has some message bound to ShowWarning, and if the ViewModel is not compliant, along with some other conditions, we want to show the warning. So, I'm coding it like this:
private bool mbIsCompliant;
public bool IsCompliant
{
get { return mbIsCompliant; }
set
{
mbIsCompliant = value;
RaisePropertyChanged (() => IsCompliant);
RaisePropertyChanged (() => ShowWarning);
}
}
public bool ShowWarning
{
get { return !IsCompliant && [other conditions]; }
}
Note that double RaisePropertyChanged call in the setter for IsCompliant, to trigger the update for the view bound to ShowWarning. But this feels klunky to me, because each property has a sprinkling of these calls throughout the ViewModel.
What I would prefer is a way to have a table of dependencies that I can register in the constructor, and have MVVMCross keep track of the fact that if Property A changed, then Property B also changed, and so on. In this way, each property keeps track of itself, and the class as a whole manages the dependency relationship between the properties.
Does this exist? Is it a reasonable idea, or is there a better way to accomplish my goal?
There's no 'one way' to do this, but a few people have experimented with different techniques including general INotifyPropertyChanged interception, some attribute based extensions and some Aspect Oriented Programming techniques
For some examples and information on these, see:
http://twincoders.com/blog/codigo-limpio-con-fody/ (via http://slodge.blogspot.co.uk/2013/07/awesome-clean-viewmodels-via-fody.html)
https://github.com/zleao/MvvmCross-PropertyChangedEventPropagation
http://slodge.blogspot.ca/2013/07/intercepting-raisepropertychanged.html
http://slodge.blogspot.co.uk/2013/06/intercepting-raisepropertychanged.html
Here's the situation: I have an abstract class with a constructor that takes a boolean (which controls some caching behavior):
abstract class BaseFoo { protected BaseFoo(boolean cache) {...} }
The implementations are all generated source code (many dozens of them). I want to create bindings for all of them automatically, i.e. without explicit hand-coding for each type being bound. I want the injection sites to be able to specify either caching or non-caching (true/false ctor param). For example I might have two injections like:
DependsOnSomeFoos(#Inject #NonCaching AFoo aFoo, #Inject #Caching BFoo bFoo) {...}
(Arguably that's a bad thing to do, since the decision to cache or not might better be in a module. But it seems useful given what I'm working with.)
The question then is: what's the best way to configure bindings to produce a set of generated types in a uniform way, that supports a binding annotation as well as constructor param on the concrete class?
Previously I just had a default constructor on the implementation classes, and simply put an #ImplementedBy on each of the generated interfaces. E.g.:
// This is all generated source...
#ImplementedBy(AFooImpl.class)
interface AFoo { ... }
class AFooImpl extends BaseFoo implements AFoo { AFooImpl() { super(true); } }
But, now I want to allow individual injection points to decide if true or false is passed to BaseFoo, instead of it always defaulting to true. I tried to set up an injection listener to (sneakily) change the true/false value post-construction, but I couldn't see how to "listen" for a range of types injected with a certain annotation.
The problem I keep coming back to is that bindings need to be for a specific type, but I don't want to enumerate all my types centrally.
I also considered:
Writing some kind of scanner to discover all the generated classes and add a pair of bindings for each of them, perhaps using Google Reflections.
Creating additional, trivial "non caching" types (e.g. AFoo.NoCache extends AFoo), which would allow me to go back to #ImplementedBy.
Hard wiring each specific type as either caching/non-caching when it's generated.
I'm not feeling great about any of those ideas. Is there a better way?
UPDATE: Thanks for the comment and answer. I think generating a small module alongside each type and writing out a list of the modules to pull in at runtime via getResources is the winner.
That said, after talking w/ a coworker, we might just dodge the question as I posed it and instead inject a strategy object with a method like boolean shouldCache(Class<? extends BaseFoo> c) into each generated class. The strategy can be implemented on top of the application config and would provide coarse and fine grained control. This gives up on the requirement to vary the behavior by injection site. On the plus side, we don't need the extra modules.
There are two additional approaches to look at (in addition to what you mentioned):
Inject Factory classes instead of your real class; that is, your hand-coded stuff would end up saying:
#Inject
DependsOnSomeFoos(AFoo.Factory aFooFactory, BFoo.Factory bFooFactory) {
AFoo aFoo = aFooFactory.caching();
BFoo bFoo = bFooFactory.nonCaching();
...
}
and your generated code would say:
// In AFoo.java
interface AFoo {
#ImplementedBy(AFooImpl.Factory.class)
interface Factory extends FooFactory<AFoo> {}
// ...
}
// In AFooImpl.java
class AFooImpl extends BaseFoo implements AFoo {
AFooImpl(boolean caching, StuffNeededByAFIConstructor otherStuff) {
super(caching);
// use otherStuff
}
// ...
class Factory implements AFoo.Factory {
#Inject Provider<StuffNeededByAFIConstructor> provider;
public AFoo caching() {
return new AFooImpl(true, provider.get());
}
// ...
}
}
Of course this depends on an interface FooFactory:
interface FooFactory<T> {
T caching();
T nonCaching();
}
Modify the process that does your code generation to generate also a Guice module that you then use in your application setup. I don't know how your code generation is currently structured, but if you have some way of knowing the full set of classes at code generation time you can either do this directly or append to some file that can then be loaded with ClassLoader.getResources as part of a Guice module that autodiscovers what classes to bind.