Category Archives: Week 3

Expose Your Ignorance

Just like the title says this week I have read the pattern “Expose Your Ignorance” from “Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman” by Dave Hoover and Adewale Oshineye. This pattern describes how any aspiring developer should put aside their ego and be able to tell other about not knowing something and ask questions. It is about being able to admit that we do not know something and to start learning even if it means showing others your “ignorance”.

As always with this book and its chapters this hits close to home when it come to me and my work experience, as well as school in that matter. I found it interesting because it really shows me that it is not only me who can struggle with this particular pattern. My boss always tells me and my teammates during any meeting or code review: “you owe me at least two questions”, and this is the part that is described well in this chapter as well. The author says: “The most obvious way to expose your ignorance is to ask questions.”. I agree wholeheartedly with this statement, we have to be able to ask questions even if it shows our ignorance on the subject, but the sooner something like that is out there the sooner we can work and fixing the problem as well as better working with the team, since they will know that we might need some help.

The only part of this pattern that I do not agree with all the way is the same one I just mentioned. In my opinion there is a place and time to ask questions to expose one’s ignorance, but there are also times when holding them back until later is the right decision. One such time is when working directly with a customer, a particularly tough or difficult one. Or when having a meeting with a lot of higher ups at a company and your development team. Question on the subject are usually good but ignorant questions can have some unforeseen consequences in these situations. Overall, I agree with this pattern and the idea about having a list of things you do not understand and to update it periodically is in my opinion a very good idea.

From the blog #CS@Worcester – Pawel’s CS Experience by Pawel Stypulkowski and used with permission of the author. All other rights reserved by the author.

Android Activities and Fragments: Getting Them Straight

AndroidX has brought a few changes to the Android framework, but the general architecture remains the same. Likewise, the few years since I’ve first learned Android has completely changed how I feel about Android. At this point, I am developing the basic architecture of my independent study app.

There are a lot of conflicting opinions about Activities and Fragments in the Android Developer community. A few years ago with my limited Android experience, I did not completely understand. I likely don’t completely understand now. However, I have better tools and more programming experience to see how they should be used, as well as to make my own decisions on how to use them.

At first, I found myself paralyzed with confusion on how Google wants its developers to use Activities and Fragments. As an example of how programming concepts translate well to other technologies, learning Angular helped me understand the difference. Activities are a single “thing” that a user does, and can be thought of as a web page. A Fragment should be used for a modular UI component, and function as Components do in Angular.

This isn’t a perfect analogy, as the frameworks are very different, but this is a good way to proceed when deciding how to structure your app. Google’s Introduction to App Architecture guide is a great explanation, and the most important thing to remember is to maintain a separation of concerns. In the end, Activities and Fragments aren’t a significant part of your app. They contain your app. They are something your app uses to work within the Android framework, and your business logic should be elsewhere because Android will pause or stop any Fragments or Activities it needs to if, for example, memory is running low. There is no guarantee they will maintain state unless you take additional steps to ensure it does so.

In researching opinions on how to use them, some people mentioned that they’ve seen developers decide on having a single Activity, and adding all features with Fragments. This is a tempting solution, but that might result in complex logic to control navigation. Furthermore, Fragments are meant to communicate through their parent Activity. In a large app, this would likely result in many implemented interfaces and complicated callbacks. Bloated Activities a big NO.

Likewise, others mentioned only using Activities and not adding complexity with Fragments. This seems a bit more reasonable, but restricts reusability of the Fragments in the UI. Only one Activity can run at a time. The beauty of Fragments is they can easily be dropped into a layout and reused. If they are designed to interact through their parent Activity, two Fragments can be shown at the same time on a larger tablet, even if they must be shown on different screens on a phone. Creating Activities only would mean either creating new Activities with repeated code for a tablet, or reusing the phone UI at the expense of user experience.

I’ll reiterate: separation of concerns. In Android, or any framework, understand the philosophy behind a class and component before deciding to try to simplify things. It’s likely that they were designed to prevent the problems you will run into.

From the blog CS@Worcester – Inquiries and Queries by James Young and used with permission of the author. All other rights reserved by the author.

Concrete Skills

I have furthered my reading in Chapter 2 of the Apprenticeship Patterns this time about Concrete Skills. With all the romanticism of being an Apprentice and obtaining the ability to learn quickly this chapter really tells the other side of that. It does pay to bring a level of enthusiasm for learning to a team but in order to be hired on a team you need a point of persuasion. This is when concrete skills come into play. Examples described in this chapter are things like a basic knowledge of various industry popular languages, frameworks, and a well developed understanding of your native language. Having these basic, or concrete skills, allow you to show some sort of way that you can benefit a team indirectly with basic tasks before you learn how to directly help.

