Using "Adapter" pattern - java

How I understand, the Goal of the Adapter pattern is to call some class methods using some interface (which opened to clients). To make adapter pattern we need to implement some interface (which uses by client), and also we need to extend some class, which methods client need to call when calling interface methods.
class Adapter extends NeedClass implements PublicInterface{}
But what if we haven't interface, but have only 2 classes? For example we have some class(not interface!) which methods uses clients. Now we need to call methods of other class by making adapter class, but we cant to do this, because we cant make multiple Inheritance on the adapter class.
class Adapter extends NeedClass, PublicInterface
above code doesnt work.
What we can do in this case?

You can has an instance of NeedClass in Adapter and call it, when you need. So you extend only from PublicInterface.
public class Adapter extends PublicInterface {
private NeedClass needClass;
#Override
public void doSomething() {
needClass.doSomethingElse("someParameter");
}
}

You can use a composition instead of inheritance. Add a field to Adapter class of type NeedClass:
public class Adapter extends PublicInterface {
private NeedClass needClass;
}
Then inside Adapter methods delegate execution to needClass field.

From what i have understood the Adapter Pattern.
it is helpful when dealing with the third part codes such as API which is/ are subject to changes any time and my likely to break your code if implemented direct.
For example : Using Paypal in your site for payment online.let's assume the Paypal uses the method payMoney() for payment. and after sometime they decide to change the method to something else let's say sendMoney(). This is likely to break your code if implemented directly, with the use of Adapter Design pattern this can be solves as follow
the third part code => Paypal
class Paypal {
public function __construct(){
// their codes
}
public function payMoney($amount){
// the logic of validating
// the $amount variables and do the payment
}
}
so implement it directly in the code as below will break the code
$pay = new Paypal();
$pay->payMoney(200);
using adapter will save numbers of hours and a complex work of updating the code from payMoney() to sendMoney() in every where that the API scripts has been implemented. Adapter enable update in one place and that's it.
Let see it.
class paypalAdapter {
private $paypal;
// Paypal object into construct and check if it's pa
// Paypal object via type hint
public function __construct(PayPal $paypal) {
$this->paypal = $paypal;
}
// call the Paypal method in your own
//custom method that is to be
// implemented directly into your code
public function pay($amount) {
$this->paypal->payMoney($amount);
}
}
so it is like that and there you can go and use the PaypalAdater directly into the code as follow;
$pay = new PaypalAdapter(new Paypal);
$pay->pay(200);
So in future when the Vendor(Paypal) decide to use sendMoney instead of payMoney what to be done is to open the PaypalAdapter class and do the following in the pay($amount) method:
// SEE THIS METHOD ABOVE TO OBSERVE CHANGES
// FROM $this->paypal->payMoney($amount);
// TO $this->paypal->senMoney($amount);
public function pay($amount) {
$this->paypal->sendMoney($amount);
}
After this minor change in one place, everything works well as before.

Related

Use a generic type to pass a specific class

