I have an arraylist that I want normal users to only be able to GET information from and then I have an administrator account that I want to be able to do SET, SORT, and other methods to the arraylist. How do I share this array list with my administrator account and normal user accounts while also having different functionality to users depending on who they are. I came across the adapter class which if I understand correctly allows you to extend it and then only use the methods that you want to use and not have to override the other ones. Please let me know if this is correct. I don't have any code right now because I am still planning my project.
You can make a list readonly by using Collections.unmodifiableList()
You don't give much details in your question, but here is an example of how it could work. Assuming that you have an object that allows you to get a hold of an array based on a UserType enum:
public List<Object> getMyArray(UserType type) {
if (type == UserType.ADMIN) {
return _myList;
}
else {
return Collections.unmodifiableList(_myList);
}
}
You can return a Collections.unmodifiableList() for the underprivileged consumers.
Or, if you want to be really restrictive and expose only certain ArrayList methods then you could consider creating your own class that has an ArrayList within. You could further subclass this with the extra methods that you want to expose to privileged consumers.
Something like this:
public class MyList<T> {
ArrayList<T> arrayList;
public T get(int index) {
return arrayList.get(index);
}
}
public class MyModifiableList extends MyList<T> {
public boolean add(T object) {
return arrayList.add(object);
}
}
Your object would no longer be a List, so it would not be able to take advantage of good stuff like Collections.sort(list).
Related
So, this is my design. AccessDecorator classes have a reference to another Access just like normal Decorator Pattern.
But the problem is when I create an AccessDecorator wrapping a ConcreteAccess and then try to see which type the Access is:
Access access = new InAllowedAccess();
Access wrapperAccess = new MismatchAccess(access);
if (wrapperAccess instanceof InAllowedAccess) //this condition could be used to be a predicate for a filtering over an access list for example
//do something
Of course this won't work because wrapperAccess is not of type InAllowedAccess but what I really want to know is all the types of some Access. In this case, the wrapperAccess would be not only of type MismatchAccess but also of type InAllowedAccess
I thought about implementing methods like isInstanceofInAllowed(), isInstanceofOutAllowed(), isInstanceofInDenied() and isinstanceofOutDenied(), isinstanceofMismatch() in Access classes but don't seems a good solution, I don't know...
Otherwise should I create a big hierarchical tree with MismatchAccesses for each 4 types InAllowedMismatchAccess, OutAllowedMismatchAccess, InDeniedMismatchAccess and OutDeniedMismatchAccess? And then, when I develp another decorator?...
Or is there another better design?
How can I know all the types of an Access? Not only the type of the wrapper access but also the type of the wrapped access.
EDIT:
One of my needs is: filter a collection of Accesses by their type - ÌnAllowedAccess, InDeniedAccess, OutAllowedAccess, OutDeniedAccess, MismatchAccess (which is a decorator) and other types of decorators that I might develop
Avoiding type checking is the usually the best way to do things. Unfortunately you haven't given enough context how you are going to use your classes so that I can give an example on how you can use polymorphism and avoid it.
Adding type checking will limit the ability of your system to grow because as new classes are added, these types need to be included in your type checks. Sometimes this can lead to bugs as your code can make assumptions of the number of classes or their types. Here's an example:
Note: I just made this up for illustrational purpose. It's not about having to represent your logic or anything like that.
public void someMethod(Access access) {
if(access instance of InAccess) {
InAccess inAccess = (InAccess)access;
}
else {
OutAccess outAccess = (OutAccess)access;
}
}
When we started our system had two classes that inherit from Access. Assume that we add another Access class to our system. This code will crash on the else because we may pass the new third access type and the cast won't succeed.
Of course this isn't always the case. Sometimes the number of classes that you have won't grow too much. It's possible that you can predict all types that will have.
And of course, since all things can happen in programming, sometimes you do need to know the types of objects you are using.
Let's assume that your system do need to know the type of objects. Here are two solutions:
Add an enum that will represent all types that you have.
public enum AccessType {
InAccessAllowed,
InAccessDenied,
OutAccessDenied,
// other types
}
public interface Access {
AccessType getType();
// other stuff
}
This way you will use the enum AccessType instead of type casting.
Use interfaces.
Instead of using classes define an interface for each type of Access. Then you will check for the interfaces instead of classes. This way your decorators can implement the same interface as the class it decorates.
public interface InAllowedAccess { }
public class InAllowedAccessImp implements InAllowedAccess { }
public class InAllowedAccessDecorator implements InAllowedAccess { }
I just wan't give an example of an alternative implementations. Since context is lacking in your description, I'll just try to guess how you are going to use your classes and add behavior to them. It's just an idea an nothing more.
Let's assume that your system grant access to users. Users can be given In and Out access and some part of your system need to ask if an access is granted or denied to a specific user so that it can execute a specific logic.
If you don't have any behavior associated with your Access classes you can just use it as a descriptor that will carry the information necessary for other classes to do their jobs.
public enum PortType { In, Out }
public enum Permissions { Allowed, Denied }
public class Access {
private PortType mPortType;
private Permissions mPermissions;
public Access(PortType portType, Permissons permissions) {
mPortType = portType;
mPermissions = permissions;
}
public PortType getType() { return mPortType; }
public Permissions getPermissions() { return mPermissions; }
}
If you do have behavior, then you can use polymorphism. Define the behavior in your Access interface and let classes that impelement this interface define the behavior.
Let's say we have messaging system that a user can receive (In) and send (out) messages. These messages go trough a channel. These channels will either accept or reject messages. Here's a way you can use polymorphism instead of type checking.
public interface MessageChannel {
public bool canSendMessages(); // out
public bool canReceiveMessages(); // in
public void receiveMessage(Message m);
public void sendMessage(Message m);
}
public class InMessageChannel implements MessageChannel {
// out messaging is not allowed, cannot send
public bool canSendMessages() { return false; }
// In messaging allowed, can receive
public bool canReceiveMessages() { return true; }
public void sendMessage(Message m) {
throw new SendingMessagesIsNotAllowd();
}
public void receiveMessage(Message m); {
// do something with the mssage
}
}
public class OutMessageChannel implements MessageChannel {
// out messaging allowed
public bool canSendMessages() { return true; }
// In messaging not allowed
public bool canReceiveMessages() { return false; }
public void sendMessage(Message m) {
// send the message
}
public void receiveMessage(Message m); {
throw new ReceivingMessagesIsNotAllowd();
}
}
As you can see each MessageCahnnel has a behavior accosiated with it. It can either send of receive messages if it's allowed or not. This way other classes that use the MessageChannel won't have to do type casting.
I thought about implementing methods like isInstanceofInAllowed(), isInstanceofOutAllowed(), isInstanceofInDenied() and isinstanceofOutDeniedd() in Access classes but don't seems a good solution, I don't know...
You are right. That’s a bad solution. An interface often belongs to a layer with high level of abstraction in software, thus the list of its methods should be stable. If you put such a bunch of methods like above into the Access interface, the interface would be very unstable since in the future it’s very likely that you will add more such methods to it.
The simplest solution to your problem is adding (only one time) a new method named core() to the Access interface. Every decorator just implements this method by returning the wrapped/core object.
interface Access {
...
Access core();
}
Access a = ...
if (a.core() instanceof ...
I'm trying to define a container for a whole bunch of classes as some parts of the code will make more sense with a collection but other places will make sense with single values.
Ideally I'd like to do this:
public class AllModes<T> {
private T<Car> car;
private T<Boat> boat;
private T<Train> train;
private T<Plane> plane;
...40 more of these...
}
then I'd like to use the class like:
AllModes<List> allModes;
AllModes<Optional> oneOfEachMode;
But I get the error I get is "The type T is not generic; it cannot be parameterized with arguments "
The reason I'm defining these in multiple variables and not a single HashSet based on a superclass is I want to have get methods that return the correct types to avoid consumers of this class needing to cast down everywhere as each object has its own distinct fields.
I also considered just storing a single value list or set but I thought it might less error prone to use the correct type I intended (ie. one value)
You can't achieve what you want using the Java type system.
Since you can't have a generic container type, you'll need to enforce the invariants with dedicated constructors (or subclasses).
But if you do so, the clients of your class will not be able to distinguish between different container types (Optional vs List), they will need to work with a generic abstraction (like Stream, Iterator, Iterable, whatever suits you).
Here's an example:
public class AllModes {
private final Supplier<Stream<Car>> cars;
private final Supplier<Stream<Boat>> boats;
public AllModes(Optional<Car> car, Optional<Boat> boat) {
// Assuming Java 8, when Optional did not have a stream() method yet
this.cars = () -> car.map(Stream::of).orElse(Stream.empty());
this.boats = () -> boat.map(Stream::of).orElse(Stream.empty());
}
public AllModes(List<Car> cars, List<Boat> boats) {
this.cars = cars::stream;
this.boats = boats::stream;
}
public Stream<Car> getCars() {
return cars.get();
}
public Stream<Boat> getBoats() {
return boats.get();
}
}
You can't solve it this way. Use the instanceof operator instead. Here is an example:
public class AllModes<T> {
private T object;
private void check(T object) {
if(object instanceof Boat){
System.out.println("Boat");
// your code for Boat goes here
} else if (object instanceof Car) {
System.out.println("Car");
// your code for Car goes here
}
}
}
I'd suggest you take a step back and re-consider what exactly you want to achieve with this container. E.g. ask yourself what its domain is or what the client is supposed to do with Allmodes<T>...
Another more concrete question that comes to mind is how exactly you intend to popuplate that Optional<T> generically? Will it be the first element in the List<T> or the last? Or an element which satisfies a specific Predicate<T>?
Your design doesn't seem to be that well thought out yet.
What you could do which would come close to what you descibed (in case I got that right) is provide an accessor of type Stream<T> as you could get both a List<T> aswell as an Optional<T> from it. Your client would then have to make that decision and also determine how exactly to derive the Optional<T> from the Stream<T>.
From The Java™ Tutorials - Why Use Generics?:
By using generics, programmers can implement generic algorithms that work on collections of different types, can be customized, and are type safe and easier to read.
You can have multiple types in class and then you can associated them with the fields. But in your case, you have several fields with some type. A class don't have much dependencies on others. You should design you class in a way that there are no much dependencies there.
public class AllModes<T,T1,T2,T3> {
private T car;
private T1 boat;
private T2 train;
private T3 plane;
}
Consider the following class:
public class Cars extends Observable{
private ArrayList<String> carList = new ArrayList<String>();
public void addToCarList(String car){
// ...
hasChanged();
notifyObservers();
}
public void removeFromCarList(String car){
// ...
hasChanged();
notifyObservers();
}
public ArrayList<String> getCarList() {
return carList;
}
}
As you can see, every time the carList is changed, I want to notify the Observers.
If someone does getCarList().add(...);, this is circumvented.
How can I give read access to the carList (for iterating over it etc.) but prevent write access to it except for the special methods addToCarList and removeFromCarList?
I thought about this:
public ArrayList<String> getCarList() {
return (ArrayList<String>)carList.clone();
}
but someone using my class would, when adding something to the clone of carList, not be informed that that's not the way it's meant to be done.
You can return an unmodifiable view of it, changing the return type to List<String> instead of ArrayList<String>:
public List<String> getCars() {
return Collections.unmodifiableList(carList);
}
Note that as Collections.unmodifiableList does only provide a view, the caller will still see any other changes that are made via addToCarList and removeFromCarList (which I'd rename to addCar and removeCar, probably). Is that what you want?
Any mutating operations on the returned view will result in an UnsupportedOperationException.
First, always avoid using concrete class at the left side of assignment and as a return value of method. So, fix your class as
public class Cars extends Observable{
private List<String> carList = new ArrayList<String>();
........................
public List<String> getCarList() {
return carList;
}
}
Now you can use Collections.unmodifiableList() to make you list read-only:
public List<String> getCarList() {
return Collections.unmodifiableList(carList);
}
BTW, if you do not really have to return List you can probably return Collection or even Iterable. This will make increase the encapsulation level of your code and make future modifications easier.
Jon Skeet's answer is excellent (as always) but the one thing it doesn't touch on is concurrency issues.
Returning an unmodifiable collection will still leave you with issues if multiple threads are accessing this object at the same time. For example if one thread is iterating over the list of cars and then at the same time another thread adds a new card.
You will still need to synchronize access to that list somehow, and this is one reason why you might consider returning a clone() of the list as well as or instead of just wrapping it in the unmodifiableList wrapper. You would still need to synchronize around the clone() but once the clone is completed and the list returned to the querying code it no longer needs to be synchronized.
I think you could probably make your Object implement the Collection-Interface, if it is in fact an ObservableList. It is a List and it should be Observable - so it should implement both interfaces.
You could even Extend List<..> because you just want to add extra functionality (observers) to the current functionality and your List can be used everywhere where a normal List could be used...
use Collections.unmodifiableList(list) as it provides a new List object which cannot be modified , it would throw an UnsupportedOperationException while trying to update/add/delete objects list.
I would like to add a collection of objects to an arrayList ,only if the particular attribute is not null.
I am thinking of extending the ArrayList and implementing the check inside the child class.
One alternate way is to check for the the attribute before putting it in a Arraylist, but that would mean , i will have to scatter the if checks every where if i need to add the objects to the arraylist based on the logic.
I would like to know your thoughts on it ... on a second thought is it a overkill ?
Decorator pattern
I would actually recommend wrapping ArrayList using well-documented Decorator pattern. You simply wrap your ArrayList with another List implementation that delegates most of the methods but adds validation logic:
public class ValidatingListDecorator extends AbstractList<MyBusinessObject>
{
private final List<MyBusinessObject> target;
public ValidatingListDecorator(List<MyBusinessObject> target) {
this.target = target;
}
#Override
public MyBusinessObject set(int index, MyBusinessObject element)
{
validate(element);
return target.set(index, element);
}
#Override
public boolean add(MyBusinessObject o)
{
validate(o);
return target.add(o);
}
//few more to implement
}
Advantages:
You can still access raw list without validation if you want (but you can restrict this)
Easier to stack different validations, turn them on and off selectively.
Promotes composition over inheritance as noted by #helios
Improves testability
Does not tie you to a specific List implementation, you can add validation to LinkedList or Hibernate-backed persistent lists. You can even think about generic Collection decorator to validate any collection.
Implementation notes
Despite the implementation remember there are quite a lot of methods you have to remember about while overriding: add(), addAll(), set(), subList() (?), etc.
Also your object must be immutable, otherwise the user can add/set valid object and modify it afterwards to violate the contract.
Good OO design
Finaly I wrote:
validate(element)
but consider:
element.validate()
which is a better design.
Stacking validations
As noted before if you want to stack validations, validating each proprty/apsect in a single, separate class, consider the following idiom:
public abstract class ValidatingListDecorator extends AbstractList<MyBusinessObject>
{
private final List<MyBusinessObject> target;
public ValidatingListDecorator(List<MyBusinessObject> target) {
this.target = target;
}
#Override
public MyBusinessObject set(int index, MyBusinessObject element)
{
validate(element);
return target.set(index, element);
}
protected abstract void validate(MyBusinessObject element);
}
...and few implementations:
class FooValidatingDecorator extends ValidatingListDecorator {
public FooValidatingDecorator(List<MyBusinessObject> target)
{
super(target);
}
#Override
protected void validate(MyBusinessObject element)
{
//throw if "foo" not met
}
}
class BarValidatingDecorator extends ValidatingListDecorator {
public BarValidatingDecorator(List<MyBusinessObject> target)
{
super(target);
}
#Override
protected void validate(MyBusinessObject element)
{
//throw if "bar" not met
}
}
Want to only validate foo?
List<MyBusinessObject> list = new FooValidatingDecorator(rawArrayList);
Want to validate both foo and bar?
List<MyBusinessObject> list =
new BarValidatingDecorator(new FooValidatingDecorator(rawArrayList));
If you would like to enforce this I don't see why not (although you should check the return value of the add method whenever you do add to make sure that it succeeded).
This is a good way to get rid of that redundant logic which may or may not stick around in later software iterations.
I don't think this is a good practice. Consider instead writing a Util-Method in a Util-Class taking two parameters: The array list and the object you would like to add. There you can check whatever you want and can reuse the logic all over your code.
Only issue would be if you go to reuse this code and you don't remember you've overriden the ArrayList class, make sure to comment thoroughly.
I have a class called DataSet with various constructors, each specifying a different type of variable. It might look a bit like this:
public class DataSet
{
private HashSet Data;
public DataSet( DataObject obj )
{
Data = new <DataObject>HashSet();
Data.add( obj );
}
public DataSet( ObjectRelationship rel )
{
Data = new <ObjectRelationship>HashSet();
Data.add( rel );
}
// etc.
Note: I haven't yet gotten to test that code due to incomplete parts (which I'm building right now).
In a function that I'm currently building, getDataObjects(), I need to return all DataObject objects that this set represents. In the case of constructors that initiate the class's HashSet, Data with types other than DataObject (such as the above ObjectRelationship), there obviously won't be any DataObjects stored within. In this case, I need to be able to detect the type that the HashSet 'Data' was initiated with (like, to tell if it's 'ObjectRelationship' or not, I mean). How do I do this?
tl;dr: How do I tell the type that a Collection (in this case, a HashSet) was initiated with in my code (like with an 'if' or 'switch' statement or something)?
Sounds like you want to make the entire class generic- add a template parameter to the declaration for the class and define your HashSet and retrieval functions using that template parameter for the types.
I'm a .Net guy at the moment, though, so I couldn't give you the Java syntax, but using C# syntax it would look something like this:
public class DataSet<T>
{
private Set<T> Data;
public DataSet( T obj )
{
Data = new HashSet<T>();
Data.add( obj );
}
public Iterator<T> getDataObjects()
{
return Data.iterator;
}
}
You could fetch an object from the set and verify its type.
Or you could have multiple sets to contain different types.
Or you could have an instance variable of type Class to act as a discriminator as an instance variable.
Or you could create a proxy object for HashSet using the last technique.
You could use a map to the set
HashMap <Class<?>, HashSet<Object>> data;
HashSet temp = data.get(DataObject.class);
if(temp == null)
{
temp = new HashSet();
data.put(DataObject.class, temp);
}
temp.add(obj);
Then you will get the best of both worlds.
Sounds like your design needs to be re-thought.
Also, to be clear on Generics; you cannot access the type at runtime. The type parameter is only for compile-time checking and is completely gone (type erasure) at runtime.
What does this class offer that CachedRowSet does not?
Sorry, I don't consider this to be a very good abstraction. If I were a member of your team, I wouldn't use it.
Your syntax doesn't look correct to me, either. IntelliJ agrees with me: it won't compile.
This does:
import java.util.HashSet;
import java.util.Set;
import java.util.Arrays;
public class DataSet
{
private Set<DataObject> data;
public DataSet(DataObject obj)
{
this.data = new HashSet<DataObject>();
data.add(obj);
}
public DataSet(DataObject[] objs)
{
data = new HashSet<DataObject>();
data.addAll(Arrays.asList(objs));
}
// etc.
}
Still a poor abstraction. Rethink it.
You could add an property to your dataset class (an enumerated value, boolean or type) that specifies which type was used to initialize the hashset.
Set the property in the appropriate constructor. This allows you to bypass getting an element out of the collection to check its type.
pseudo-code:
public class DataSet
{
private HashSet Data;
private Type _iw = null;
public Type InitializedWith { return _iw; }
public DataSet(DataObject)
{
...
_iw = typeof(DataObject);
}
public DataSet(ObjectRelationship)
{
...
_iw = typeof(ObjectRelationship)
}
I'm going to follow duffymo's advice and just use better abstraction. I'm going to make multiple classes for each specific type I plan to use (each implementing a common interface) so that I can just bypass this dumb problem.
It'll add a minuscule bit of overhead during the process of creating each DataSet object of correct type, but I suppose that's just how it goes.
I don't know what DataObject gives you over and above an Object.
I think an object-oriented approach to your problem would use classes that reflected your domain of interest (e.g., Invoice, Customer, etc.). The persistence layer would hide the persistence details.
A common way to accomplish this is to use the Data Access Object, which might look like this in Java:
public interface GenericDao<T>
{
T find(Serializable id);
List<T> find();
void save(T obj);
void update(T obj);
void delete(T obj);
}
Now you're dealing with objects instead of things that smack of relational databases. All the CRUD details are hidden behind the DAO interface.