This chapter addresses something I often think about. Some questions that run through my head, “What are the basic skills I need for getting my first job?”, “Am I expected to know what they are developing and how to contribute, or will they teach me?”. The truth is you can’t know about a development project before you are part of it. How things are done and what the scope is, will have to be learned as you go. Then my first question of what it is I need to know beforehand becomes more clear. My concrete skills need to be further developed, I need to explore more now at this stage in my career. 

I often feel the pull to my familiar skills when presented with a project. I need to use Java because that’s what I know, I need to use this IDE, I need to use this Database. However, it’s interesting as I read this book I see my development toward these goals presented in each chapter. The reading helps solidify my exploration into the unknown. The start of this semester I thought I would only use my most used IDE and the database I was used to using. As the semester got going I began to use a new IDE that seemed to better fit my interests after I took the step to get familiar with it. I also took the chance to learn about a new database application that better fit the needs of the project rather than catering to my familiarity. My next goal is to learn a basic understanding of a few more popular languages.

Developing these concrete skills is just as important as unleashing your enthusiasm for learning. Both are beneficial for a team but concrete skills will give you a practical use upon hiring.

From the blog cs@worcester – Zac's Blog by zloureiro and used with permission of the author. All other rights reserved by the author.

Craft Over Art: or how I learned to stop worrying and love my ugly UI

As I mentioned last week, I have a tendency to try to make products out of projects; meaning I can’t just have something to tinker with for fun, it needs to essentially be a rough draft for the actual project I have to work on. In the same vein, I have another hang-up on wanting things to be clean and pretty to start. Now, of course, one should strive for well formatted code following best practices, but specifically for those projects with a user interface I try to go straight to a finished product from the start. As a result, the Craft Over Art Pattern was illuminating, bringing into focus where my priorities should lie especially in contrast to where they are currently.

In sum, this pattern emphasizes that you have been charged with creating a functioning product, not necessarily a pretty one. The line, “the things we build for customers can be beautiful, but must be useful” says it all. I realize in constantly polishing a project before its feature complete, I end up throwing away a lot of work spent on “dolling up” features or elements of the user interface that may change or not even be used. I even caught myself making the same mistake even on a personal project using a different web application language, where I did not even attempt to make any forms or methods that communicated to the backend, instead spending time adding libraries for user interface elements that look nice and animate well. While there is certainly a place for those things, this pattern helps one understand that is when you have all of the parts of your application finalized.

I should have learned this lesson last semester with my final project. I spent so much time fiddling with the color palette and page animations, that the content on those pages was barren, or poorly formatted. It is nice, I think, that my webpage looks and animates nicely, but when pages break upon reloading then it hardly matters. If there is constantly some expectation of failure with a project, then the font you choose is hardly relevant. I think that is what this pattern helped me realize most about this weakness of mine; utility is the most important aspect of software, everything else is so much fluff.

From the blog CS@Worcester – Press Here for Worms by wurmpress and used with permission of the author. All other rights reserved by the author.

Apprenticeship Pattern Review 2: The Deep End

“The Deep End” is another extremely useful pattern taken from Apprenticeship PatternsThis pattern is best used when you feel as though you are stuck in a rut and not much progress is being made to further your software development career. In order to save yourself from a career of mediocrity something must be done. “The Deep End” prescribes the developer to set aside fear and jump into a project greater than anything they’ve done before. While this could end in failure, even failure is a better outcome than never starting in the first place since so much knowledge will be gained in the process. More often than not, it seems as though jumping into a project that seems too complex or too large when compared to previous work tends to be the best way to supercharge your learning.

I agree with this pattern wholeheartedly. I have already acquired countless examples in my relatively short career of software development where forgoing my fears and jumping into a project that I didn’t know I could complete helped me get out of a rut. One of the hardest things for me to remember is to keep jumping into “the deep end” whenever I can instead of getting into ruts of self doubt and fear. I also agree with Hoover and Oshineye that while this notion of “the deep end” is a key to becoming a software craftsman, one can not blindly jump into a project that is way beyond their comprehension and expect to swim. It is extremely important to take into consideration the prep work and skills at your disposal when deciding if an opportunity is right for you. While I do think the idea of recording the size of projects you have worked on could help when utilizing this pattern, I don’t think its necessary. Instead of getting bogged down by wondering if the project you want to work on is bigger or more complex than the last I think the most important thing is that you take the leap and start working on the projects that can propel your career forward.

This pattern will stick with me because I’ve seen it work in my own career previously, yet I’ve never had a concrete pattern to remind me of it. It will come in handy when I’m working on my capstone project. It’s imperative that I never let fear get the best of me and I instead choose to continue working through problems that I think there’s a possibility I fail at. I will keep this pattern close at all times and whenever I feel like declining an opportunity because of fear I will remind myself of “The Deep End”.

 

