Tag Archives: refactoring

Refactoring: 4 Key Principles

I believe in refactoring.  The Agile Manifesto holds that

The best architectures, requirements and designs emerge from self-organizing teams.

The quality of our software systems depends on refactoring.  In fact, I believe that the only way that an organization can avoid refactoring is by going out of business.  Maybe I should explain that.

Refactor or Die

Heart Monitor Flatline - Refactoring or DeathEvery software system that we build is inside a dynamic environment.  The organization(s) using the software are all in a state of constant change.  The people using the software are also constantly changing.  Due to this constant change, every software system needs to be adapted to the environment in which it is used.  Most of the time, businesses think of this constant change in terms of new features and enhancements – the scope of functionality that a system can handle.  Less commonly, businesses think of this change in terms of the obvious external qualities and attributes of the system such as performance or security.  But almost never does an organization, from a business perspective, think of the invisible qualities of the software system such as simplicity and technical excellence.

What happens when the business does not recognize those invisible qualities?  I’m sure almost every software developer reading this can answer this question easily: the system becomes “crufty”, hard to maintain, bug-prone, costly to change, maze-like, complex.  Some people refer to this as legacy code or technical debt.

The longer this state is allowed to continue, the more it costs to add new features – the stuff that the business really cares about.  It is pretty easy to see how this works – for someone who has a technical background.  But for those without a technical background it can be hard to understand.  Here is a little analogy to help out.

Imagine that you set up a system for giving allowance to your kids.  In this system, every week your kids have to fill out a simple form that has their name, the amount that they are requesting, and their signature.  After a few weeks of doing this, you realize that it would be helpful to have the date on the form.  You do this so that you can enter their allowance payments in your personal bookkeeping records.  Then you decide that you need to add a spot for you to counter-sign so that the paper becomes a legal record of the allowance payment.  Then your kids want extra allowance for a special outing.  So you add some things on the form to allow them to make these special requests.  Your accountant tells you that some portions of your kids allowance might be good to track for tax purposes.  So, the form gets expanded to have fields for the several different possible uses that are beneficial to your taxes.  Your form is getting quite complex by this point.  Your kids start making other requests like to be paid by cheque or direct-deposit instead of in cash or to be paid advances against future allowances.  Every new situation adds complexity to the form.  The form expands over multiple pages.  Filling out the form weekly starts to take significant time for each child and for you to review them.  You realize that in numerous places on the form it would be more efficient to ask for information in a different way, but you’re not sure if it will have tax implications, so you decide not to make the changes… yet.  You decide you need your own checklist to make sure that the forms are being filled out correctly.  A new tax law means that you could claim some refunds if you have some additional information… and it can be applied retroactively, so you ask your kids to help transcribe all the old versions of the form into the latest version.  It takes three days, and there is lots of guess-work.  Your allowance tracking forms have become a bureaucratic nightmare.

The forms and their handling is what software developers have to deal with on a daily basis – and the business usually doesn’t give time to do that simplification step.  The difference is that in software development there are tools, techniques and skills that allow your developers to maintain a system so that it doesn’t get into that nightmare state.

For a more in-deth description of this process of systems gradually becoming more and more difficult to improve, please see these two excellent articles by Kane Mar:

Technical Debt and Design Death

Technical Debt and Design Death: Part II

Ultimately, a software system can become so crufty that it costs more to add features than the business benefit of adding those features.  If the business has the capacity, it is usually at this point that the business makes a hard decision: let’s re-write the system from scratch.

I used the word “decision” in that last sentence.  What are the other options in that decision?  Ignoring the problem might be okay for a while longer: if the company is still getting benefit from the operation of the system, then this can go on for quite a while.  Throwing more bodies at the system can seem to help for a bit, but there are rapidly diminishing returns on that approach (see The Mythical Man-Month for details).  At some point, however, another threshold is reached: the cost of maintaining the operation of the system grows to the point where it is more expensive than the operational value of the system.  Again, the business can make a hard decision, but it is in a worse place to do so: to replace the system (either by re-writing or buying a packaged solution), but without the operating margin to fund the replacement.

In his articles, Kane Mar describes this like so:

It’s pretty clear that a company in this situation has some difficult decisions ahead. There may be some temporary solution that would allow [a company] to use the existing system while building a new product, [A company] may decide to borrow money to fund the rewrite, or [a company] may want to consider returning any remaining value to their shareholders.