I'm very new to programming language. My question might not even make sense. My environment is using java and trying to implement both ios and android apps in the same automation testing framework.
So, the idea is that any test script should be able to run on both the apps. Ex: one signin test script should be run for both ios and android.
I've decided to use interface and class implementation approach. The problem I'm facing is with test data. My company doesn't want to use excel. They want to use json for test data.
Here's my problem, look at the following line of code:
ValidBuy goodBuy = JsonFileReader.loadDaTa(TestBase.DATA_PATH, "good-buy.json", ValidBuy.class);
As you can see I have a class "ValidBuy" that has all the getters for a particular json file. I have another class "JsonFileReader" which takes the json filePath, fileName, and a class as an input and returns the data for that class name that I passed in. For this example I've passed ValidBuy.class
So, when I run a positive test, I'm passing "goodBuy" variable which is of type "ValidBuy". The problem starts here.
The test case is now specified with the data from goodBuy because it's type is "ValidBuy" and I'm passing goodBuy as a parameter.
Look at one of my extracted methods:
private void enterBuyInfo(ValidBuy goodBuy) {
itemPage = nativeApp.getItemPage(goodBuy);
itemPage.setItemName(goodBuy.getItemName());
itemPage.setItemSize(goodBuy.getItemSize());
itemPage.setItemDigitSSN(goodBuy.getSsn());
itemPage.clickContinue();
}
You can see those getters I'm using are coming from ValidBuy class.
If I run this test with the data for a badBuy:
InvalidBuy badBuy = JsonFileReader.loadDaTa(TestBase.DATA_PATH, "bad-buy.json", InvalidBuy.class);
It fails because now I have to change "ValidBuy" class with "InvalidBuy" class. Since, changing the parameter in the extracted method in every run is not possible, how can I make it more generic?
I want something like this:
TestData data = JsonFileReader.loadDaTa(RESOURCES_PATH, "good-client.json", InvalidBuy.class);
Here, TestData is generic. It could either be a class or interface (I don't know if that's possible) and the return type will be specified by whichever class I pass into the loadData() method. In this case InvalidBuy.class
The extracted method should look like this:
private void enterBuyInfo(TestData data) {
itemPage = nativeApp.getItemPage(data);
itemPage.setItemName(data.getItemName());
itemPage.setItemSize(data.getItemSize());
itemPage.setItemDigitSSN(data.getSsn());
itemPage.clickContinue();
}
If I can do this, I can use those extracted methods to create more tests.
I know I wrote a lot. I've only tried to make it as clear as possible. If it doesn't make any sense, just disregard it.
Any suggestions, ideas, code samples will be highly appreciated.
Firstly let me see if I understand your question. I think you are saying that loadData may return a value of type ValidBuy or InvalidBuy and you want to pass into it the class that you want returned. You then want to know how to use an interface that might represent either of these classes in your test methods so you can test various return values (both valid and invalid). You use the term "generic" in your question but I'm guessing you don't mean to use it in the specific way it's used in Java.
If I've understood your question correctly, then here's an answer:
Passing the class you wish to have returned into a method is an unusual usage and almost certainly not ideal. Better OOD would be to extract the common methods for all objects returned from loadData into an interface.
So:
interface Buy {
String getItemName();
boolean isValid();
}
class ValidBuy implements Buy {
#Override
public boolean isValid() {
return true;
}
...
}
class InvalidBuy implements Buy {
#Override
public boolean isValid() {
return false;
}
...
}
class JsonFileReader {
Buy loadData(Path path) {
...
}
}
Then your tests can look like:
#Test
void testValidBuy() {
assertTrue(reader.loadData(validPath).isvalid());
}
#Test
void testInvalidBuy() {
assertFalse(reader.loadData(invalidPath).isValid());
}
I realise I've simplified it a bit but hopefully you get the idea.

Java - Send a method as parameter and decide if there is need to call it