From the blog CS@Worcester – Your Friendly Neighborhood Programming Blog by John Pacheco and used with permission of the author. All other rights reserved by the author.

Confront Your Ignorance

This week, I’d like to discuss the next step from last week’s apprenticeship pattern. Once you’ve exposed your ignorance to others and realized it yourself, you have to own it and fix it. If others can’t help you, you’re on your own.

This pattern can be used in isolation, without showing others. This is helpful if it’s something very basic which would be embarrassing to admit to, or something you lied about knowing, which is never a good idea. The downside to learning on your own is an isolationist mindset. In a team where everyone is working on their own, this could create a culture where ignorance is frowned upon.

I generally agree with the ideas in this pattern. It is good to keep its downsides in mind, especially since I know I generally prefer to learn on my own. Sometimes, it is simply more efficient. In college, I’ve saved about 2 semesters’ worth of time (and money) by taking CLEP exams, learning the material on my own. For some subjects, it’s simply much more efficient to create my own study guide, find the gaps in my knowledge, and fill them in.

The result of doing so has been much clearer, broader, and more detailed understanding of the subject matter as a whole than I would have otherwise had taking a class. Taking a single exam held me more accountable than a class generally does, which is broken up into smaller assignments with the goal of preparing you for the final exam.

This would never be the case for learning to work on a software team, as we are in our software development capstone. Reading about Agile won’t make you an expert in Agile. Collaboration is a practice.

While not always ideal, I think this pattern can be extrapolated to professional applications. If you’re learning a technology on your own, you don’t know what someone might ask of you. The pressure is on to learn as much as you possibly can. If your goal is to appear as knowledgeable in a subject as possible, this pattern might be the way to go.

The warning against taking this pattern to the extreme is valid in cases of working with a team. It is important to use discretion when choosing between exposing ignorance to others, or confronting it on your own. I plan to lean toward exposing ignorance and asking for help in the future.

From the blog CS@Worcester – Inquiries and Queries by James Young and used with permission of the author. All other rights reserved by the author.

Understanding Continuous Integration and Continuous Delivery (CI/CD)

While good testing and version control habits are always helpful and save a lot of time, the process of committing changes, running tests, and deploying the changes can in itself be time consuming. This is especially true in an agile development process, which aims to make small, incremental changes in a series of sprints. Ideally, the process of committing, testing and delivering could be done in a single command.

This is where CI/CD comes in. An Oracle blog post on CI/CD describes the software development pipeline as being a four-step process: commit, build, automated tests, and deploy. CI/CD involves automating this process so that a single commit results in changes deployed to production, so long as the changes can be built and pass the tests. However, any of these stages can be skipped and not all of them have to be automated if it doesn’t make sense to do so. Additionally, other stages can be added if desired.

Oracle stresses the importance of testing in this process, and the requirement to have a suite of unit, integration, and systems tests. These are important to have for any project, but are vital if a commit is automatically deployed to production to make sure users are getting a reliable product.

Gitlab uses Runners to run the jobs defined in a file named “.gitlab-ci.yml”. Jobs can be defined in the stages mentioned above, or any arbitrary number of custom stages, to create a single pipeline. When a commit is made, the pipeline lists the stages and whether they pass. Of course, unit tests should be run before a commit to ensure that the code is behaving as expected, but once a change is committed the rest of pipeline can be automatic.

In large systems, this automation is especially useful. You may be not able to compile an entire code base on a local machine. You may not be working on the same schedule as the rest of your team. Automating other portions of testing and deployment allows a single developer to finish a feature or patch on their own and reliably get it into the hands of users.

In researching software engineering jobs, it seems that many companies use Docker as part of their CI/CD process. Imagine you want to make sure your software runs on Mac and Windows machines. Docker can use predefined images to build isolated containers in which the code can be run. A pipeline can contain separate build stages, for example, to make sure the code builds on both operating systems before running tests and deploying. Next week, I will look at Docker in more detail and describe how it can be applied to software testing.

From the blog CS@Worcester – Inquiries and Queries by ausausdauer and used with permission of the author. All other rights reserved by the author.

The Importance of Writing Well

Today I stumbled upon a blog post titled: Undervalued Software Engineering Skills: Writing Well by Gergely Orosz. That can be found here: https://blog.pragmaticengineer.com/on-writing-well/. I found this linked tangentially where the author was mentioning that in order to create clear diagrams that everyone can follow, honing your writing skills in general is one aspect of accomplishing that.

In this blog post, the author talks about how writing and communicating is a very under-appreciated skill that a software developer can have. I think that software devs have this stigma that they are not great communicators and maybe not particularly good with words, so this may be a surprise to some. However, writing well is the first step in creating diagrams that can be followed and amended by a team that is working on a project.