In other words, refactor or die.

Refactoring and Business

Refactoring and Business Success - Growth ChartIn the Scrum Master and Product Owner classes that we teach, this topic comes up frequently: how does the business account for refactoring?  How do we “govern” it?  How do we make good decisions about refactoring?

There are a few principles that are important in helping to answer these questions.  All of these principles assume that we are talking about refactoring in an Agile team using a framework like Scrum, OpenAgile, or Kanban.

Refactoring Principle One: Keep It Small

Refactoring is safest and cheapest when it is done in many small increments rather than in large batches.  The worst extreme is the complete system re-write refactoring.  The best refactoring activities take seconds or minutes to execute.  Small refactorings create a constant modest “overhead” in the work of the team.  This overhead then becomes a natural part of the pace of the team.

Not all refactoring moves can be kept so small.  For example, upgrading a component or module from a third party might show that your system has many dependencies on that module.  In this case, efforts should be made to allow your system to use both the old and the new versions of the component simultaneously.  This allows your system to be partially refactored.  In other words, to break a large refactoring into many small refactorings.  This, in turn, may force you to refactor your system to be more modular in its dependencies.

Another common problem with keeping refactorings small is the re-write problem.  Your own system may have a major component that needs to be re-written.  Again, finding creative technical means to allow for incremental refactoring of the component is crucial.  This can often mean having temporary structures in your system to allow for the old and new parts to work harmoniously.  One system that I was working on had to have two separate database platforms with some shared data in order to enable this “bi-modal” operation.

Refactoring Principle Two: Business Catalysts

When is the earliest that a refactoring should be done? Not whenever the technical team wants to do it.  Instead, the technical team needs to use business requests as catalysts for refactoring.  If the business needs a new feature, then refactoring should only be done on those parts of the system that are required to enable that feature.  In other words, don’t refactor the whole user interface, just refactor the parts that relate to the specific business request.

Again, there can be exceptions to doing this… but only in the sense that some refactorings might be delayed until a later date.  This is tricky: we want to make sure that we are not accumulating technical debt or creating legacy code.  So, instead, we need to allow the technical team to refactor when they detect duplication.  Duplication of code, data or structure in the system.  A business request might impact a particular part of the system and the team sees how it might be necessary to refactor a large swath of the system as a result.  But, the cost of doing so is not yet justified: the single request is not enough of a catalyst, and the team can also choose a simple temporary solution.  Later, the business makes another request that also implies the same large refactoring.  Now is the time to seriously consider it.  It is now a question of duplication of another simple temporary solution. The business may not be happy with the extra expense of the large refactoring so the principle of keeping it small still applies.  However, the technical team must also be willing to push back to the business under the right circumstances.

Refactoring Principle Three: Team Cohesion

Teamwork in Agile requires high levels of communication and collaboration.  In refactoring work, teamwork applies just as much as in any other activity.  Here, it is critical that all members of the team have a unified understanding of the principles and purpose of refactoring.  But that is just the first level of team cohesion around refactoring.

The next level of team cohesion comes in the tools, techniques and practices that a team uses in refactoring.  Examples include the unit testing frameworks, the mocking frameworks, the automation provided by development tools, continuous integration, and perhaps most importantly, the team working agreements about standard objectives of refactoring.  This last idea is best expressed by the concept of refactoring to patterns.

The highest level of team cohesion in refactoring comes from collective code ownership and trust.  Usually, this is built from practices such as pair programming or mob programming.  These practices create deep levels of shared understanding among team members.  This shared understanding leads to self-organizing behaviour in which team members make independent decisions that they know the other team members will support.  It also impacts research and learning processes so that teams can do experiments and try alternatives quickly.  All of which leads to the ability to do refactoring, large and small, quickly and without fear.

Refactoring Principle Four: Transparency

In many ways, this is the simplest refactoring principle: the team needs to be completely open and honest with all stakeholders about the cost of refactoring.  This can be difficult at first.  Another analogy helps to see the value of this.  A surgeon does not hide the fact that care is put into creating a clean operating environment: washing hands, sterilizing instruments, wearing face masks and hair covers, restricted spaces, etc.  In fact, all of those things contribute to the cost of surgery.  A surgeon is a professional who has solid reasons for doing all those things and is open about the need for them.  Likewise, software professionals need to be open about the costs of refactoring.  This comes back to the main point of the first part of this article: hidden and deferred costs will still need to be paid… but with interest.  Software professionals are up-front about the costs because doing so both minimizes the costs and gives stakeholders important information to make decisions.

