I'm writing a Java program which separates user interface from program logic (I want to have different user interfaces)
So i want to have guaranteed, that there are capabilities to use some features of my program. Especially that means i have a class with some functions and i want to have a guarantee, that these functions will be executed (Or at least, that they somewhere are called).
To be more concrete:
I'm writing a Roguelike in Java and there shall be a classical terminal interface (only using keys) an a windowed interface (with mouse supply). In program logic there is a function for opening doors. Now i want to have guaranteed that in all user interfaces the command to open a door won't be forgotten without compiler errors. Somehow i want to have something like an inverse interface :D
Is there a way?
(An explanation in UML instead Java would be good too)
Here you had met some discrepancy in words. What you name interfaces, they are User Interfaces, UI, and they'll be realized as classes. Not interfaces.
And those descriptions that will make your UI to have all functionalities needed are called Interfaces. Funny, isn't it? :-)
public interface DoorView{
void openDoor(Orientation: openingDirection);
}
...
public class WinDoorView implements DoorView{ // this line will be marked
//as erroneous until you will write the function openDoor for the class
}
public class AsciiDoorView implements DoorView{
void openDoor(Orientation: openingDirection){
//graphics realization
}
}
In your conceptual part you'll work with DoorView.
And a class based on the interface MUST have all its functions - it will be controlled by compiler.
Related
I am programming in java for a while not much used interface. I just wondering what are the benefits of using interface. I read a article about loose coupling it states that
Tight coupling makes it much harder to add new functionality. With loose coupling, you can swap out components easily. This also makes your system more scalable as your system grows. Using loose coupling, you can safely write additional code when adding new features to your system without breaking the existing functionality.
After reading this i understood that the key take away is classes/components can be swapped easily and it helps to achieve code extensibility without breaking the existing functionality. code swapping makes sense but code extensibility without breaking changes doesn't makes sense to me.
I tried creating a interface called Player at first.
public interface Player {
void play();
}
After creating this interface i had implemented the contracts of this interface
public class BlackPlayer implements Player{
#Override
public void play() {
System.out.println("playing videos from black player");
}
}
Finally i had created a VideoPlayer class and the constructor takes Player implemented classes.
public class VideoPlayer {
private Player videoplayer;
VideoPlayer(Player videoplayer){
this.videoplayer = videoplayer;
}
void playVideo(){
videoplayer.play();
}
}
In the main method i am creating the Videoplayer instance and using its functionality
class Main{
public static void main(String[] args) {
VideoPlayer player = new VideoPlayer(new BlackPlayer());
player.playVideo();
}
}
Java Interface helps to achieve code extensibility without breaking changes, easy implementation swapping and easy unit testing(exclude about testing for now).
In future i planned to add different player i can easily swap its implementation by other class which implement the contracts of Player lets call it as Redplayer. Now i can easily swap the implementation by this line of code
Before - VideoPlayer player = new VideoPlayer(new BlackPlayer());
After- VideoPlayer player = new VideoPlayer(new RedPlayer());
Correct me if i told anything wrong about implementation swapping.
Now the second thing which confused me alot.
Interface help to achieve extensible code without breaking its functionality.
Again in future all my app users are requesting a pause feature which is already in production. Now i am trying to add the additional contracts to the already created interface.
public interface Player {
void play();
void pause();
}
After adding this pause contract all the class which implements Player showing error that override missing for pause. By introducing the pause contract broken my existing class.
Then how can i achieve code extensibility without breaking existing functionality. How can i scale the application with new features?
Adding a new method to an interface will break compilation for all the existing implementations of that interface. This is why for many years Java did not add any functionality to its core library classes like Collections. In Java 8 they added the ability to add a default implementation of an interface method so they could then add new methods to Collections interfaces without breaking compilation for everyone upgrading.
So to answer your question, you can always add a new method to an interface and give it a default implementation and you would not be breaking any of your existing code. The second way you can do this is to create a new interface called PausablePlayer which has the pause method. In Java you can implement multiple interfaces, so any implementations which support pause could implement that new interface in addition to the existing one. This approach works best when you want to add functionality which only applies to certain implementations but not all.
I have an interface like so
public interface Manager {
public void manage();
}
Now, all Managers will need to load work to manage, however, I have mixed feelings about adding public void loadWork() to the interface...
On one hand, all Managers will do this, but on the other hand, users of a Manager class will not need to know about loadWork().
Question: Is it bad practice to add "helper" or "setup" type methods to an interface?
It's not always a bad idea to add "setup" methods in an interface. For example, Java EE has an interface called ServletContextListener that is purely meant to make setup and shut down.
It's even sometimes acceptable to make interfaces with methods you should actually never directly call such as the Runnable or the Callable interface.
Being said that, it seems is that you want to force your developers to implement a loadWork() method in Manager but you also want to hide it from the class' users.
As you say, one option is adding the method in the interface but this way the method will be accessible (which you don't want). If you don't want the method to have visibility I see two options:
Make the class Manager an abstract class and add a loadWork() protected method.
Create an interface called LoadWorker with a method loadWork(). Then create an abstract class AbstractManager that implements Manager and has as a private/protected LoadWorker field. This way, even though loadWork() is public, it's not accessible from AbstractManager's users as it is called through a protected/private field (LoadWorker).
At the end it comes to a balance between overengineering and good design. It's up to you to take the decision following the specific needs. Nevertheless, there is no 'perfect solution'.
I am trying to create a simple game that can work in different platforms as a proof of concept. For now I am happy to have it working for both J2SE (using AWT or Swing) and Android. I decided to use Java for the logic of the game as both platforms expects Java code. The idea is creating a set of interfaces to abstract the OS and have a clean straight-forward game logic using these interfaces. And having 2 implementations of these interfaces, one per platform.
Some code to describe what I mean:
public class MyGameLogic implements GameLogic {
private GameSprite _sprite;
#Override
public void init(GamePlatform platform) {
_sprite = platform.loadSprite("arena");
}
#Override
public void draw(GameCanvas canvas) {
canvas.drawSprite(_sprite, 100, 200);
}
}
Here GamePlatform, GameSprite and GameCanvas would be interfaces. These interfaces will be implemented in a different way for the different platforms depending on the platform capabilities and APIs. In a similar way, GameLogic is an interface that is implemented by the game logic and not the platform. The platform will use the GameLogic interface to initialise the logic and redrawing every time is required, but more method are expected to be added in the future.
Even if I think this option is great, I see 2 flows in this design:
* the game logic can create its own implementation of GameSprite and call drawSprite() with it, which is not expected by the platform implementation.
* the implementation of the platforms must cast back all the interfaces in order they can access the real data inside the GameSprite. So if the GameSprite returned in loadSprite for J2SE is in reality a J2SESprite class, which implements GameSprite, when calling draw() I should cast the GameSprite back to J2SESprite.
In order to solve the problem I thought in adding generics, but it will make the code really ugly, here is the same code with generics.
public class MyGameLogic<
Sprite extends GameSprite,
Platform extends GamePlatform,
Canvas extends GameCanvas>
implements GameLogic<Platform, Canvas> {
private Sprite _sprite;
#Override
public void init(Platform platform) {
_sprite = platform.loadSprite("arena");
}
#Override
public void draw(Canvas canvas) {
canvas.drawSprite(_sprite, 100, 200);
}
}
This way, the game logic will not be able to call new Sprite(), as it is a generic type nor extending it, which solves the first problem, and we do not need to cast it back as the generics will provide the proper type. The problem is that I have to add the generics in all my game logic classes, and there is a generic parameter for each interface, and can be a lot at the end.
Is there any better solution? Any design pattern I am not aware of that I can use for this purpose?
Thanks!
You have one game that might have two or more user interfaces ( Swing, Android). For business applications it is common to separate the user interface from the business logic. The business logic is placed in a service layer, which is an internal API used just by the user interface code. The service layer manipulates and provides domain objects that represent what the program is about. The user interface code is placed in a separate presentation layer. It translates user inputs into calls to the service layer and translates domain objects returned from theservice layer into user interface changes.
You could use a similar design. You would have different implementations of the presentation layer (for Swing and Android) but the same service layer.
I seen many conflicting recommendations on the internet including here on how to handle input with awt and swing and several people have worked on my code and its a mess.
options
implement KeyListener or extend KeyAdapter
^to the application's main class, use an anonymous class, use a private class or use an external input managing class.
to send the event object to each object that needs to know input, to send an array of keys pressed, or to make every class a listener and add it to the main class.
So I could have
public class Board extends JPanel implements KeyListener{
public Board(){addKeyListener(this);}}
or
public Board(){addKeyListener( new KeyListener(){...});}
or
public class Board extends JPanel {
private class PrivateListener implements KeyListener{...}
public Board(){addKeyListener(new PrivateListener());
or
public class PublicListener implements KeyAdapter{...}
public class Board extends JPanel {
public Board(){addKeyListener(new PublicListener());
or
addKeyListener(this);
addKeyListener(obj1);
addKeyListener(obj2);
and implements KeyListener can be replaced with extends KeyAdapter but I won't do that because java only allows for one parent class.
then there is which I don't know how this got into my code
private boolean [] keys = new boolean[256];
public void keyPressed(KeyEvent e) {keys[e.getKeyCode()] = true;}
public void keyReleased(KeyEvent e) {keys[e.getKeyCode()] = false;}
public boolean isKeyDown(int k) {return keys[k];}
or
public void keyPressed(KeyEvent e) {
obj1.keyPressed(e);
obj2.keyPressed(e);
}
Truly, what is the best implementation of awt keyboard input?
This is a solid "it depends" situation, and this answer is open to plenty of academic discussion.
My Oppinion:
This is definately just an oppinion, but I would recomend talking to your coders and agreeing on two things. Make your decision based on the answers, and put it in the README at the base of your code:
Anonymous classes, or not?
Mega classes, or not?
Assuming prefering small, named classes I would go for the following.
public class PublicListener implements KeyAdapter{...}
public class Board extends JPanel {
public Board(){addKeyListener(new PublicListener());
Using KeyAdapter you will only have to override the functions you care about, and other programmers can see quite easily that this is where the input is handled as it is in its own class.
TLDR
Firstly, wanting to work with low level classes is a valid desire. In production code I would not recomend it, but AWT is still the basis of Swing, and wanting to learn is not to be discouraged! If nobody learns the low level stuff, then one day the open source community will have a big problem being built on top of code, which nobody has learned.
While the comments on Swing and Key Bindings are valid, in the documentation about Swing Key Bindings, there is the quote:
An alternative to key bindings is using key listeners. Key listeners have their place as a low-level interface to keyboard input, but for responding to individual keys key bindings are more appropriate and tend to result in more easily maintained code.
So if you are in it to learn some low level stuff, go for it, but take note of the maintainability warnings!
The rest comes down to two main point. Coding Style and Application Architechture.
Coding Style:
Consistency across a code base is often more important than having the perfect implementation, so if you have a codebase with an existing style, then stick to that style. For example, if your codebase already uses lots of Anonymous Classes in other places for other things, then adding a new KeyListener(){...} is fine. That said, in my personal projects I avoid anonymous classes, because personal preference...
The decision for (what I call) Mega and Mini classes is also important in coding style. The very clear recomendation is to prefer small (mini) classes, with specific roles. This would support implementing a dedicated class which extends KeyAdapter. Mini classes rarely struggle from multiple inheritance problems, allowing you to rely on default implementations (like KeyAdapter), further reducing your code complexity. Future coders can then very easily see what that class is for. Mega classes centralise all of the code into one java file, but then you will be implementing lots of interfaces, and also having to provide default implementations for everything. Compairing KeyListener to KeyAdapter this means implementing three functions instead of overriding one.
Mega classes have their place because multiple inheritance. A "Player" can be a Human, "PositionProvider", a "Drawable" etc. But in all seriousness, this is just not recommended.
Architechture:
Games programming was mentioned, so this is also an important consideration. The architechture of a game can be very different to a dektop GUI application. You need to pick an architechture, and make code which sticks to it. E.g. are you planning to let several components listen to the AWT events and act independantly (entities), or do you plan to have a seperate "InputManager" class, which abstracts input from e.g. keyboard and joypad?
I'm making a game in Java, and I think I have a good idea of how to handle events. Does this sound right?
A Window class--the view. It's a representation of the World at the current moment.
There's also a Game class -- the controller. (The model's implementation is irrelevant for this question).
The Window class doesn't care about events. Therefore, the event listener simply dispatches them to the Game class (via something like game.notifyEvent(Event e);.
The Game class, upon receipt of this event, will start updating values and the like, and some variables (like the location of the player) will be changed. At this point, it uses its class variable Window w to notify it of the changes (via various methods such as w.movePlayer(Position p), etc.
SO, does this sound like something that would make sense to you?
Yes, what you're doing makes some sense. I find it much more intuitive to have the Window listen to the Game than the other way round. I've also found that Java is much more maintainable if you separate out the different areas of the GUI and pass the Game into each of them through a fine-grained interface. I normally get the GUI elements to listen to changes in the model, and request any interactions to be dealt with. This way round makes for easier unit testing, and you can replace the GUI with a fake for acceptance testing if you don't have a decent automation suite, or even just for logging.
Usually splitting up the GUI results in some panels purely listening, and some panels purely interacting. It makes for a really lovely separation of concerns. I represent the panels with their own classes extending JPanel, and let the Window pass the Game to them on construction.
So for instance, if I have two panels, one of which displays the results and one of which has an "Update" button, I can define two interfaces: INotifyListenersOfResults and IPerformUpdates. (Please note that I'm making role-based interfaces here using the IDoThisForYou pattern; you can call them whatever you like).
The Game controller then implements both these interfaces, and the two panels each take the respective interface. The Update interface will have a method called RequestUpdate and the Results interface will have AddResultsListener. Both these methods then appear on the Game class.
Regardless of whether you get the Game to listen to the Window or the Window to the Game, by separating things through interfaces this way you make it much easier to split the Game controller later on and delegate its responsibilities, once things start getting really complicated, which they always do!
I think you should implement the Observer design pattern (http://en.wikipedia.org/wiki/Observer_pattern) without using .NET's events. In my approach, you need to define a couple of interfaces and add a little bit of code. For each different kind of event, create a pair of symmetric interfaces
public interface IEventXDispatcher
{
void Register(IEventXHandler handler);
void Unregister(IEventXHandler handler) throws NotSupportedException;
}
public interface IEventXHandler
{
void Handle(Object sender, Object args);
}
X denotes the specific name of event (Click, KeyPress, EndApplication, WhateverYouWant).
Then make your observed class implement IEventDispatcher and your observer class(es) implement IEventHandler
public class Dispatcher implements IEventXDispatcher, IEventYDispatcher ...
{
private List<IEventXHandler> _XHandlers;
private List<IEventYHandler> _YHandlers;
void Register(IEventXHandler handler)
{
_XHandlers.Add(handler);
}
void Unregister(IEventHandler handler) throws NotSupportedException
{
//Simplified code
_XHandlers.Remove(handler);
}
private MyMethod()
{
[...]
for(IEventXHandler handler: _XHandlers)
handler.Handle(this, new AnyNeededClass())
[...]
}
//Same for event Y
All the code is hand-written. I have little experience with Java but I believe this pattern may help you!