A simple example:
I got three methods [A & B & C], and their relationship is easy. In A method it calls B; in B method it calls C. So if I draw on paper it looks like:
A
B
C
I would like to make the "code" itself can clearly reveal this relationship so that as we read the code we can understand "how they call each other" in a big picture. Rather than we keep doing "find usage" or something else.
I know it's a little bit hard since we sometimes can not force [B only be accessible by A] and [C only accessible by B]. ( Although we can actually make it by inner class, but if there're only three methods it's a little bit pain for creating three classes. )
The way I now try to achieve this is to make the "method name" somehow reveals their relationship. But it is not a really realistic way to do it.
Apart from how can this be implemented in Java, does any other programming language have this kind of feature? I would also really like to know how does the mechanism implemented.
Many thanks for any advice or response.
It seems to me that you should realize the reason why you want to split this the code on three methods.
If you can create these three methods A, B, C in one single class and make B and C methods private, so this makes you sure that nothing will call B and C outside your class.
But if your goal is to make some restrictions inside the class, so maybe it's better to keep A, B, C as a single method, because in Java you can't restrict methods in such way.
Is possible to create such kind of relationship only passing B as parameter to A and C as parameter to C.
This can be accomplished with lambda expressions since Java 8 or with anonym classes prior java 8.
Other systems are not possible because you can't be sure that other methods can't call it.
Functional languages handle that very well. Here is an example using javascript:
var a = function(fn) {
// Do something
fn();
}
var b = function(fn) {
// Do something
fn();
}
var c = function() {
// Do something
}
// To call it
a(b(c));
Note that this solution define the relationship between a, b and c at execution time of the code a(b(c))
In java this is more difficult to do (prior of lambda expressions):
public interface Command {
public void execute();
}
public class X {
public void a(Command comm) {
// Do something
comm.execute();
}
public void b(Command comm) {
// Do something
comm.execute();
}
public void c() {
// Do something
}
}
final X x = new X();
x.a(new Command() {
public void execute() {
x.b(new Command() {
public void execute() {
x.c();
}
});
}
});
Related
So basically what this thread boils down to is that I want some private methods to just represent a block of code inside another method. I'm aware of how scoping works in Java but there are times where I wish things worked differently:
Suppose I have a method doLotsOfStuff() in my class that does more than one thing. Naturally one would divide the things into several methods doThis() and doThat() of type VOID. You encounter problems of this kind:
1) I can no longer operate on any data defined in doLotsOfStuff() in either doThis() and doThat() without first passing all the necessary arguments needed, which would not make them void! For example doThis(int doLotsOfStuffsInt) This means that if I want a chain of calls, the same variable must be passed along throughout in a line of arguments. ..which leads to this:
2) doThis() and doThat() set as private would still be visible for all other methods in the same class, even though I just want to use them for doLotsOfStuff(). Having a long chain of sub methods that are only meant to be used a single time will now clutter up the whole Class.
Here is what I wish existed:
a,b,c,d are private methods in the same class. The -> indicates a call to a method.
a() -> b() -> c()
c() can use variables from a() or b() freely without passing the arguments around down the chain.
d() -/-> c()
c() cannot be called by d() as c() is only "local" to a() and any of its subsequent callers.
Consider the short example:
private void someMethod()
{
char a = 'a';
printA();
}
private void printA() {
System.out.println(a); //a cannot resolve, but I don't want to pass it as an argument from someMethod()!
}
Is there a way to achieve this, without having to pass a as an argument? Some sort of declaration in the lines of
"private void printA() dependson someMethod"?
Wouldn't this be a good functionality to have? If not, why? How would you do it?
What you are looking for is called Closure scoping:
Closures are not natively supported in Java and honestly not very elegant to imitate. This ability is native in most dynamic languages like Groovy or JavaScript
A Closure captures the variables in a scope of its definition.
If you use final references you can refer to them in inner classes and mimic the behavior of data hiding in a Closurewith an inner class.
Q32766010.java
public class Q32766010
{
public static void main(final String[] args)
{
final Example e = new Example();
e.doSomething(23,42);
}
public static class Example
{
public void doSomething(final int a, final int b)
{
class ClosureLikeThing {
ClosureLikeThing doThis() { System.out.println("a = " + a); return this; }
ClosureLikeThing doThat() { System.out.println("b = " + b); return this; }
}
new ClosureLikeThing().doThis().doThat();
}
}
}
Outputs
a = 23
b = 42
This hides the inner details from the public interface.
This will do the data/method hiding you are looking for. It is a
Method Object pattern implementation of sorts and might trip up new programmers because it is not used very often in Java. This kind of inner class usage is prevalent in more dynamic languages like Python, JavaScript and Ruby.
This can help declutter your code in a good IDE that supports code folding. If you set your IDE to fold all inner classes it will make the source less
noisy.
More lines of code is not always bad, if you make it easier to automatically refactor something using a tool like Intellij IDEA easier then more lines of code is better because it can be maintained automatically.
A few more lines of code to narrow the scope of something is almost always better. The narrower the scope the less side effects that are possible and the easier to maintain and debug because what effects that code and what that code effects are minimal and explicitly obvious because of the narrow scope.
This idiom is used in Java mostly for things like Iterator and FluentBuilder pattern implementations to hide the details of the implementation. Here is an example 'UrlBuilder'.
Alternative using Interfaces if you have multiple implementations:
This works the same way but will allow you to create multiple implementations if you need different behavior from the same Interface.
public static class Example
{
interface ClosureLikeThing
{
public ClosureLikeThing doThis();
public ClosureLikeThing doThat();
}
public void doSomething(final int a, final int b)
{
new ClosureLikeThing()
{
#Override
public ClosureLikeThing doThis()
{
System.out.println("a = " + a);
return this;
}
#Override
public ClosureLikeThing doThat()
{
System.out.println("b = " + b);
return this;
}
}.doThis().doThat();
}
}
If a method is so complex that even splitting it in sub methods and passing arguments clutters up the class, it's probably a good sign that you need to delegate to another stateful class.
For example:
private void someMethod() {
ComplexPrinter printer = ComplexPrinter('a');
printer.foo();
printer.bar();
printer.baz();
}
Or at least, to avoid passing too many arguments to each method, to store them in a single context object:
private void someMethod() {
PrintContext context = PrintContext('a', 'b', 'c', 'd', 'e');
foo(context);
bar(context);
baz(context);
}
Based on Seelenvirtuose's comment:
You can create a "method object", to whose constructor you pass all the arguments, which you can then use freely in any of its methods:
Suppose you have:
public class SomeClass
{
private void someMethod()
{
char a = 'a';
char b = 'b';
char c = 'c';
System.out.println(a);
/* Lots of code here */
System.out.println(b);
/* More lots of more code here */
System.out.println(c);
}
}
You could turn it into:
public class SomeClass
{
private void someMethod()
{
LongMethod lm = new LongMethod('a', 'b', 'c');
lm.printA();
lm.printB();
lm.printC();
}
private static class LongMethod
{
private char a;
private char b;
private char c;
public LongMethod(char a, char b, char c)
{
this.a = a;
this.b = b;
this.c = c;
}
public void printA()
{
/* A third of a lot of code here */
System.out.println(a);
}
public void printB()
{
/* A third of a lot of code here */
System.out.println(b);
}
public void printC()
{
/* A third of a lot of code here */
System.out.println(c);
}
}
}
What you are proposing goes against the paradigm in most programming languages called scope.
The reason the method exists is to encapsulate a piece of functionality of a larger program to make it understandable and re-usable.
It is good to break up a big method to make it understandable (even if you only call the method once), but if you find yourself needing access to lots of variables in the original big method, I would question if it is really necessary to break it up.
If the language allowed methods to access variables in other methods, it would become a nightmare to keep track of what is going on in your program.
I found this funny analogy on the wikipedia article and I think it applies well here.
Imagine that you have a really nice collection of tools—really nice.
Now imagine that you decide to lend your tools to any neighbor who
asks. Unless you have exceptional neighbors, you will probably find it
necessary to modify this policy eventually because some of those tools
will end up broken and others will disappear forever without a trace.
Is there some object oriented thing that you can call some methods from certain classes, but not all of them? Is there something like that which is similiar to protected?
Say you have a method void foo() and you want it to be available to the programmer in a few types of classes (perhaps something like using Type variables (to specify: T type). Now, perhaps is there some way, without inheriting the class with foo() in it, or making an interface, to specify which classes or types of classes have access to that method?
I would guess this could be like multiple-inheritance and polymorphism? But I still want only the class and certain classes to access the method without changing the visibility of the method. I want the visibility to be class-specific.
Here is an example:
class A sees foo() as private, but only that class sees it as private.
class B sees foo() as public/protected, but only that class sees it as public.
The method type would be default.
I guess what is easier to ask and answer to is: "Is there class-specific visibility?"
There is something like you are asking for in C++, it is called friend classes. Nevertheless, that concept is not supported by Java:
'Friends' equivalent for Java?
A second option is to use code reflection to access a class private members but it isn't such a clean solution and only works for protected elements:
public class C1 {
public C1()
{
x = "Hello Word!";
}
protected String x;
}
At a different class's method:
String val = (String)obj.getClass().getDeclaredField("x").get(obj);
System.out.println("val: " + val);
EDIT: After making a little bit of research I found it is possible even to access private members:
Field field = obj.getClass().getDeclaredField("x");
field.setAccessible(true);
String val = (String)field.get(obj);
field.setAccessible(false);
No, there's nothing like that in Java.
The closest you've got is putting classes within the same package, at which point they have access to any members which don't specify any access modifier. You can't specify particular classes though.
Another option which is appropriate in some cases is to use nested classes:
class Outer {
private static class Inner {
}
}
Here Outer and Inner have access to each other's private members.
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
thats your lot, there are not any other access modifiers.
With a little sleight of hand you can make one class seem to be two different classes:
// An interface.
interface A {
public void a ();
}
// Another interface.
interface B {
public void b ();
}
// Deliberately NOT stating we implement either A or B but actually we implement both.
class C {
public void a () {
}
public void b () {
}
}
// Pick either implementation from C and tell the world about it.
class D extends C implements A {
// Do nothing - already done by C.
}
class E extends C implements B {
// Do nothing - already done by C.
}
public void test() {
A d = new D();
B e = new E();
}
Here D and E are actually identically functioned objects because they are both actually Cs. However, as they are created they are made to seem to be A or B which are two different interfaces.
Unfortunately we cannot hide the fact that they both extend C but a little further sleight of hand and we can do that too with a Factory.
// Hide the guts of it all in a factory.
static class Factory {
// Make sure you MUST use the factory methods.
private Factory () {
}
// Construct an A.
public static A newA () {
return new D();
}
// Construct a B.
public static B newB () {
return new E();
}
}
Here's what i remembered:
In C++, if derived class defines a member function with the same name, but different signature (parameter etc) than the base class, it'll 'hide' the corresponding member function in base. e.g.
class Base {
public:
void virtual f(double x);
};
class Derived : public Base {
public:
void f(char c);
};
int main()
{
Derived* d = new Derived();
Base* b = d;
b->f(65.3); // call f(double x)
d->f(65.3); // call f(char c)
delete d;
return 0;
}
correct me if i am wrong, but i think in C++ by saying 'hide', it also means Derived class can not see 'f(double x)', or in other words, Derived do not have 'f(double x)' as its inherited member function from Base, correct?
In Java tutorial, 'hide' actually means something else (for static class method), whereas for instance method, you can overload the method inherited from base. Looking at this example: Using inherited overloaded methods
public class ClassA {
public void method(Number n) {
System.out.println("ClassA: " + n + " " + n.getClass());
}
}
public class ClassB extends ClassA {
public void method(Integer d) {
System.out.println("ClassB: " + d + " " + d.getClass());
}
}
ClassA a = new ClassB();
a.method(3);
In C++ type of thinking, i would get the same result that 'method(Number n)' from Class A is called, based on 'dynamic binding' and 'hiding' idea in C++, but:
I am still not sure how to explain it in Java. The link itself explains using 'method signature is chosen at compile time' and 'it is actually calling from Class B'; but in C++ thinking, the former is OK, but i do not think it's calling from Class B, it should be calling from Class A, right?
In Using inherited overloaded methods and Java tutorial, 'Class B' is allowed to overload function from 'Class A', and 'Class B' actually can see both 'method(Number n)' and 'method(Integer d)'. So C++ and Java are treating overloading differently, right? And why is that? Say in the C++ example, if Derived also allow overloading, 'd->f(65.3)' would call 'f(double x)', not 'f(char c)'.
Thanks,
In C++ every thing is static for non-virtual functions, so for non-virtual functions you don't have dynamic-binding. And hiding do not remove function from inheritance. It's something like this:
When you define method M as: void M(int) then compiler implement a function internally name Base::M as void Base::M( Base* this, int ). Now this function is implemented somewhere in code and can't removed and you can call it as long as you be able to provide a this (actually you can call it without even having this). So in Child I can call Base::M(0); and C++ convert this from Child* to Base* and call M. When you define a function with its name correspond to the name of base class you tell the compiler that I prefer to use that name in my class for a new method or property! But you don't remove any thing and you can use using to bring old definition of M to Child:
struct Base {
void f( int ) {}
};
struct Child : Base {
void f( char* ) {}
using Base::f; // Bring Base::f to this class, so I have f(char*), f(int)
};
And beside that you can call f(int) without even use of using.
// In the Child class
void test() {
Base::f('c'); // Call Base::f(char)
}
// Outside of class
Child c;
((Base*)&c)->f('1');
This is not how I would expect C++ to behave. Rather than hiding the base class method, I would expect the subclass to simply overload the method because the parameters are different. Thus, the compiler will know which method to use when you call b->f() because there's only one available, but it has to work out which one to use when you call d->f() based in your parameter type. If it can't then at compile time you will be forced to use a cast. With your example it should recognise the decimal point and use double instead if char.
I have a kind of specific problem, let's say, that I have
public interface A {
}
//------------------------------
public class B implements A {
static int countx = 0;
}
//----------------------------------
public class C implements A {
static int county = 0;
}
//----------------------------------
public class Arc {
public A from;
public A to;
//========================================
and now I have an object a (which is an instance of Arc) and I want to find out whether it is an instance of B or C and get to the atributes countX or countY (stg like a.from.countX)
any ideas? :)
I think you could use instanceof to solve this issue
as in
if(a instanceof B) return a.countx
if(a instanceof C) return a.county
Your current design is not good from the OOP standpoint. You need some encapsulation and polymorphism. In an OOP language, you don't explicitly check for the type of an object, you arrange for that to happen automatically via dynamic dispatch. So whatever data you need from both B and C, add a method to the interface A that will get that data and then implement the method in B and C accordingly. Also, don't use public instance fields, that breaks encapuslation.
Use instanceof and a typecast:
if (a.from instanceof B) {
B b = (B)a.from;
b.countx;
}
Edit: But you should really not need such a thing! If you do, you can probably redesign it to not produce ugly code like this.
For example you could let your interface A have a method getCount() and let your classes B and C implement these, by returning countx or county.
Edit2: I just noticed that your countx and county members are static! Why would you do that? static means, that they don't "act" upon instances of your class but on your class object (they are "class members"). This means that you can access and modify these variables everywhere by accessing them through A.countx or B.county; you most probably don't want this, because multiple instances of class A will share the same countx!
If you have an object that is an instance of Arc, then how is it also an instance of B or C? I feel like your code is flawed and needs restructuring. For example, as Tudor pointed out, "There is no relation between the classes Arc and A in your hierarchy."
If you simply want to have information about the classes :
getClass().getSuperclass()
Regards,
Erwald
Think about it like this :
What makes me want to discriminate between a B and a C ? Is it an operation? If so, just implement those operations appropriately in B vs C and let dynamic dispatch take care of the rest.
interface Operation {
public Result operate(String[] args);
}
class A implements Operation {
#Override
public Result operate(String[] args) {
//I need to do some special calculations for an A...
for(String arg : args) {
}
.
.
.
}
}
class B implements Operation {
#Override
public Result operate(String[] args) {
//i know this does nothing so return the empty result
return Result.EMPTY;
}
}
Resist the tempation to use instanceof. In most cases you don't need it - and its not OO.
When using Mockito, I only use it to mock out dependencies, i.e. my workflow looks mostly like this:
I have a class with dependencies:
public class C {
public C (A a, B b) {
this.a = a;
this.b = b;
}
public String fooBar() {
return a.foo() + b.bar();
}
}
In my test class, I mock out those dependencies, and tell them which values to return when some specified methods are called:
public class CSpec {
private A a = mock(A.class);
private B b = mock(B.class);
#Test
public itShouldReturnFooBar() {
when(a.foo()).thenReturn("foo");
when(b.bar()).thenReturn("bar");
C c = new C(a, b);
assertThat(c.fooBar().isEqualTo("foobar"));
}
}
(I hope this example is not too simple or too derived ;-)). This works fine, it allows me to test classes (here: C) in isolation. Still, I never use Mockito's verify methods or any other of its features. Is it okay / sufficient to use Mockito this way?
Verify would be typically used to check that your C really calls the A.foo() and B.bar() methods. So you could add
verify(a).foo();
verify(b).foo();
before or after the assertThat. I don't think you need or should use them here but there are several situations where you would need that:
a or b does something that is not visible / reachable from c's public API (for example logging)
You are concerned with the order of execution
You want to make sure that only a.foo and b.bar methods are called, nothing else like a.foo2
You could use those mocks as spy's, so that call to a.foo would be then routed to the aReal.foo
The verify approach is particularly useful in a Tell Don't Ask style of programming.
Consider the following version of your class C:
public class C {
public C(A a, B b, CListener L) { ... }
...
public void foobar() {
String result = complexPrivateMethod(a, b);
L.fooBarred(result);
}
}
Thus, rather than just computing the result, you inform some interested party (e.g. a user interface) about the result.
To test foobar now, you'd want to verify that the listener is correctly invoked:
public class CTest {
#Mock CListener mockListener;
...
#Test itShouldTellCAboutFooBar() {
C c = new C(stubbedA, stubbedB, mockedListener);
...
verify(mockedListener).fooBarred("foobar");
}
}
This use of verify is typical for Test-Driven Development: See Freeman & Pryce's Growing Object-Oriented Software Guided by Tests.
Thus, if you want to use the full potential of Mockito (the question), you most of all need to adopt the corresponding design philosophy in your code.
Yeah, there's no problem with this test, it's perfectly fine. The simple fact the the stubs are being used make the test working, if you remove or change the stubs then the test won't work.
Adding verify statements will just make things redundant in this kind of tests.
However if you precisely want to verify arguments, the order or number of interactions or something else then you definitely want to add checks on the interactions between the tested object and his collaborators.
It is totally ok to use Mockito just this way. But if your code gets more complex you need to do some more things to get your code tested as simple as possible.
Another small example:
public void eitherAorB() {
if(somethingIsTrue) {
a.doSomething();
} else {
b.doSomethingElse();
}
}
You might want to make sure, that the expected method is called on the expected object.
#Test
public doSomethingShouldBeCalledOnA() {
A a = mock(A.class);
C c = new C(a, new B());
c.setSomeThingIsTrue(true);
eitherAorB();
verify(a).doSomething();
}
#Test
public doSomethingElseShouldBeCalledOnB() {
B b = mock(B.class);
C c = new C(new A(), b);
c.setSomeThingIsTrue(false);
eitherAorB();
verify(b).doSomethingElse();
}
In other cases you might want to know which paramater was passed into a method. For that you need an ArgumentCaptor.
Or in some cases you need to call the actual method or use an actual object (no mock), so it is time to spy on an object and capture arguments or verify behavior.
So there is a lot more to Mockito you might need once in a while.
The answers given so far are good, but there are additional features you didn't mention either. The #Mock, #Spy, #InjectMocks annotations are all very useful. Along with the verify(...) methods, there is also the InOrder class to help verify the order of method calls. And perhaps you use the matcher methods already (<T> any(T t), anyString(), etc), but you don't show that you use those facilities.