The challenge for business stakeholders is to accept the costs.  Respecting the team and trusting their decisions can sometimes be very hard.  Teams sometimes make mistakes too, which complicates trust-building.  The business stakeholders (for example, the Product Owner), must allow the team freedom to do refactoring.  Ideally, it is continuous, small, and low-level.  But once in a while, a team will have to do a large refactoring.  How do you know if the cost is legitimate?  Unfortunately, as a non-technical stakeholder, you can’t know with certainty.  However, there are a few factors that can help you understand the cost and it’s legitimacy, namely, the principles that are described here.

If the refactoring is small, it is more likely to be legitimate.

If the refactoring is in response to a business catalyst, it is more likely to be legitimate.

If the refactoring is reflective of team cohesion, it is more likely to be legitimate.

And, of course, if the refactoring is made transparent, it is more likely to be legitimate.

 


Affiliated Promotions:

Try our automated online Scrum coach: Scrum Insight - free scores and basic advice, upgrade to get in-depth insight for your team. It takes between 8 and 11 minutes for each team member to fill in the survey, and your results are available immediately. Try it in your next retrospective.

Please share!
Facebooktwittergoogle_plusredditpinterestlinkedinmailFacebooktwittergoogle_plusredditpinterestlinkedinmail

Summary of User Stories: The Three “C”s and INVEST

User Stories

Learning Objectives

Becoming familiar with the “User Story” approach to formulating Product Backlog Items and how it can be implemented to improve the communication of user value and the overall quality of the product by facilitating a user-centric approach to development.

Consider the following

User stories trace their origins to eXtreme Programming, another Agile method with many similarities to Scrum. Scrum teams often employ aspects of eXtreme Programming, including user stories as well as engineering practices such as refactoring, test-driven development (TDD) and pair programming to name a few. In future modules of this program, you will have the opportunity to become familiar enough with some of these practices in order to understand their importance in delivering quality products and how you can encourage your team to develop them. For now, we will concentrate on the capability of writing good user stories.

The Three ‘C’si

A User Story has three primary components, each of which begin with the letter ‘C’:

Card

  • The Card, or written text of the User Story is best understood as an invitation to conversation. This is an important concept, as it fosters the understanding that in Scrum, you don’t have to have all of the Product Backlog Items written out perfectly “up front”, before you bring them to the team. It acknowledges that the customer and the team will be discovering the underlying business/system needed as they are working on it. This discovery occurs through conversation and collaboration around user stories.
  • The Card is usually follows the format similar to the one below

As a <user role> of the product,

I can <action>

So that <benefit>.

  • In other words, the written text of the story, the invitation to a conversation, must address the “who”, “what” and “why” of the story.
  • Note that there are two schools of thought on who the <benefit> should be for. Interactive design specialists (like Alan Cooper) tell us that everything needs to be geared towards not only the user but a user Persona with a name, photo, bio, etc. Other experts who are more focused on the testability of the business solution (like Gojko Adzic) say that the benefit should directly address an explicit business goal. Imagine if you could do both at once! You can, and this will be discussed further in more advanced modules.

Conversation

  • The collaborative conversation facilitated by the Product Owner which involves all stakeholders and the team.
  • As much as possible, this is an in-person conversation.
  • The conversation is where the real value of the story lies and the written Card should be adjusted to reflect the current shared understanding of this conversation.
  • This conversation is mostly verbal but most often supported by documentation and ideally automated tests of various sorts (e.g. Acceptance Tests).

Confirmation

  • The Product Owner must confirm that the story is complete before it can be considered “done”
  • The team and the Product Owner check the “doneness” of each story in light of the Team’s current definition of “done”
  • Specific acceptance criteria that is different from the current definition of “done” can be established for individual stories, but the current criteria must be well understood and agreed to by the Team.  All associated acceptance tests should be in a passing state.

INVESTii

The test for determining whether or not a story is well understood and ready for the team to begin working on it is the INVEST acronym:

I – Independent

  • The solution can be implemented by the team independently of other stories.  The team should be expected to break technical dependencies as often as possible – this may take some creative thinking and problem solving as well as the Agile technical practices such as refactoring.