As someone that has worked in the corporate world for a long time with massive amounts of cross-communication between different departments, I can tell you that writing is something that people in every profession could stand to do better. Sometimes something as simple as communicating your thoughts precisely, concisely, and interestingly can be enough to get you noticed, even in a large corporate environment.

The author mentions that for a software dev, writing can be a tool to “influence engineers and other teams outside of your immediate peers.” He also frequently mentions durability, and how the better you are at writing, the more “durable” your decisions, trade-offs, and ideas will be. This will not only help your own career, but will help your team manager their project better.

I am pretty passionate about writing, and I think that in any career, having a grasp on good writing practices can make a huge difference for how you are perceived by your peers, and for a skill that is often seen as ancillary, can be a real game-changer.

From the blog CS@Worcester – Alan Birdgulch's Blog by cjsteinbrecher and used with permission of the author. All other rights reserved by the author.

SSSSSolid says the snake

SOLID is an acronym for a set of important design principles. Paired together they create a framework for worry free code, and by “worry free” I am speaking of code that would trouble you if any changes needed to be made. In the world today things are constantly changing and being updated and so should your code. If that’s the case then any code you write should have the ability to be edited without causing a complete overhaul of your whole program. Basically what you want to avoid is trickle down effects, and unlike trickle down economics, this is real. If you change one thing or responsibility of a class or variable and that causes a cascade of continuous changes and troubles, then you are experiencing this trickle down effect. To help with this issue is the first design principle in the acronym, Single Responsibility Principle.

Single Responsibility Principle is exactly what it sounds like. Give your classes and methods a sole responsibility so that if they are changed it will only effect that method or classes responsibility. If a class or method handles multiple responsibilities then changing the design of one part may be cause to change the entire entity. 

A crude example would be a Rectangle Class. Let us say you have a constructor to build a rectangle object and all it does is take arguments for height and width. However, you also add if and else statements in the constructor to see if the dimensions make a square and printing a confirmation message if it is. Perhaps you even write “if (myShape.isSquare())..” to send the object to a method to, but this is giving the constructor more than one responsibility. If you decide to change the placement of the square check then there will either be duplicated code or you will have to edit the constructor to pass the isSquare result to other methods. Doing any of this would result is test case changes if you were testing the code. In this scenario it is best to have the constructor just be the constructor and to dedicate the square check to its own method like isSquare. In this case if changes were made then only a single class would require changes and not several that are connected in a convoluted fashion.

I think the Single Responsibility Principle is a must know. I remember beginning coding is CS140 and Data Structures and I would try to get as much done in as few methods as possible by cramming in multiple functions into them. I thought the less methods the better but I was so wrong, it’s worth so much more to have many separate methods and classes that each have a sole function. This way code is organized, easy to arrange, and simple to implement or change.

SOLID Design Principles Explained: The Single Responsibility Principle. (2018, December 17). Retrieved from https://stackify.com/solid-design-principles/

From the blog cs@worcester – Zac's Blog by zloureiro and used with permission of the author. All other rights reserved by the author.

Digital Code apparently can smell.

How can code smell? This was my
question last class in my Software Architecture class, and I was surprised to
learn that it can. Not literally of course, but because code can be written in
a manner that somebody may say that there is something going bad in here, as
food would. According to Wikipedia
Code Smell is
: “any characteristic in the source code of a program that
possibly indicates a deeper problem” and “Code smells are usually not bugs;
they are not technically incorrect and do not prevent the program from
functioning. Instead, they indicate weaknesses in design that may slow down
development or increase the risk of bugs or failures in the future.” This is a
very interesting topic in my opinion because it can make me and other alike to
be a better coder and help us avoid common mistakes.

While searching for some more
information about the topic I have stumbled upon blog by Jeff Atwood that gives
and describes different kinds of smells that code can have. This directly related
to my class and helped me to specify different problems that can arise when I create
some software. In the class we have described smell in a little bit broader
scope then in the blog, which describes more detailed cases. For example,
Atwood gives us this: “Long Method – All other things being equal, a shorter
method is easier to read, easier to understand, and easier to troubleshoot.
Refactor long methods into smaller methods if you can.”, and in my opinion
anyone writing code nowadays can agree with that assessment. I know it can be
hard sometimes to write a short method because it would be more functional, and
that is a one of the subjects of one of my classes I took before about writing
clean code.

In my opinion this blog is a great reference
for everybody who wants to keep in mind problems that can arise, or to say avoid
you code from smelling a certain way. I know it will be helping me a lot both
in my school and professional life. Eventually anybody can learn this by heart
and know it  at the drop of a hat, but
for me until it will become almost a reflex I know I will be probably using
this post and other like it as a reference. Anybody who has plans to have a career
in a Computer Science field should learn this.

From the blog #CS@Worcester – Pawel’s CS Experience by Pawel Stypulkowski and used with permission of the author. All other rights reserved by the author.