I am designing a game and I have good overview of what I am doing.
However I've been trying to improve my OOP skills but now and then I face the same problem, how should I use the abstracted objects?
Lets say I have a list of Entitys that represents anything that has x and y property on screen and probably width and height haven't figured all out yet!
Then I have special types of entitys, one that can move and one that cannot and probably something like collidable in future.
They're all in a collection of Entitys (List<Entity> in my case) and now I want to simulate entitys that moves and are instances of DynamicEntity on main loop but they're all on abstract list of Entitys and I don't know is the Entity in loop either dynamic entity or not.
I know I could just check it with instanceof but I am pretty sure that's not the best idea..
I've seen some people having something like boolean inside the Entity for checking its type but I don't really want to hardcode all kind of entitys there..
I just want to know what is the best practice in such case?
Usually it's better to avoid checking the type if possible. If you think you need to use instanceof in your code then there's probably an abstraction you could be using to make your design more extensible. (If you decide to add a third type of Entity in the future you don't want to have to go back and update all of your instanceof checks with a third case.)
There are two common ways to have different actions based on an instance's concrete type without checking the concrete type:
One common way is the visitor pattern. The idea here is to create a Visitor class with an action for each type of object. Next, each concrete class has an accept method which simply calls the correct visit method inside the visitor class. This single level of indirection allows the objects to choose the correct action themselves rather than you choosing it by checking the type.
The visitor pattern is usually used for one of two reasons. 1) You can add new actions to a class hierarchy that implements the visitor pattern without access to the classes' source code. You only have to implement a new visitor class and use it in tandem with the visitable classes' pre-existing accept methods. 2) When there are many possible actions one can perform on classes from some type hierarchy sometimes it's more clear to split each action off into it's own visitor class rather than polluting the target classes with a bunch of methods for a bunch of different actions, so you group them with the visitor rather than the target classes.
However, in most cases it's easier to do things the second way: to simply override the definition of a common method in each concrete class. The Entity class might have an abstract draw() method, then each type of Entity would implement that draw() method in a different way. You know that each type of Entity has a draw() method that you can call, but you don't have to know the details of which type of entity it is or what the method's implementation does. All you have to do is iterate over your List<Entity> and call draw() on each one, then they'll perform the correct actions themselves depending on their type since each type has its own specialized draw() implementation.
You're right that you don't want to check the instance type or have some sort of function to check capability. My first question would be - why do you have a list of entities of that base type in the first place ? It sounds to me like you need to maintain a list of dynamic entities.
You could implement a move() method that does nothing for non-dynamic entities, but again that doesn't seem right in this particular scenario.
Perhaps it would be better to implement an event that triggers the iteration of that list, and pass that event into each object in turn. The dynamic entities could decide to move upon that event. The static entities would obviously not.
e.g.
Event ev = ...
foreach(e : entities) {
e.actUpon(ev);
}
In this scenario you could have different event types, and the entities would decide upon their action upon the basis of the event type and the entity type. This is known as double-dispatch or the visitor pattern.
If your processing of entities relies on knowing details about the entity types, then your Entity abstraction doesn't buy you much (at least not in this use-case): your List<Entity> is almost as opaque for you as a mere List<Object>.
If you know that every entity you can imagine will be either static or dynamic, there's no "hard-coding" in having a boolean property to all entities: isDynamic() or something.
However, if the dynamic aspect only makes sense for a subset of your entities, this flag will indeed bring some mess to your abstraction. In this case, my first guess is that you didn't model the use-case properly since you need to work with a list of items that do not provide enough polymorphic information for you to handle them.
Related
Based on the Accountability Analysis Pattern:
The concept is that we have a class diagram following the logic of the Accountability Analysis Pattern. How can I use the given function assignStaffContact() to assign contact?
I have undrerstood that StaffContact class is a control class and the Client, StaffMember are entity classes (we don't care about the TimePeriod class).
I cannot figure out which classes are gonna play a part in the procedure of assigning staff contact in order to create the proper sequence diagram (UML) of this action. Arbitrarily there must be a boundary class providing the wanted interface. The actor is gonna pick the case of assigning staff contact, which will trigger the method assignStaffContact() of the control class StaffContact but with which entity classes this will communicate and finally assign the staff?
I am getting confused with class ContactForCampaign and the logic behind it being connecte to the classes Client and StaffMember. I hope I explained well enough my problem and my thought process.
This diagram says that:
A StaffContact instance can be associated to several ContactForCampaign instances
Each instance of ContactForCampaign is associated with exactly one instance of a Campaign, and defines exactly one StaffMember object as responsible, and. one Client object as commissioner (probably for the campaign).
As a consequence, we can only guess that StaffContact::assignContact() requires to know which StaffMember to add (should be an argument of the operation). Since several ContactForCampaign instances can be considered, the ooeration would probably also need to know which ContactForCampaign is relevant for the assignment. Probably this can be determined with the help of a Campaign parameter. Two cases must then be considered: replacing a staff member of an existing ContactForCampaign or create a new one if no assignment exist for a campaign. You have now all the ingredients for your sequence diagram. Note also that the operation would need to know which client is to be assigned as commissioner if a new ContactForCampaign os created.
The result could look like (simplified):
Note that StaffContact::removeStaffContact() does not seem relevant, in view of the multiplicity 1 for the StaffMember, unless you condider removing as well the ContactForCampaign, which would then cause to lose the information regarding the commissioner.
Last but not least, in view of the 1 multiplicity on the side of StaffContact, it would not be a control class, since the control is in princple existing for the time of the use case execution only, and should not have a permanent semantic link to the objects that it controls.
I am designing a program that allows you to create an object with traits and then add it to a database. For example, a renting property like so:
public class Property
{
PropertyType type;
int bedrooms;
int bathrooms;
double squareFootage;
boolean furnished;
}
Then, you or other users can search the database for objects based on those traits. But here are the restrictions:
All properties have one of each trait defined (you can't leave one trait blank)
You may search for properties by any one trait, combination of traits, or no traits (to see all). AND you can specify a multiplicity for each trait. For example, you can specify a HOUSE with 2, 3 or 4 bedrooms and 2 or 3 bathrooms. Thereby not putting restrictions on square footage or furnishing.
This poses a problem, as the existence of a trait in the search criteria may or may not exist, and may have a multiplicity. Here is my current solution to hold the search criteria:
public class SearchCriteria
{
ArrayList<PropertyType> type;
ArrayList<int> bedrooms;
ArrayList<int> bathrooms;
ArrayList<double> squareFootage;
ArrayList<boolean> furnished;
}
The problem is that when I want to add another trait to Property, I have to add it to both these classes (and probably more in database controller etc) and add additional functions for it in each. What is a design pattern I can utilize to make this code more modular and abstract?
Essentially, a good answer would be a solution that allows the addition or removal of traits by only changing one class/file.
Simply using an interface Trait with an overidden function getTrait() wouldn't work because the return types aren't the same across all traits.
EDIT: I have to implement a SearchCriteria class because this program is run on a client/server connection, so SearchCriteria will be serialized and sent over a socket, not sent directly to the database.
If you only have a handful of traits, and they're fundamental to your business model, it's totally reasonable to have to change more than one class when you add a new trait or want to change the type of behavior of one of those traits.
However, if you're trying to come up with a model that can handle dynamically adding different types of traits to your object, you may consider not encoding the traits as class properties at all. Rather, have your model contain a list of Traits, where each Trait knows its TraitType. Each TraitType has a specific shape for its data, as well as a specific shape for its Criteria. This would enable you to define your model in a file or database somewhere, and change it on demand, and only have to change the code when you identify a new TraitType. But it would also be an enormous amount of work, and would only be worthwhile if your business needs require a high degree of configurability.
I need to implement some specific functionality and I am wondering if you might know of a java library that does this, or something like it already. I would rather use an existing before building my own.
Basically I want a collection type class that contains instances of FooBar. When the container is constructed, I specify the attribute values or ranges that qualify a FooBar for membership, so when a FooBar instance is inserted, it will be rejected if it does not meet the criteria. In addition, if the attributes of any FooBar in the container are modified in such a way that they no longer meet the membership criteria, they will be ejected (preferably with some sort of callback to registered listeners).
I can elaborate more, but I think the concept is fairly straight forward.
Seen anything like that ?
Thanks.
You could add a set of listeners to the class performing the add / retain and which allows the class to 'choose' whether to add candidate as a listener - and also later on based on your interesting events occurring - whether to 'retain' them or evict them:
public interface AddableEvictable {
public boolean isAddable();
public boolean evict();
}
Then add a Set to your interesting server class and candidate classes to add/(/later evict) would need to (a) implement this simple interface and (b) offer themselves to the server class for it to decide whether to add/not (and later when/if to evict)
I have a class which models FK relationship. It has 2 lists in it. These lists contains the column names of the Parent Table & the Child Table respectively. These lists are passes by the client to me. Now before creating my FK object, I think it is necessary to do following checks (in order):
Check if lists are not null.
Check if lists contains null.
If a list contains duplicates columns?
Size of both the lists are equal.
So you can see there will be total 7 checks. Is it OK to have so many checks?
If it is OK to have these many checks, is there any pattern to handle such cases (with high no. of validation checks)?
If it is not OK, then what should I do? Should I just document these conditions as part of contract & mention that API will produce nonsensical results if this contract is violated?
Edit : Basically, I am trying to takes these 2 lists & produce a Database specific Query. So, it is kind of important to have this object built correctly.
Like everybody says, it depends on you. There is no such fixed/standard guideline for this. But to make it simple, you must have to put all your validation logic in one place, so that it remains readable and easy to change.
A suggestion can be, as you said, all of your validation logic seems to be very business oriented..by which I mean the end user should not be bothered about your db configuration. Let assume your class name, FKEntity. So if you follow the entity concept then you can put the validation logic in FKEntity.validate() (implementing an interface Validatable) which will validate the particular entity...this is for those kind of validation logic which applies to all FKEntity type objects in same way. And if you need any validation logic that compares/process different FKEntity depending on each other (e.g. if there is one FKEntity with some value "x" then no other entity can have "x" as their values, if they do, then you can not allow the entire entity list to persist), then you can put the logic in your Service layer.
Inteface Validatable { void validate() throws InvalidEntityException; }
Class FKEntity implements Validatable {
//..
public void validate() throws InvalidEntityException {
//your entity specific logic
}
}
Class FKDigestService {
public digestEntities() {
try {
for(FKEntity e : entityList)
e.validate();
//your collective validation logic goes here
} catch (EntityValidationException e) {//do whatever you want}
}
}
This will give you two advantages,
Your entity specific validation logic is kept in a single place (try to think most of the logic as entity specific logic)
Your collective logic is separated from entity logic, as you can not put these logic in your entity since these logic is only applicable when there is a collection of FKEntity, but not for single entity...it is business logic, not validation logic
I depends on you. There is no real argument against many checks. If your are developing an API, this can be very useful for other programmers. And it will make your own program more reliable.
I think the important point is, that you do your checks at one single point. You must have a clean and simple interface for your API. In this interface, it is ok to make checks. After these checks you could be sure that everything works.
What happens if you leaf the checks away? Will an exception be thrown somewhere or will the program just do something? If the program will just work and do something unpredictable, you should provide checks or things will begin to get strange. But if an exception will be thrown anyway, (I think) you can leaf the checks away. I mean, the program will get an exception anyway.
This is complex problem, so solution should be simplest possible to do not make it even more complicated and less understandable.
My approach would be:
some public method wrapping private method named something like doAllNeededListsValidationInFixedOrder() in which I'd create another private methods - each for every needed validation.
And ofc writing method like doAllNeededListsValidationInFixedOrder should be follow by some solid javadoc, even though it's not public.
If you want to go for pattern - the solution wouldn't be so straightforward. Basic thing to require checks in given order is to create lots or classes - every one for state telling that object is after one check, before another.
So you can achieve this with State pattern - treating every check as new state of object.
OR
You can use something like Builder pattern with forced order of methods invoked to create object. It is basically using a lot of interfaces to have every single (building) method (here validating) fired from different interface, to control order of them.
Going back to begining - using simple, well documenented and properly named method, that hides validating methods set, seems better for me.
If it is OK to have these many checks, is there any pattern to handle such cases (with high no. of validation checks)?
These checks become trivial if tackled from a data conversion point of view.
List from a client is actually any list of any possible elements
List from a client is to be converted to a well defined list of not duplicating not null elements
This conversion can be decomposed into several simple conversions ToNonNull, ToNonNullList, ToNonDuplicatingList
The last requirement is essentially conversion from two lists to one list of pairs ToPairs(ListA, ListB)
Put together it becomes:
ParentTableColumns = List1FromClient.
ToNonNull.
ToNonNullList.
ToNonDuplicatingList
ChildTableColumns = List2FromClient.
ToNonNull.
ToNonNullList.
ToNonDuplicatingList
ParentChildColumnPairs = List.
ToPairs(ParentTableColumns, ChildTableColumns)
If data from client is valid then all conversions succeed and valid result is obtained.
If data from client is invalid then one of the conversions fails and produces an error message.
I am working a container to hold a list of objects (of the same class) the have certain fields that use a custom RetentionSortable annotation. The purpose of the annotation is two fold:
To mark the field as able to be compared to another objects same field.
And to give the sort name of the field (eg. Modification Date or First Name).
The container will then walk through the list of objects (remember they are like) and gather the list of RententionSortable's that the object contains and pass the list to the GUI. The GUI will display the list and request a sortable selection and return it to the sortable which will then sort the list based on the RetentionSortable selected.
The purpose of this method or sorting object is to allow me to create a small container that can generically accept any object and sort it as long as it has at least one RetentionSortable field.
My gut screams that this is bad practice and that relying this much on reflection is a bad idea but my tests work flawlessly and better than I expected.
Is using annotation reflection to find all the fields that are annotated by a particular annotation good practice for abstract object sorting?
Annotations are there for convenience, and your use is making the situation more convenient, so it seems reasonable. The alternative is to maintain a separate dictionary of which fields are sortable for which objects, and is slightly more cumbersome but slightly better from a seperation of concerns point of view.
The question is really whether your object should know about the annotations or not (is the object going to be reused in another situation where the annotations do not make sense or conflict). With a separate list of sortable fields, you can pick which to apply in any given case.
If the convenience trade-off works for you, then you should stick with the annotations, just so long as you are aware of the potential design ramifications (which may be nothing for your particular case).
How do you think basically every annotation-driven configuration framework works? "Give me all the of such-and-such type fields annotated with '#Inject'" or "give me everything in package baz.plugh annotated with '#Controller'".
Whether or not it's good for "abstract sorting" or not, I don't see why not. If it works, and eliminates the need for things like bean mappers and bean info classes, what's the issue?