N – Negotiable

  • The scope of work should have some flex and not be pinned down like a traditional requirements specification.  As well, the solution for the story is not prescribed by the story and is open to discussion and collaboration, with the final decision for technical implementation being reserved for the Development Team.

V – Valuable

  • The business value of the story, the “why”, should be clearly understood by all. Note that the “why” does not necessarily need to be from the perspective of the user. “Why” can address a business need of the customer without necessarily providing a direct, valuable result to the end user. All stories should be connected to clear business goals.  This does not mean that a single user story needs to be a marketable feature on its own.

E – Estimable

  • The team should understand the story well enough to be able estimate the complexity of the work and the effort required to deliver the story as a potentially shippable increment of functionality.  This does not mean that the team needs to understand all the details of implementation in order to estimate the user story.

S – Small

  • The item should be small enough that the team can deliver a potentially shippable increment of functionality within a single Sprint. In fact, this should be considered as the maximum size allowable for any Product Backlog Item as it gets close to the top of the Product Backlog.  This is part of the concept of Product Backlog refinement that is an ongoing aspect of the work of the Scrum Team.

T – Testable

  • Everyone should understand and agree on how the completion of the story will be verified. The definition of “done” is one way of establishing this. If everyone agrees that the story can be implemented in a way that satisfies the current definition of “done” in a single Sprint and this definition of “done” includes some kind of user acceptance test, then the story can be considered testable.

Note: The INVEST criteria can be applied to any Product Backlog Item, even those that aren’t written as User Stories.

Splitting Stories:

Sometimes a user story is too big to fit into a Sprint. Some ways of splitting a story include:

  • Split by process step
  • Split by I/O channel
  • Split by user options
  • Split by role/persona
  • Split by data range

WARNING: Do not split stories by system, component, architectural layer or development process as this will conflict with the teams definition of “done” and undermine the ability of the team to deliver potentially shippable software every Sprint.

Personas

Like User Stories, Personas are a tool for interactive design. The purpose of personas is to develop a precise description of our user and so that we can develop stories that describe what he wishes to accomplish. In other words, a persona is a much more developed and specific “who” for our stories. The more specific we make our personas, the more effective they are as design tools.iii

Each of our fictional but specific users should have the following information:

  • Name
  • Occupation
  • Relationship to product
  • Interest & personality
  • Photo

Only one persona should be the primary persona and we should always build for the primary persona. User story cards using personas replace the user role with the persona:

<persona>

can <action>

so that <benefit>.

 


i The Card, Conversation, Confirmation model was first proposed by Ron Jeffries in 2001.

ii INVEST in Good Stories, and SMART Tasks. Bill Wake. http://xp123.com/articles/invest-in-good-stories-and-smart-tasks/

iii The Inmates are Running the Asylum. Alan Cooper. Sams Publishing. 1999. pp. 123-128.


Affiliated Promotions:

Try our automated online Scrum coach: Scrum Insight - free scores and basic advice, upgrade to get in-depth insight for your team. It takes between 8 and 11 minutes for each team member to fill in the survey, and your results are available immediately. Try it in your next retrospective.

Please share!
Facebooktwittergoogle_plusredditpinterestlinkedinmailFacebooktwittergoogle_plusredditpinterestlinkedinmail

Product Backlog Refinement

The ultimate purpose of Product Backlog refinement is to ensure an ongoing conversation that increases transparency of the Product Backlog and therefore the Product itself – to orient everyone on the team to breaking out of their waterfall silos and focus on delivering business value, period.

On mature teams, a lot of the refinement work happens as ad hoc conversations while they are sitting around and thinking together about how to build something great because they are just motivated by that and it becomes part of their mode of operation.

The objective of the refinement work of any given Sprint (that often needs to be repeated over and over like a mantra with new, immature teams) is to ensure that the items at the top of the Backlog are transparent enough that the Development Team considers them ready to pull and get “Done” in the next Sprint.  This is where the concept of the Definition of “Ready” (DoR) comes from – the Scrum Team defines the DoR and spends up to 10% of its capacity refining enough items at the top of the Backlog so that it can provide estimates (if required) and have a reasonable degree of confidence that it can deliver the items in the next Sprint.

