Skip to content

Implement your own Shark ASAP application (1 of 5)

Thomas Schwotzer edited this page Nov 3, 2023 · 7 revisions

VERY IMPORTANT: Read our developer guide before you start working on your own app with this developer guide.

Step 1: Designing your API

This first step does not concern us with any communication architecture whatsoever. This first steps brings us to an application programmers interface (API) for your app. These are the following sub steps:

Step 1.1 - use cases

Users will interact with your application.

Let’s assume a messenger app: User Alice types something in her app e.g. to send a message to her good old buddy Bob. Something happens which is of no concern yet. That's pretty easy and it won't be more complicated. Here is your first task:

Describe use cases: What are users meant to do with you applications? Do not think about libraries and communcation in ad-hoc networks. Think of your application only. What does it offer its users? These are your use cases. Write them down. Think briefly about it but do not over- engineer that step. You will miss some use cases most probably. You come back later to this point. No harm done. You are still about designing your application.

Step 1.2 - programmers interface

Uses cases define user actions performed on your application. You have to design and implement a (graphical) user interfaces later. Later, not now.

Now you have to derive a programmers interface from your use cases that will serve the later GUI. Create a project and define your interface like

public interface YourApplicationAPI {
}

Now, read your use cases and find required methods in your API. A send message use case will require a method like sendMessage(String message);. Add it.

public interface YourApplicationAPI {
    void sendMessage(String message);
}

Go ahead with all use case and write it down. Do not seek perfection. It is still a sketch and we are still in design phase. A 80 % draft will do. You need to get a feeling of your application in this stage of design.

Note: Some applications have a status. Round based games have. Chess players for instance are either active or passive. Some statuses are set from outside, some are changed by application logic from inside. Messenger applications rarely have a status except blocking. Maybe you have something like this:

public interface YourApplicationAPI {
    void sendMessage(String message);
    void blockUser(String userID);
}

Step 1.3 - data structures

An object-oriented API usually comprises data structures described by interfaces. A message in a messenger application could have two parts: message and recipient. There are two ways to describe a send method in the interface.

void sendMessage(String recipient, String message) throws Exception;
}

We could define a message interfaces:

interface Message {
    String getRecipient();
    String getMessage();
}

...
    void sendMessage(Message message) throws Exception;
...
}

Both variants will do. We prefer the latter not only due to ASAP, though. Why? We focus on data structures. Data are transmitted in any distributed application, no matter if centralized or decentralized. Sooner or later, programmers have to define data structures.

There are frameworks which help you with that, like hibernate, Room to just name a few. They help to write data into a data base. That is no help here. We need code that allows sending structured data from you application to another one – regardless if it is a server or peer.

We need code for serialization and de-serialization of structured data. We do not need it in this step but very soon. API design has an impact in data structures. It is a good time to think about it.

This code must convert structured data into a byte array and vice versa. Java offers object serialisation. That’s good but binds you to this programming language. That’s not a huge drawback. You can be on the safe side and use ASAPSerialization. Here is an example.

class MessageSerializer implements Message {
    private String recipient, message;
    private byte[] serializedMessage;

    MessageSerializer(String recipient, String message) {
        this.recipient = recipient;
        this.message = message;
        this.serialize();
    }

    MessageSerializer(byte[] serializedMessage) {
        this.serializedMessage = serializedMessage;
        this.deserialize();
    }

    private void serialize() {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ASAPSerialization.writeCharSequenceParameter(this.recipient, baos);
        ASAPSerialization.writeCharSequenceParameter(this.message, baos);
        this.serializedMessage = baos.toByteArray();
    }

    private void deserialize() {
        InputStream is = new ByteArrayInputStream(this.serializedMessage);
        this.recipient = ASAPSerialization.readCharSequenceParameter(is);
        this.message = ASAPSerialization.readCharSequenceParameter(is);
    }

    String getRecipient() { return this.recpient;}
    String getMessage() { return this.message;}
    byte[] getSerializedMessage() { return this.serializedMessage;}
}

Results

You have produced a first sketch of your API that allows for implementation of user interfaces. You also have a clear understanding of how you could (de-) serialize data which come and go through your API.

Congratulations. Next step awaits you.

Clone this wiki locally