Design Pattern for multiple similar APIs in one application [closed] - java

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 days ago.
Improve this question
Let's say I'm working with multiple different music stream APIs. User passes me the link from one of the supported streaming services. Similar API responses should be mapped on the same application's object for further processing, but every API has unique algorithm of doing that. What's the correct way of doing that?
I came up with next solution. I'm creating an interface MusicApi, which contains methods getAppObject and isLinkMatches
public interface MusicApi {
public static AppObject getAppObject(String link);
public static boolean isLinkMatches(String link);
}
For example we're working with these APIs. Let's say they're implementing method correctly.
public class NapsterApi implements MusicApi {}
public class SpotifyApi implements MusicApi {}
public class YoutubeApi implements MusicApi {} // As example of completely different audio extraction algorithm
Now I have to choose when to use which API. I've decided to create MusicApiSelector class
(Kept implementation listing simple without using Java Reflection API or Spring #Component)
public class MusicApiSelector {
private static final MusicApi[] registeredApis = new MusicApi[]{NapsterApi, SpotifyApi, YoutubeApi};
public static MusicApi getApi(String link) {
for (MusicApi api : registeredApis) {
if (api.isLinkMatches()) {
return api;
}
}
throw new Exception("This link is not supported")
}
}
Using this should look something like this
public class Main {
public static void main(String[] args) {
String link = https://www.youtube.com/watch?v=djV11Xbc914;
MusicApi api = MusicApiSelector.getApi(link);
AppObject appObject = api.getAppObject(link);
}
}
Can you tell me if that's valid approach how this pattern is called (i guess it's Strategy Pattern). And what I can do better (maybe some completely different patterns)

Related