Refinement is NOT solutioning – I think this is the big trap that a lot of teams fall into because there is a false assumption that technical solutions need to be hashed out before estimates can be made (part of the carried-over lack of trust and communication between the business and IT) – I would almost rather throw out estimates in cases where this is not improving – The Planning Game exercise, when facilitated well, lends itself more to increasing transparency rather than solutioning.

The fact that teams are telling us that they need to solution before they can estimate is also an indication of weak Agile Engineering practices such as refactoring, test-driven development and continuous integration (XP).  The best refinement sessions are those in which the team is able to focus on the “what” – the business benefit results that the Product Owner really wants – rather than the “how” (solution).  Strong teams emerge in an environment in which they are trusted by the business and management to find the right solution as a team.  They don’t need to have it all figured out before giving an estimate because they are not afraid to give a bad estimate and fail.  Also, if the team is struggling to give estimates, this is often a sign that the Product Backlog Items are too big.  Most likely the team also needs to expand the Definition of “Done” to include testing against acceptance criteria within the Sprint so that they can estimate based on that criteria.

The “how” (solution) should be mapped out by the Development Team at a high level in the 2nd part of Sprint Planning (partly why the time box is bigger than they often think they need) and more detailed architecture, requirements and design work as part of the Sprint Backlog

But this level of maturity is very hard to do and it will take a while to get there, perhaps even years.

It also depends on your interpretation of “detail”, the word used in the Scrum Guide to describe what the team does in Product Backlog refinement. To me, it means understanding in more detail what the Product Owner really wants and needs. What does it mean to you?


Affiliated Promotions:

Try our automated online Scrum coach: Scrum Insight - free scores and basic advice, upgrade to get in-depth insight for your team. It takes between 8 and 11 minutes for each team member to fill in the survey, and your results are available immediately. Try it in your next retrospective.

Please share!
Facebooktwittergoogle_plusredditpinterestlinkedinmailFacebooktwittergoogle_plusredditpinterestlinkedinmail

Tips to Start Agile in a Hostile Environment

Although Agile methods are very popular (particularly Scrum), there are still many organizations or departments which may not yet have official support for adopting Agile methods formally.  In some cases, management may even be hostile to the concepts and practices of Agile methods.  If you are interested in Agile, you don’t have to give up hope (or look to switch jobs).  Instead, here are some tips to start using Agile methods even in hostile environments.

Regular Retrospectives

Some Agilists claim that the retrospective is actually the key to being Agile.  In some ways, this is also the easiest practice to introduce into an organization.  Start with “easy” retrospectives like “Pluses and Deltas” or “Starfish“.  These are retrospectives that can be done in 15 minutes or half an hour.  Try to do them with your team weekly.  If you are are a team lead or a project manager, it will be easy to include this as part of an existing weekly status meeting.  If you are “just” a team member, you might have to get some modest amount of permission.

So why would it be good to do a retrospective?  Because it’s a high return-on-investment activity.  For a few minutes of investment, a team using retrospectives can become aware of dramatic opportunities for improvement in how they are functioning.   Here are a couple more articles about the importance of retrospectives:

What’s an Agile Retrospective and Why Would You Do It?

What is a Retrospective?

Practice-by-Practice

Although I strongly recommend starting with retrospectives, sometimes that’s not the best way to start.  Myself, my first formal Agile environment, I started with the Daily Scrum.  Another time less formal, I started with Test-Driven Development.  In both cases, starting with a single practice, done well, led to adding additional practices over a relatively short period of months.  This gradual adoption of practices led, in time, to attracting positive interest from managers and leaders.  This is the practice-by-practice approach.  Start with a simple Agile practice that you can do without asking anyone for permission.  Make sure it is a practice that makes sense for your particular environment – it must produce some benefit!  If you are technical contributor on a team, then practices such as refactoring or test-driven development can be a good place to start.  If you are more business-oriented, then maybe consider user stories or one of the Innovation Games.  If you are responsible for administrative aspects of the work, then consider a Kanban board or burndown charts.

It is important to get the chosen practice done consistently and done well, even when the team is struggling with some sort of crisis or another.  If the practice can’t be sustained through a project crisis, then you won’t be able to build on it to add additional Agile practices.

Stealth Project

