5

I currently work on a hobby project which I use to learn more about Android/Java programming and programming in general. Recently, I decided to integrate jUnit into the project. Just getting it in there wasn't much of a problem, but actually using it was. I've read that a unit test should be the definition of what a method (or component) is supposed to do, and that unit tests force you to write good, or at least better code.

But the problems started occurring the moment I wrote the first unit test to test some logic. The method I wanted to test does only logical work, nothing with the UI is done and the results are simply saved in variables for later use. But, in the same class, I have a method to display whatever the first method has worked out. And jUnit doesn't seem to like that; for the second method I need (of course) UI imports, and jUnit complains that it doesn't know any "Android Context class". Until now, I thought that putting the logical and UI parts of a component in one class but seperated methods would be easily understandable and an acceptable practice. But now, because "jUnit forces you to write good code", I'm much less sure about this.

So, should I put the UI and logical parts for one component in seperate classes? They depend on each other, the UI method needs the values from the logical method, but the logical method can't do anything with its computed values without the UI method. But because someone else might think different about this... And that "someone else" is the one who probably has to understand my code somedays afterall.

5

UI design patterns like Model-View-Controller, Model-View-Presenter and Model-View-ViewModel routinely provide mechanisms (i.e. separate classes) that allow Separation of Concerns between the surface of the UI and the class that manages it, for the same reasons that you've already cited.

  • A good, standard answer, but I'd add that these patterns are so successful that there are three confusing variations of them. :-( – user949300 Nov 27 '16 at 0:52
  • These patterns raise a whole lot of questions. Can/should I use them everywhere or just for some components? What about the main method, can it also follow such a pattern? – Namnodorel Nov 27 '16 at 7:02
  • 1
    @Namnodorel. Due to the goal here is learning, don't you worry too much. Read the links above, choose one and try to implement it. For the sake of the coherence of the code, apply the pattern to your whole UI. Even if It's a single method class. Even if it doesn't have logic at all. Just try it, get practice, compare results among the implementations. Just enjoy by the pleausure of learning. If during the process you have any specific question or doubt about any of the patterns, search a little if you don't find answers out there, come here and ask :-) – Laiv Nov 27 '16 at 10:10
5

If this is a hobby project you have a wonderful opportunity to learn here.

I encourage you to keep you design the way it is. Don't move logic out of the ui. Don't separate at all.

Instead start another project that does the same thing. This time separate ui and logic. Keep the behavior of both projects the same.

You'll notice that the separated design is a lot more work for the same behavior. This is always true. So you might think this separation business is a waist of your time. If the story ends here, it is.

Next design a whole new GUI. Maybe in a different IDE. Maybe make a text based version. Now, of the two projects, in which is it easier to make these changes?

The point of solving problems with software rather then hardware is that software is easier to change. Don't write your code in a style that makes me think I might as well have hired an electrical engineer to solve it.


I don't know if it would be a good idea to rewrite the whole thing instead of seperating the classes... I've worked on this project for about halve a year now, so it would be either a lot of copy + pasting from the old project, or a whoooooollleee lot of work. – Namnodorel

If the project is that big it might be smarter to write a small exploratory project. Take a smaller feature, say a single screen from your hobby project or one that will eventually be part of it, and create a separated version of it. This way you don't have to wait for the whole conversion to get some feedback to tell you if you like the idea. Keep in mind this won't be easy. You'll be coding against what you're used to. It will probably take time just to get used to reading this kind of code.

MVC is a fine thing to study but it won't give you a clear plan since it's really just about seperating 3 concerns not about how those concerns talk to each other. Also, be careful of your assumptions. The separation isn't just into three classes. You can write classes that handle each little part of the three concerns.

Look at the observer pattern to see the event way to talk between them. The Observer pattern taught me more about event driven programming than anything else.

Look at n tier architecture to see how to separate multiple classes into layers of concerns. Also good lessons along those lines in ports and adapters, and clean architecture.

There's a lot to learn here and plenty of places to fall off and give up. Just don't stop just because it's hard. But don't just use it on faith. Make each idea prove it's worth to you.

  • I don't know if it would be a good idea to rewrite the whole thing instead of seperating the classes... I've worked on this project for about halve a year now, so it would be either a lot of copy + pasting from the old project, or a whoooooollleee lot of work. – Namnodorel Nov 27 '16 at 6:52
  • Make a second workspace, do a copy of the project in the new workspace. Refactor the new project instead the current one (separe logic from the ui). Then compare the projects and see which one is easier to test, scale up, maintain, etc... – Laiv Nov 27 '16 at 9:56
  • I am always impressed by your answers and your willingness to help others learn. – Thomas Carlisle Oct 30 '17 at 13:12
  • @ThomasCarlisle why thank you. : ) That's so nice to hear. – candied_orange Nov 2 '17 at 23:21
2

TL;DR

Yes, you should.


  • A class should only have one reason to change.
  • If the logic must be adjusted, your class has a reason to change
  • If the UI needs changing, your class has another reason to change
  • So your class has two reasons to change
  • That's undesirable for a lot of reasons.
  • That's called Single Responsability Principle.
  • One of the problems of not following the SRP is that business logic is more difficult to test (what is hapenning to you).
  • Another disadvantage of having UI logic and business logic in the same class is that you will have to test things that have not changed (or that you think have not changed). When you edit the class to change the UI color, you now have to test the class again in case you broke something (software is like that). If you had separated UI and BL you wouldn't need to test the BL. Your business logic class has not been modified.

That said, if that is a hobby project you shouldn't worry too much about maintainability and testability, but the fact that you are puting jUnit into the coctail says that you want to learn more and do things better that just a simple hobby. So start applying the principles that make software more maintainable and testable. jUnit is a professional tool and as such it demands some standards.

  • Hm, ok... But isn't it kind of an anti-pattern if I have a class which basically just holds one method that is ever called? (There may be more methods, but they wouldn't be called by anything but the main method, and they're not always there) – Namnodorel Nov 26 '16 at 23:22
  • @Namnodorel: Um, did you see my answer about MVC, MVP and MVVM? Your technique is not exactly without precedent. – Robert Harvey Nov 26 '16 at 23:35
  • A class can have one method or a hundred, as long as the class ramins cohesive and has just one concern. (Maybe if it has a hundred methods, there is some design flaw though). The main method is the entry point of an application, most classes shouldn't have a man method. – Tulains Córdova Nov 26 '16 at 23:38
  • @RobertHarvey I did, however I did not look it all up yet because I thought it would be a longer read ;) – Namnodorel Nov 26 '16 at 23:46
  • 1
    @Namnodorel: If you're merely looking for reassurance, my word ought to be enough. Otherwise, you might spend a few minutes reviewing those Wikipedia articles. – Robert Harvey Nov 26 '16 at 23:47
-4

You can use a Server/Client architecture to separate logic(Server) and UI(Client).

See this tool : http://rock.s.architecture.free.fr/

  • 1
    Are you honestly suggesting writing a C++ server and communicating with it over CORBA to implement an Android app?! – Sean Burton Oct 30 '17 at 15:21
  • Please add some detail in your answer. As it is now, this answer is little more that a random link and a comment. – Jay Elston Oct 30 '17 at 20:51
  • CORBA is a strong technology to do this : see the link and you'll can see it's very easy to use : you'll get a skeleton of an entire Server/Client without knowing about CORBA. I use it on ubuntu. I'm sure it can be used on androïd also – benur29 Nov 1 '17 at 8:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.