I am currently making an app and I am implementing cache in it. The thing is the DAOs are implemented in another service.
The idea that I had, to avoid code repeating, is having a generic cache in my service. Then, acording to the method called it verifies the respective cache and, in case it doesn't exist, calls the DAO associated with the method passed as parameter. Is there any way to do this?
NOTE: I am using java 1.6 in my application
I suppose you need an Adapter pattern. Naive realisation could be
class AdapterA implements Adapter<A> {
private A;
#Override
public void getValue() { return getA();}
}
and then when you get instance of A, B or C you wrap it in appropriate Adapter. Later you could call just getValue regardless specific type under hood.
Another approach. I would be grateful if someone say what the pattern is (possibly Proxy?):
class ProxyImpl implements Proxy {
#Override
public void doAction(<? extends DAO> dao) {
if (dao instance of A) { ((A)dao).getA()
} else if (dao instance of B) { ((B)dao).getB()

Is there any standard way to transform object to different object?

I'm having a special case where I have implemented builder pattern. One of the variable is of type ExternalClassA, Where as the parameter passed to builder is of type InternalClassA. Currently I have used a method something like below:
Class Parent {
String variableX;
int variableY;
ExternalZ variableZ;
public static builder {
....
ExternalZ varz;
/* .. builder logic */
private builder withExternalZ(InternalZ internalZ) { //This is the transform method I'm using currently
this.variableZ.getSomeObject().setX(this.internalZ.getSomeObject().getX()); //Similar kind of lines making my transform method look ugly
}
}
Is there any way to make my withExternalZ method look simpler? Currently I'm thinking either to implement Mapper pattern or Java8 Function (As explained in http://www.leveluplunch.com/java/tutorials/016-transform-object-class-into-another-type-java8/). Mapper seems not a good choice as I only need one way conversion.
If anyone has better and simpler approach, kindly share.
Currently you are passing an InternalZ instance to withExternalZ() method which actually needs\expects an ExternalZ object.But what you have in hand is an InternalZ method.
Adapter pattern is built for such scenarios as it adapts/converts the target interface(InternalZ) to the client expected one (ExternalZ). In short you need to write an adapter which converts from InternalZ to ExternalZ object. Adapter class code will roughly be along the following lines -
public class IntToExtZAdapter extends ExternalZ{
InternalZ internalZ=null;
public IntToExtZAdapter(InternalZ internalZ){
this.internalZ=internalZ;
}
public X getX(){
//Logic for getting X from internalZ object in adapter
}
public setX(X x){
//Logic for setting X in internalZ object in adapter
}
//...and so on
}
Then instead of doing this -
private builder withExternalZ(InternalZ internalZ) { //This is the transform method I'm using currently
this.variableZ.getSomeObject().setX(this.internalZ.getSomeObject().getX()); //Similar kind of lines making my transform method look ugly
}
What you now do is -
this.variableZ=new IntToExtZAdapter (internalZ);
Now you can use variableZ as it is and internally IntToExtZAdapter will adapt/convert from InternalZ to ExternalZ and back.
All the "ugly" logic of converting back and forth from InternalZ to ExternalZ and vice-a-versa is now "hidden" inside the adapter.
What do you mean when you say mapper? which design pattern is that?
The data mapper I'm familiar with are explicitly used for persistent storage as described by Martin fowler.
Anyways I think you can use a variation of the Decorator pattern without adding functionality. Assuming you can derive from the ExternalZ and override the getters you can create a class which wraps the InternalZ class.
class ExternalZOverInternalZ extends ExternalZ {
private final InternalZ internalZ;
ExternalZOverInternalZ(InternalZ internalZ) {
this.interalZ = internalZ;
}
#Override
public int getX() {
return internalZ.getX();
}
}
If you have the possibility to add dependencies to your project, guava from google is a good option, it provides Functions (like Java 8) in older versions of Java
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Function.html
You can add it to maven with
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>

Can we mock a method in service while testing the service itself?

I am working on a project where I am using MyBatis annotations as persistence framework. Therefore, I have to create an interface for the 'mapper' and compose the mapper in the service like :
class XYZServiceImpl{
public XYZMapper getXYZMapper(){
return SessionUtil.getSqlSession().getMapper(XYZMapper.class)
}
}
Now while unit testing the service with Mockito, I am trying to inject a mock for the mapper. But since I am injecting mock in an instance of XYZService, how can mock a method of the service itself, in this case getXYZMapper() is what I am trying to stub. Although I have got a solution of creating the instance XYZMapper in the service and not call on demand like the above code does something like :
Class XYZServiceImpl{
XYZMapper mapper;
public void useXYZMapper(){
mapper = SessionUtil.getSqlSession().getMapper(XYZMapper.class);
}
}
But that would bring a lot of code changes (ofcourse I can refactor) but is there a way to achieve without having to make code changes?
Also what would be a 'purist' way to have a mapper instance in the class is it the method 1 that is better than method 2 in terms of performance?
EDIT : Here XYZMapper is an interface. Something like :
public interface XYZMapper{
#Select("SELECT * FROM someclass WHERE id = #{id}")
public SomeClass getSomeClass(int id);
}
EDIT : I am facing a similar situation but with a variance that I have a service that I do want to test like XYZServiceImpl. Now it has a method getXYZDetails() which has a lot of business logic handled within the service. Now if getXYZDetails looks like the following :
public XYZDetails getXYZDetails(int id){
XYZDetails details = new XYZDetails();
details.set1Details(fetchSet1Details(id));
//Perform some business logic
details.set2Details(fetchSet2Details(id));
if(details.set2Details() != null){
for(int i = 0; i < details.set2Details().size(); i++){
flushTheseDetails(i);
}
}
.
.
}
Kindly notice that fetchSet1Details(), fetchSet2Details(), flushTheseDetails are public service, public and private service respectively.
I want to know of a method that can mock/stub these methods while testing getXYZDetails() thus enabling me to
There are several options you can use.
Inject dependency
This works only for simple methods like getXYZMapper when method only returns external dependency of you object. This may require to create new XYZServiceImpl instances if for example mapper is bound to connection which is opened per request.
Encapsulate method behavior in object
Another way to achieve similar result is to use a factory or service locator
like this:
public class XYZServiceImpl {
public XYZServiceImpl(XYZMapperFactory mapperFactory) {
this.mapperFactory = mapperFactory;
}
public XYZMapper getXYZMapper() {
return mapperFactory.getMapper();
}
}
This will allow you easily substitute factory in test with implementation which returns mock mapper.
The similar approach can be used for other methods fetchSet1Details, fetchSet2Details, flushTheseDetails that is moving them to other class or classes. If the method contains complex (and may be loosely related) logic it is a good candidate to be moved in separate class. Think about what these methods do. Usually you can move some essential and unrelated part of them to other class or classes and this makes mocking them much easier.
Subclass
This is not recommended but in legacy code sometimes is very helpful as a temporary solution.
In your test subclass you class under test and override methods you need:
#Test
public void someTest() {
XYZServiceImpl sut = new XYZServiceImpl() {
public XYZMapper getXYZMapper() {
return mapperMock;
}
public Whatever fetchSet1Details() {
return whateverYouNeedInTest;
}
}
sut.invokeMethodUnderTest();
}
The only thing you may need to do is to change access modifier of private method to package-private or protected so you can override them.
Spying
This method in also discouraged but you can use mockito spies:
XYZServiceImpl realService = new XYZServiceImpl();
XYZServiceImpl spy = Mockito.spy(realService);
when(spy.fetchSet1Details()).thenReturn(whaeveryouneed);
when(spy.getXYZMapper()).thenReturn(mockMapper);
spy.methodUnderTest();
I would suggest the "purist" way of doing this is to accept an XYZMapper instance in your constructor and store it in a local field.
In production use, you can pass an e.g. SQLXYZMapper, which will interact with your database. In test use, you can pass in a mocked object that you can verify interactions with.

How not to expose a public interface in Java

In my project jOOQ, I model SQL queries with a complex data structure. All components of a query implement
public interface QueryPart {
int bind(java.sql.PreparedStatement stmt);
int bind(java.sql.PreparedStatement stmt, int initialIndex);
SQLDialect getDialect();
String toSQLDeclaration();
String toSQLDeclaration(boolean inlineParameters);
String toSQLReference();
String toSQLReference(boolean inlineParameters);
}
This interface's methods are used internally by all packages of the library to construct and execute SQL. They should not be invoked directly from client code. For that purpose, I have added
public interface QueryPartProvider {
QueryPart getQueryPart();
}
Which is the only publicly exposed interface. An example of an actual query part is:
public interface Table extends QueryPartProvider {}
class TableImpl implements QueryPart, Table {}
As you can see, the QueryPart methods can only be accessed via Table.getQueryPart().toSQLDeclaration(), etc.
My design helps discouraging direct access to QueryPart methods, but cannot completely hide it. My question is: Can anyone tell me a good design pattern to achieve this goal?
Note: The simplest but not very nice solution would be to cast all objects to QueryPart, e.g. ((QueryPart) table).toSQLDeclaration()
All methods of an interface are always public, so there is no way for you to have access to something which is not accessible to your library clients as well.
Maybe you could achieve what you want using an abstract class for Table, and the getQueryPart() method as package protected. I'm not sure however that I would want to do that, instead of a cast from Table to TableImpl.
After implementing something similar to what sfussenegger suggested, I came up with an even better solution involving the Adapter design pattern. This is the general outline:
/**
* Objects providing an internal API implement this interface
*/
public interface Adapter {
/**
* Dynamically expose an (publicly unknown) internal API.
*/
<T> T internalAPI(Class<T> internalType) throws ClassCastException;
}
This adapter type is the only fact exposed to the public about anything internal. Only package private implementation methods know about the possible arguments to this method (and those hackers that really want to actually use the internal API for workarounds, extensions, etc).
/**
* This type contains the public API for a QueryPart
*/
public interface QueryPart extends Adapter {
// [...]
}
/**
* This type contains the internal API for a QueryPart
*/
public interface QueryPartInternal extends QueryPart {
// [...]
}
The above QueryPart and QueryPartInternal are related. This fact is known to public but no public class / type extends QueryPartInternal. Only the following package-private class and its gazillion subclasses do:
/**
* This class is the base class for all QueryParts.
* It is package private and thus doesn't expose anything
*/
abstract class AbstractQueryPart implements QueryPartInternal {
// [...]
/**
* For other package private implementation methods
*/
#Override
public final <T> internalAPI(Class<T> internalType) {
return internalType.cast(this);
}
/**
* Convenience method for subclasses heavily using the
* internal API
*/
protected final QueryPartInternal internal(QueryPart part) {
return part.internalAPI(QueryPartInternal.class);
}
// [...]
}
Could you please explain why you'd like to do that? The only reason I can see is to make it impossible to implement the interface for a user of your library.
I don't think that's a good approach. Simply add some Javadoc and explain why it doesn't make sense to implement it. But finally, leave it to the user whether there's a valid reason to create a custom implementation. It's always difficult to foresee each and every use case.
If somebody gots stuck with his approach it's certainly not your fault - he can't say he hasn't been warned :)
To give an example, that's what you can find all over Apache Wicket's source code:
/**
* THIS IS WICKET INTERNAL ONLY. DO NOT USE IT.
*
* Traverses all behaviors and calls ...
*/
EDIT:
just another though: you could try this, although I'd still discourage it - don't say you haven't been warned ;)
public interface ExposedInterface {
void foo();
}
// only default visibility
interface InternalInterface extends ExposedInterface {
// nothing here
}
// and here some methods
ExposedInterface get(); // user can use it
void set(InternalInterface obj); // user is out of luck here

Categories