Sometimes you get an unusual opportunity: a project that is funded but hidden from the bureaucracy.  This can happen for a variety of reasons, but often it is because some executive has a pet project and says (effectively): “make it so”.  This is an opportunity to do Agile.  Since there is little oversight from a process perspective, and since the overall project has a strong executive sponsor, there is often a great deal of freedom on the question of “how do we actually execute.”  There can be challenges as well: often the executive wants daily insight into progress, but that level of transparency is actually something that Agile methods can really support.  In this case, there is no need to ask anyone on what method to use, just pick one (e.g. Scrum or OpenAgile or XP or Kanban or Crystal or…) and go for it.  Don’t talk about it.

The “just do it” approach requires that you have some influence.  You don’t have to be an influencer, but you need connections and you need charisma and you need courage.  If you don’t have at least two of those three, you shouldn’t try this approach.  You have to do things and get away with things that normally would get people fired – not because they are illegal – but simply because they are so counter-cultural to how your organization normally works.  Here are a few comments on Stealth Methodology Adoption.

Co-Conspirators

There’s nothing like working with a band of rebels!  If you can find one or two other people to become co-conspirators in changing your organization, you can try many lines of action and see which ones work.  Getting together for lunch or after work frequently is the best way to develop a common vision and to make plans.  Of course, you need to actually execute some of your plans.  Having people to work with is really part of the other tips here: you can have co-conspirators to help you launch a practice-by-practice Agile transformation, for example.

But, like any rebellion, you really need to trust those you work with in these early stages.  Lacking that trust will slow everything you do possibly to the point of ineffectualness.  Trust means that you have, for some time, a formal vow of silence.  Not until you have critical mass through your mutual efforts can you reveal the plan behind your actions.

Read “Fearless Change”

I can’t recommend this one enough!  Read “Fearless Change” by Mary Lynn Manns and Linda Rising.  This is a “patterns” book.  It is a collection of techniques that can be applied to help make organizational changes, where each technique has its own unique context of use.  Lots of research and experience have gone into the creation of this book and it is a classic for anyone who wants to be an organizational change agent.  Patterns include basics such as “Do Lunch” to help build trust and agreement with your ideas for change or “Champion Skeptic” to leverage the value of having systematic, open criticism of your change idea.

Don’t Call it “Agile”

This isn’t really a “tip” in the sense of an action item.  Instead, this is a preventative measure… to prevent negative reactions to your proposals for change.  The words “Agile” or “Scrum”, while they have their supporters, also have detractors.  To avoid some of the prejudices that some people may hold, you can start by _not_ calling your effort by those names.  Use another name.  Or let your ideas go nameless.  This can be challenging, particularly if other people start to use the words “Agile” or “Scrum”.  By going nameless into the change effort, people will focus more on results and rational assessment of your ideas rather than on their emotional prejudices.

A minor variant of this is to “brand” your ideas in a way that makes them more palatable. One company that we worked with, let’s call them XYZ, called their custom Agile method “Agile @ XYZ”.  Just those extra four symbols “@ XYZ” made all the difference in changing the effort from one where managers and executives would resist the change to one where they would feel connected to the change.

Get Some Training

Okay, some blatant self-promotion here: consider our Certified Real Agility Coach training program.  It’s a 40-week program that takes about 12 hours/week of your time for coursework.  The next cohort of participants starts in June 2015 and we are taking deposits for participants.  This training is comprehensive, top-notch training for anyone wishing to become an organizational change agent focusing on Agility.


Affiliated Promotions:

Try our automated online Scrum coach: Scrum Insight - free scores and basic advice, upgrade to get in-depth insight for your team. It takes between 8 and 11 minutes for each team member to fill in the survey, and your results are available immediately. Try it in your next retrospective.

Please share!
Facebooktwittergoogle_plusredditpinterestlinkedinmailFacebooktwittergoogle_plusredditpinterestlinkedinmail

Awesome Explanation of Why Refactoring is NOT on the Product Backlog!!!

From the excellent Ron Jeffries, we have “Refactoring – Not on the Backlog!


Affiliated Promotions:

Try our automated online Scrum coach: Scrum Insight - free scores and basic advice, upgrade to get in-depth insight for your team. It takes between 8 and 11 minutes for each team member to fill in the survey, and your results are available immediately. Try it in your next retrospective.

Please share!
Facebooktwittergoogle_plusredditpinterestlinkedinmailFacebooktwittergoogle_plusredditpinterestlinkedinmail