Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks.
On December 04 2017 15:17 Blisse wrote: Use a dependency injection framework and keep the Account object alive as long as the user is logged in.
I've been reading about dependency injection for the last little bit and I fail to see how it lets me implement a session any differently than just creating a regular object would. Could you clarify that?
It simplifies creating and passing objects around. For example in spring you can just say you need an Accaunt objected, and if there is one bean of that it will automatically get there. The initial idea was to have everything in interfaces so you could inject the preferred implementation which would also help with testing. And you would just let the dependency injection framework create and passed the actual object.
I don't know if you can use spring in Android, because I only did a single small app once. But your case is simple, (assuming annotation config) in the classes you need the account, just declare it as an instace variable and annotate with @Autowired. Then you just need to provide the creation mechanism. If you Account has an empty constructor (or every dependency can be autowired) you can just anotate the class with @component, otherwise you have to provide a method annotated with @bean responsible to create it. This is a monky patch. It's full of crap because I don't know your application. Don't do what I said, instead understand how it works with this example. You should check out the scope of the object, and if you are using DI it's probably better to organize everything with it. Think about what should be a bean what should not. Take good care of dependency stuff. Some people will claim that field injection in java is shit. The reason are only historic and being weird having something setting a private field. With mordern test frameworks the only real reaon against field injection is that it's easier to detect that you have too many dependencies using constructor injection.
On December 04 2017 15:17 Blisse wrote: Use a dependency injection framework and keep the Account object alive as long as the user is logged in.
I've been reading about dependency injection for the last little bit and I fail to see how it lets me implement a session any differently than just creating a regular object would. Could you clarify that?
Are you unsure about dependency injection or dependency injection as it relates to scoping?
Just got this Google coding challenge terminal thing in the browser, it's weird.
More unsure of how dependency injection works as a framework. I understand at its basis DI is just passing an object you depend on in, instead of directly depending on it. I suppose knowing how it works as a framework is the real challenge.
On December 04 2017 15:17 Blisse wrote: Use a dependency injection framework and keep the Account object alive as long as the user is logged in.
I've been reading about dependency injection for the last little bit and I fail to see how it lets me implement a session any differently than just creating a regular object would. Could you clarify that?
It simplifies creating and passing objects around. For example in spring you can just say you need an Accaunt objected, and if there is one bean of that it will automatically get there. The initial idea was to have everything in interfaces so you could inject the preferred implementation which would also help with testing. And you would just let the dependency injection framework create and passed the actual object.
I don't know if you can use spring in Android, because I only did a single small app once. But your case is simple, (assuming annotation config) in the classes you need the account, just declare it as an instace variable and annotate with @Autowired. Then you just need to provide the creation mechanism. If you Account has an empty constructor (or every dependency can be autowired) you can just anotate the class with @component, otherwise you have to provide a method annotated with @bean responsible to create it. This is a monky patch. It's full of crap because I don't know your application. Don't do what I said, instead understand how it works with this example. You should check out the scope of the object, and if you are using DI it's probably better to organize everything with it. Think about what should be a bean what should not. Take good care of dependency stuff. Some people will claim that field injection in java is shit. The reason are only historic and being weird having something setting a private field. With mordern test frameworks the only real reaon against field injection is that it's easier to detect that you have too many dependencies using constructor injection.
Thanks for the info. I know you can't use Spring on Android because you can't use Beans(for some reason).
A quick google search gave GUICE as a DI framework for android.
But you rarely should need the same global state everywhere. Try to see if you can isolate classes from that dependency.
And I sugest everyone to read Build Maintainable Software by the SIG guys. It's a pretty entry level and straight foward book but is well written, straight to the point and points out opposite views. And applies to pretty much any project. By following that book rulea you eventually end up following more complex ones by intuition. 10 extremely simple rules! All you need.
Dagger 2 and GUICE were the main recommendations I read elsewhere, so thank you for giving more strength to those recommendations.
I'm finding it very hard to understand Patterns and concepts like DI. I understand that they make your code more flexible and maintainable. I've worked maintenance at a bank for the last 1.5 years so I understand why that's important. I find it hard to relate what these cerebral concepts are supposed to accomplish to concrete improvements in my code. Is it something you need to be on the maintaining end of to understand fully?
No. DI is actuctually pretty simple to understand. You specify how to create objects and their scope, and the framework will create them for you. And them you don't need to pass them around, you can just use an inject/autowire annotation and the framework does it for you. With this you no longer need to have code to instanciate your objects, DI framewok will find and create the objects you need. Suddendly spotting the 'new' keyword in your code gets rare. In web Backends it makes your LOCs go down a lot. And if you use interfaces you can easily switch objects that you are injecting. Most frameworks also support naming objects/beans if you need more than one object of!a kind alive and the type system is not enough.
A simple DI framework with just the basic features is very simple to implement, with either the old system of a xml file to inject stuff, or the more recent java annotations ones. But big frameworks like spring have lots of stuff like injecting private fields and have a huge amount of configurations.
On December 06 2017 13:38 WarSame wrote: Dagger 2 and GUICE were the main recommendations I read elsewhere, so thank you for giving more strength to those recommendations.
I'm finding it very hard to understand Patterns and concepts like DI. I understand that they make your code more flexible and maintainable. I've worked maintenance at a bank for the last 1.5 years so I understand why that's important. I find it hard to relate what these cerebral concepts are supposed to accomplish to concrete improvements in my code. Is it something you need to be on the maintaining end of to understand fully?
Maybe this helps. I don't think it matters that the examples are in JS.
On December 04 2017 13:55 WarSame wrote: That video is pretty good.
Say I have a class in Android, Account, instanced to represent the current user's account. This shows up everywhere. I could pass it through Intents. I could put it in a subclassed Application. I could used Shared Preferences. If we assume that just about every activity will need it what is the best approach?
This was the original question. It seems pretty simple. I'm not quite sure why you'd want to load what seems to be quite a heavy framework to solve something as simple as passing around an Account object. Especially as the problem isn't with dependency boondoggles, it's specifically about accounts in Android. And the Android framework already provides the AccountManager to deal with that.
What exactly you need the account for is a more interesting question. If all you want is to get locally stored user data, there are better solutions. If it's to sync to some clould service, you definitely want to use the Android account manager, and probably a SyncAdapter.
Just got this Google coding challenge terminal thing in the browser, it's weird.
If that's like while doing a Google search, it can result in a job.
Or at least a job interview.
I've already been flown out and interviewed and rejected by Google, twice :cries:
My excuse is, I didn't want to work there anyways!
"Hahaha ;D;D you thought I wanted 2 work there? ur so stupid I was just folling round no one wants a shit job leik that you cuck I hope the company is run over by a car!" *secretly cries inside*
I'm sure you know this, but I've just followed a pseudo-code algorithm for quicksort (it's almost copy/paste). It took 11 seconds to populate a vector with 1,000,000 numbers and to sort it in debug. How about std::sort? 3 seconds. So, just use your library's algorithms. I've only done this to see to check quicksort algorithm though.
That said, I didn't use the same vector but I don't doubt std::sort is faster anyway.
Also, what quicksort did you use? The most basic, or a variant?
I don't know what language that is, but some languages it's really really hard to beat the standard sort algorithm. It may be the case that your standard sort changes approach based on the circumstances.
On December 04 2017 13:55 WarSame wrote: That video is pretty good.
Say I have a class in Android, Account, instanced to represent the current user's account. This shows up everywhere. I could pass it through Intents. I could put it in a subclassed Application. I could used Shared Preferences. If we assume that just about every activity will need it what is the best approach?
This was the original question. It seems pretty simple. I'm not quite sure why you'd want to load what seems to be quite a heavy framework to solve something as simple as passing around an Account object. Especially as the problem isn't with dependency boondoggles, it's specifically about accounts in Android. And the Android framework already provides the AccountManager to deal with that.
What exactly you need the account for is a more interesting question. If all you want is to get locally stored user data, there are better solutions. If it's to sync to some clould service, you definitely want to use the Android account manager, and probably a SyncAdapter.
Yes, it is a local account. It doesn't sound like AccountManager is what I want. For now I've just stuffed it into a Session static variable. After I get to a place where I'm happy with my project I'll post the github link and ask for feedback. There are a few specific sections of my app that I think are weak and I'm hungry to improve my coding.
First and foremost. Stop using dependency injection with inversion of control. It's just a bad idea for a cluster fuck. While people state all the "advantages" of dependency injection, they don't state the disadvantages.
Here are great reasons not to use it: 1) If you are using a compiled time program, - Why go from a compile time error to a runtime error? You aren't able to reason about the behavior of your program.
2) How many times have you really switched out an implementation of an object? I am being serious. How many times?
3) It creates bad code - I want a dependency, let me see, someone created this object for me that will have a part of what I need. Let me just bring in their dependency and all their extra garbage with it. Remember, you are not going to be the person looking at this code in the future and modifying it, so any methods and objects are fair game to be misused.
4) Object construction is actually necessary to write elegant code. Just because you can make something into an object doesn't mean it should be an object.
5) Dependency Injection Magic - Significant amount of the times, people spend time figuring out the nuances of the DI framework instead of their actual code.
What you should learn instead. 1. Data structures 2. Algorithms 3. Functional Programming
As someone has stated. Dependency Injection with IoC is just a simple idea. It is a class that has a HashMap with a simple interface, provide it a key, you get back a value. To construct the value, the value needs to know about all its dependencies. This means every object is a vertex and the edges represent a dependency. This really means that you have a Directed Acyclical Graph (DAG). To create an object, you just have to topologically sort the DAG and create the objects in order to initialize your intended object.
If you feel like this idea is valuable to you, use it, otherwise, don't use it.
Second, you should know about all the fundamental sorting algorithms and how they work if you want to be a serious programmer. You should also learn the idiosyncrasies of the sorting library that is given by the framework. It is detrimental to think you should only use the framework when other steps can be taken to speed up your specific goal.
On December 07 2017 15:10 Neshapotamus wrote: I can't believe all the bad advice I'm hearing.
First and foremost. Stop using dependency injection with inversion of control. It's just a bad idea for a cluster fuck. While people state all the "advantages" of dependency injection, they don't state the disadvantages.
Here are great reasons not to use it:
1) If you are using a compiled time program, - Why go from a compile time error to a runtime error? You aren't able to reason about the behavior of your program.
How does dependency injection change whether an error is compile time vs runtime errors in the slightest?
Why does it inhibit your ability to reason about your program? I would argue the opposite, that it clarifies in the intent of your program because each dependency is explicitly laid out at a single point in your class.
2) How many times have you really switched out an implementation of an object? I am being serious. How many times?
You don't need to switch the implementation of an object to realize the benefits of dependency injection. But you can.
We use it every day, because at the highest level, different build flavours use different implementations of the same classes. At a lower level, it allows us to switch between mock, staging and production endpoints at run-time.
3) It creates bad code - I want a dependency, let me see, someone created this object for me that will have a part of what I need. Let me just bring in their dependency and all their extra garbage with it. Remember, you are not going to be the person looking at this code in the future and modifying it, so any methods and objects are fair game to be misused.
This is an empty statement. Your code can always be misused. In fact, it's the other way around. Injecting allows you to establish an explicit contract that this feature will depend on this other feature. If you want to scope down a dependency, expose it as a separate interface, which can also be injected.
4) Object construction is actually necessary to write elegant code. Just because you can make something into an object doesn't mean it should be an object.
These two sentences contradict each other? I'm not sure what is the point being made.
There is absolutely object construction when using DI. Not sure where you get the idea that you shouldn't make objects when you have a DI framework.
5) Dependency Injection Magic - Significant amount of the times, people spend time figuring out the nuances of the DI framework instead of their actual code.
In the opposite manner, people spend too much time thinking about their code and not about how it lives in the framework of the application they are writing. Once the framework is set up, DI is invisible. Annotate and put in the constructor and be done for the majority of cases, really until you want to swap implementations, which is a feature of DI, not the core.
If DI doesn't work, it's almost always that it was written with another intent in mind. Or maybe it's just wrong. Scoped DI allows you to clarify the intent of where the object lives.
I don't disagree that DI is complicated. It is ridiculous hyperbole to suggest DI is "just a bad idea for a cluster fuck" though.
On December 06 2017 13:38 WarSame wrote: Dagger 2 and GUICE were the main recommendations I read elsewhere, so thank you for giving more strength to those recommendations.
I'm finding it very hard to understand Patterns and concepts like DI. I understand that they make your code more flexible and maintainable. I've worked maintenance at a bank for the last 1.5 years so I understand why that's important. I find it hard to relate what these cerebral concepts are supposed to accomplish to concrete improvements in my code. Is it something you need to be on the maintaining end of to understand fully?
Sorry I didn't respond quickly, busy with work. DI is just one solution for some problems with its own set of inherent advantages (and disadvantages) that might not fit with how you envision software development, and might cause more pain because the frameworks are not perfect (though one could say that about almost anything in Android...). Keeping these objects in the Application, in the Activity, and managing that complexity yourself is perfectly valid. It's easy to think about planning ahead, but you aren't going to need it (YAGNI). That being said, DI is a big thing in Android and used by many companies.
Want to differentiate between DI and DI framework, I'll be talking more of DI as a framework, as DI by itself is just as though you had a smarter Factory.
Just to run through DI, ignore words like flexible and maintainable, those terms are too abstract IMO. Same thing with stuff like decoupling.
IMO the most important advantage of IOC and DI, is that it allows you to reason about your classes in a clearer way.
Day-to-day, your classes exist in a sea of other classes. Your classes consume the behaviors of other classes that live upstream, and provide your own behaviors downstream.
With DI, your object's constructor explicitly states all the other classes and behaviors your class consumes. This allows you to easily say that your class depends on the functionality of all these other classes. You don't really care about what these classes are or where they came from, but you care that these classes implicitly provide a "contract" about their functionality, in their public methods.
If your code is very mindful of this "contract" of public methods, then when you write a class, you can rely on any of these upstream dependencies, and simply use them. And then downstream, you can compose multiple classes in such a way, without caring about why the class exists and in what space, only that they provide the functionality that you expect. And DI lets you enforce this non-caring aspect, no need to deal with creating and managing your upstream and downstream dependencies, just inject them.
There are other benefits to scoping with DI, like being able to enforce and make assumptions about the persistence of a class.
Testing classes with this form of IOC looks similar to this idea of contracts. All I'm really testing for with mocks is that classes enforce the contract I'm expecting. i.e. the send() function actually makes a (mock) network call, that these functions actually modify the state in a way I expect, without caring where the function call is coming from.
Note that you can use DI with concrete classes, not just interfaces.
On December 06 2017 13:38 WarSame wrote: Dagger 2 and GUICE were the main recommendations I read elsewhere, so thank you for giving more strength to those recommendations.
I'm finding it very hard to understand Patterns and concepts like DI. I understand that they make your code more flexible and maintainable. I've worked maintenance at a bank for the last 1.5 years so I understand why that's important. I find it hard to relate what these cerebral concepts are supposed to accomplish to concrete improvements in my code. Is it something you need to be on the maintaining end of to understand fully?
Sorry I didn't respond quickly, busy with work. DI is just one solution for some problems with its own set of inherent advantages (and disadvantages) that might not fit with how you envision software development, and might cause more pain because the frameworks are not perfect (though one could say that about almost anything in Android...). Keeping these objects in the Application, in the Activity, and managing that complexity yourself is perfectly valid. It's easy to think about planning ahead, but you aren't going to need it (YAGNI). That being said, DI is a big thing in Android and used by many companies.
Want to differentiate between DI and DI framework, I'll be talking more of DI as a framework, as DI by itself is just as though you had a smarter Factory.
Just to run through DI, ignore words like flexible and maintainable, those terms are too abstract IMO. Same thing with stuff like decoupling.
IMO the most important advantage of IOC and DI, is that it allows you to reason about your classes in a clearer way.
Day-to-day, your classes exist in a sea of other classes. Your classes consume the behaviors of other classes that live upstream, and provide your own behaviors downstream.
With DI, your object's constructor explicitly states all the other classes and behaviors your class consumes. This allows you to easily say that your class depends on the functionality of all these other classes. You don't really care about what these classes are or where they came from, but you care that these classes implicitly provide a "contract" about their functionality, in their public methods.
If your code is very mindful of this "contract" of public methods, then when you write a class, you can rely on any of these upstream dependencies, and simply use them. And then downstream, you can compose multiple classes in such a way, without caring about why the class exists and in what space, only that they provide the functionality that you expect. And DI lets you enforce this non-caring aspect, no need to deal with creating and managing your upstream and downstream dependencies, just inject them.
There are other benefits to scoping with DI, like being able to enforce and make assumptions about the persistence of a class.
Testing classes with this form of IOC looks similar to this idea of contracts. All I'm really testing for with mocks is that classes enforce the contract I'm expecting. i.e. the send() function actually makes a (mock) network call, that these functions actually modify the state in a way I expect, without caring where the function call is coming from.
Note that you can use DI with concrete classes, not just interfaces.
Nowhere did I say DI is not a useful design pattern, but it is not a solution to the very specific problem warsame was having.
That said you seem to be attributing many advantages of interface based design (something that Java almost forces upon you, and Android definitely takes seriously) to dependency injection.
Unless I misunderstood what you're trying to say.
@warsame: if all you need is a single local account, accessible only to your app, then sharedpreferences is a perfectly good place to store that profile information and make it accessible throughout your app. If you have multiple local accounts, then there are better solutions.
On December 07 2017 09:39 travis wrote: What do you mean by "release"?
Also, what quicksort did you use? The most basic, or a variant?
I don't know what language that is, but some languages it's really really hard to beat the standard sort algorithm. It may be the case that your standard sort changes approach based on the circumstances.
Executables and library files could usually be output in two configurations - release (optimised) and debug (less optimised/unoptimised). For obvious reasons, you're meant to give release versions to customers because they run faster.
Back to your question about quicksort, this is the pseudo-code that I've followed. It's almost "as-is", I just had to make a few changes so it compiles. I believe it's basic quicksort. The language I use is C++.
for (size_t i = low + 1; i < high; ++i) { if (arr[i] < pivot) { std::swap(arr[i], arr[leftwall]); leftwall += 1; } }
std::swap(pivot, arr[leftwall]);
return leftwall; }
If you have a std::vector<int>, then you sort it as follows:
quicksort(array, 0, array.size());
To others: I've not bothered to polish code too much, I'm sure it could be improved. I'm just interested in algorithm itself. I also know about std::sort but this is just for educational purposes.
Edit: Wow, C++ gives you a lot of helper functions you need to implement algorithms on your own. Just to name a few:
std::swap std::make_heap - max-heap data structure std::shuffle std::partition std::merge