How to mock protected global variables boolean in java junit test [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 16 days ago.
This post was edited and submitted for review 15 days ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
How to mock protected global variables boolean in Java JUnit test?
public abstract class Base {
protected boolean varBoolean;
...
}
public class NameClass extends Base {
private List <String> arrayStr;
public void init() {
if (varBoolean) {
...
}
...
}
}
#RunWith(JUnit4.class)
#Slf4j
public class NameClassTest {
public void testInnit() {
}
...
}
How to mock protected varBoolean be equal true in Java unit test?
And mock private string list arrayStr
I can fix it.
#RunWith(JUnit4.class)
#Slf4j
public class NameClassTest {
#InjectMocks
NameClass nameClass;
#Test
public void testInit() throws Exception {
nameClass.varBoolean = true;
nameClass.init();
...
}
}
nameClass.varBoolean = true;
Add a test only constructor to NameClass with a varBoolean parameter. Call it in your test with whatever argument you want.

What is the best way to create custom filters for a repository? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
So I have a controller called CircuitController where I want to retrieve an Entity both from the ID and from a reference:
#GetMapping("/api/circuits/{id}")
public EntityModel<Circuit> getCircuitById(#PathVariable Long id) {
Circuit circuit = circuitRepository.findById(id)
.orElseThrow(() -> new CircuitNotFoundException(id));
return circuitModelAssembler.toModel(circuit);
}
#GetMapping("/api/circuits/")
public EntityModel<Circuit> getCircuitByRef(#RequestParam(value="ref") String ref) {
// no "circuitRepository.findByRef(ref) method here.
}
For the second method, there is no findByRef(String ref) method already implemented in the JPARepository
I came up with 2 solutions:
In my CircuitRepository class I can define a default method findByRef(String ref) to do exactly what I need and then use it from the CircuitController class.
#Repository
public interface CircuitRepository extends JpaRepository<Circuit, Long> {
default Circuit findCircuitByRef(String ref) {
Optional<Circuit> circuit = this.findAll()
.stream()
.filter(circuit1 -> circuit1.getCircuitRef().equals(ref))
.findAny();
if (circuit.isPresent()) {
return circuit.get();
} else {
throw new CircuitNotFoundException(ref);
}
}
}
and then I can do:
#GetMapping("/api/circuits/")
public EntityModel<Circuit> getCircuitByRef(#RequestParam(value="ref") String ref) {
Circuit circuit = circuitRepository.findCircuitByRef(ref);
return circuitModelAssembler.toModel(circuit);
}
The 2nd option would be to implement the logic in my getCircuitByRef method directly like this:
#GetMapping("/api/circuits/")
public EntityModel<Circuit> getCircuitByRef(#RequestParam(value="ref") String ref) {
Circuit circuit;
Optional<Circuit> optionalCircuit = circuitRepository.findAll()
.stream()
.filter(circuit1 -> circuit1.getCircuitRef().equals(ref))
.findAny();
if (optionalCircuit.isPresent()) {
circuit = optionalCircuit.get();
} else {
throw new CircuitNotFoundException(ref);
}
return circuitModelAssembler.toModel(circuit);
}
I'm not sure what is the best practice here, or how the code standards for spring applications are. On thing I've noticed is that with the first option, I can then later mock my CircuitRepository interface and mock the findByRef method for UT purposes.
In general, it is a better practice to separate functional components in a project. I prefer to do it like this - Controller is responsible for handling the API calls, Repository - data access. So, I would stick with the 1st option.
As for the actual implementation, I would recommend using Spring's functionality. There is no method findCircuitByRef(String ref), but Spring can create an implementation of this method for you. What you can do is the following:
#Repository
public interface CircuitRepository extends JpaRepository<Circuit, Long> {
Circuit findByCircuitRef(String ref);
}
What Spring will do behind the scenes is the following - it will create an implementation of this method, which does what you are doing in the default implementation.
You can see more information on the topic here.

API design suggestion [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am developing an API (library) for servers (imagine a simple server that receives a request and writes a response back on the connection).
I have a situation where I have 3 different frameworks (third party libraries). All of these provide a way to handle requests, but in their own way. Imagine the following are the interfaces to each lib:
lib A
public class AHandler implements AHandler {
public Response handle(Request req){
// ..
}
}
lib B
public class BHandler extends SomeHandler {
public BResponse handle(BRequest req){
// ..
}
}
lib C
#Handler
public class BHandler {
#HandlerMethod
public void handle(CRequest req, CResponse res){
// ..
}
}
I want to create an API that abstracts out the handle() method into some uniform way. Since A, B and C are third party, I don't have a way to modify them.
Facts:
the user can have one or more of such Handlers per server;
I can't modify the source of the third party libs and I don't want to control their releases.
What is the best way to go about API designing that can provide an uniform interface for all the three libs?
You could achieve the desired result using a combination of facade and adapters.
// defines the uniform interface exposed to API clients
interface Facade {
void handleRequest(Request request, Response response)
}
// defines the uniform interface each handler will have to expose
interface Adapter {
void handleRequest(Request request, Response response)
}
// takes a concrete adapter as argument and delegates to it for the concrete handle logic implementation
class ConcreteFacade implements Facade{
private Adapter adapter;
public ConcreteFacade(Adapter adapter){
this.adapter = adapter;
}
public void handleRequest(Request request, Response response){
adaper.handleRequest(request, response);
}
}
// one concrete adapter for each library
class ConcreteAdapter implements Adapter {
private AHandler handler;
public ConcreteAdapter(AHandler handler){
this.handler = handler;
}
public void handleRequest(Request request, Response response) {
//delegate to handler
}
}

Real Time Scenarios to use singleton class in android [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I know about singleton class. but i want to know Real Time Scenarios to use singleton class in android . Can anyone give me examples in android to use and with benefits of that scenario..
Two real good scenarios
Extend your application class and use it's instance to get access to the app context within any class
SQL Database is a good idea to be a singleton class
Here is an example of App usage
import android.app.Application;
public class MyApplication extends Application {
private static MyApplication instance = null;
public static MyApplication getInstance() {
return instance;
}
#Override
public void onCreate() {
if (instance == null) {
instance = this;
}
}
}
Access String in R
public class DummyClass {
private void getAppString(){
String r = MyApplication.getInstance().getString(R.string.app_name);
}
}

Best practice: family of classes with various type of configuration class [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am defining a family of classes used to get data from different sources (from example, a class will get data from a database, another one from a file, etc.)
Since the data sources are so different, there is no common interface for their configurations.
They all share a common method getData() though.
The idea was to define a set of predefined configurations (most of the time, the configurations used will just depend on a locale, thus there would one configuration for usa, one for france, etc.).
I have create the interface:
public interface IDataSource {
public void initialize(Object config);
public List<String> getData();
}
And the class DataSourceA:
public class DataSourceA implements IDataSource {
public void initialize(Object config) {
DataSourceAConfig configA = (DataSourceAConfig) config;
initializeA(configA);
}
public List<String> getData() {
...
}
private void initializeA(DataSourceAConfig config) {
...
}
}
and DataSourceB:
public class DataSourceB implements IDataSource {
public void initialize(Object config) {
DataSourceBConfig configB = (DataSourceBConfig) config;
initializeB(configB);
}
public List<String> getData() {
...
}
private void initializeA(DataSourceBConfig config) {
...
}
}
I am not happy with that solution (for example, using initialize(Object config), then cast the config). I am looking for advice on how to rethink the problem.
Edit:
I generated the configuration implementations using jaxb. Then the user would have to pass the type of data source and the name of the configuration file to the data source factory to get the data source.
Make an interface(abstract class) like DataSourceConfig. DataSourceAConfig and DataSourceBConfig will implement(extend) it. In your initialize method, you can replace Object with DataSourceConfig.
If your datasources are so different, you should change the IDataSource too:
public interface IDataSource<T extends DataSourceConfig> {
public void initialize(T config);
public List<String> getData();
}
DataSourceConfig will be the common interface and DataSourceB will implement IDataSource like this:
public class DataSourceB implements IDataSource<DataSourceBConfig> {
public void initialize(DataSourceBConfig config) {
initializeB(config);
}
// everything else omitted for simplicity
}

Categories

Resources