Sunday, May 1, 2011

Revealing the Scala magician's code: expression

Scala is truly magical. However, sometimes it is not easy to understand how it performs the magic. Below are some common questions and their answers.

Why some of expressions below work (can be evaluated and printed) but the other don't?



Math.min //doesn't work
Math.min _ //works
val f: (Int, Int)=>Int = Math.min //works

The first expression doesn't work because Math.min is a method, but a method is not a value in Scala. The second expression works because the underscore asks Scala to convert the method to a function, which is indeed a value in Scala. The third expression also works because when Scala is expecting a function value from the expression but finds a method, it will convert it to a function automatically.

Why some of expressions below work but the other don't?



List(2, 3, 5) foreach println //works
List(2, 3, 5) foreach println(_) //doesn't work
List(2, 3, 5) foreach (println(_)) //works

The first one works because foreach is expecting a function, while println (of the Predef object which has been imported automatically) is a method, not a function, but as mentioned above Scala will convert it into a function automatically because a function is expected. So it works.
The second one is trying to create an anonymous function:

List(2, 3, 5) foreach ((x)=>println(x))

However, in Scala only a "top level" expression can be a function. In this case, println(_) is only a "term" in an expression (foreach is the operator) but not a top level expression, so the compiler won't try to make it an anonymous function. Instead, it will search further to find the first enclosing top level expression (in this case, the whole expression you entered) and turn it into an anonymous function:

(x)=>List(2, 3, 5) foreach println(x)

But then the type of x can't be inferred, so it is an error. Also, println(x) returns a value of (), the only value of the class Unit, which is not what foreach wants anyway (a function taking an Int).
With this knowledge, you can see why the third expression works:

List(2, 3, 5) foreach (println(_)) //works

This is because with the parentheses, a top level expression is expected, so Scala will make println(_) an anonymous function:

List(2, 3, 5) foreach ((x)=>println(x)) //works

Why some of expressions below work but the other don't?



List(2, 3, 5) foreach (println("hi"+_)) //doesn't works
List(2, 3, 5) foreach (println "hi"+_) //doesn't works
List(2, 3, 5) foreach (Predef println "hi"+_) //works

The first expression doesn't work because the first top level expression found is "hi"+_ due to the parentheses. So, Scala will treat it as:

List(2, 3, 5) foreach (println((x)=>"hi"+x)) //doesn't works

So you're printing a function to the console and returning a unit value () to foreach. In order to fix the problem, you may try to get rid of the parentheses so "hi"+_ is no longer a top level expression:

List(2, 3, 5) foreach (println "hi"+_)

The problem is that Scala will now try to parse:

println "hi"+_

as:

expr1 op1 expr2 op2 ...

println is assumed to be an expression instead of a prefix operator because only !, ~, +, - can be prefix operators. So, println will be treated as an expression while the String "hi" will be treated as an operator, which is obviously incorrect.
To fix this problem, you can provide a real object as expr1, which is the Predef object:

List(2, 3, 5) foreach (Predef println "hi"+_)

Note that there are two operators: println and +. Because all symbolic operators have higher precedence than identifier operators, + will be applied first.
So, the first enclosing top level expression is turned into an anonymous function:

List(2, 3, 5) foreach ((x)=>Predef println "hi"+x)

Because in Scala "e1 op e2" is treated as e1.op(e2), the code is treated as:

List(2, 3, 5) foreach ((x)=>Predef.println("hi".+(x)))

Friday, April 22, 2011

Great way to learn the Scala API: Scala interpreter

If you have already learned the language construct of Scala, the next step is to learn its API. If you're a Java programmer, usually you'll try to do that by writing small Scala programs in an IDE. However, there is a much better way: using the Scala interactive interpreter. This way you can inspect the effect of each line of code as soon as you press Enter. This is quite non-obvious for Java programmers because there is no such thing in the Java tool set.
For example, you'd like to learn about the Seq trait in Scala. So you open the API page of it and find a long list of methods. Let's say you're interested in learning the behaviors of the following methods:

/** Appends all elements of this sequence to a string builder. The written text consists of the string representations (w.r.t. the method toString) of all elements of this sequence without any separator string. */
def addString(b: StringBuilder): StringBuilder

To do that, you issue the "scala" command from a shell/command prompt and then explore the method like:

kent@dragon:~$ scala
Welcome to Scala version 2.8.0.r20327-b20091231020112 (Java HotSpot(TM) Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val a = List("a", "b", "c")
a: List[Int] = List(a, b, c)

scala> val b = new StringBuilder
b: StringBuilder =

scala> b.append("hi")
res0: StringBuilder = hi

scala> a.addString(b)
res1: StringBuilder = hiabc

From the experiment, it is clear that the addString() method will append all the elements of the Seq to the string builder.
Let's consider another. You're interested in:

/** Multiplies up the elements of this collection. num is an implicit parameter defining a set of numeric operations which includes the * operator to be used in forming the product.
*/
def product[B >: A](num: Numeric[B]): B

So, try it in the Scala interpreter:

scala> val a = List(3, 5, 2)
a: List[Int] = List(3, 5, 2)

scala> a.product
res2: Int = 30

So it seems to work fine. Possible to override the * operator? From the API doc it is clear that the default being used is the IntIsIntegral object:

package scala.math

class Numeric {
object IntIsIntegral extends IntIsIntegral with IntOrdering {
...
}
}

So, the first try is:

scala> import scala.math.Numeric._
import scala.math.Numeric._

scala> val x = new IntIsIntegral {
| override def times(x: Int, y: Int) = x+y;
| }
<console>:9: error: object creation impossible, since method compare in trait Ordering of type (x: Int,y: Int)Int is not defined

Oops, forgot to specify the IntOrdering trait which defines the compare() method. So, do it now:

scala> import scala.math.Ordering._
import scala.math.Ordering._

scala> val x = new IntIsIntegral with IntOrdering {
| override def times(x: Int, y: Int) = x+y;
| }
x: java.lang.Object with math.Numeric.IntIsIntegral with math.Ordering.IntOrdering = $anon$1@1e5d007

We have successfully created a new object to redefine the * operator as just addition. Now, pass it to the product() method:

scala> a
res5: List[Int] = List(3, 5, 2)

scala> a.product(x)
res6: Int = 11

It should be 3+5+2=10 but why the result is 11? Recall that it is doing multiplication, so it is using 1 as the seed for calculation (1+3+5+2). To change the seed from 1 to, say, 0, we can override the one() method:

scala> val x = new IntIsIntegral with IntOrdering {
| override def times(x: Int, y: Int) = x+y;
| override def one = 0;
| }
x: java.lang.Object with math.Numeric.IntIsIntegral with math.Ordering.IntOrdering = $anon$1@11a9f20

scala> a.product(x)
res7: Int = 10

Obviously now it works.

Tuesday, April 5, 2011

Five signs that your talents are not being appreciated

Here are the five signs:

  1. Late arrival to the office. Your boss is so blind to see your great contributions to the company, therefore you are so de-motivated that you come in to the office late everyday.

  2. Micro-management. Your boss is always trying to micro-manage you by telling you the "right" ways to do things such as agile methodologies, but actually you know those aren't just good as your way because you've been in the trenches long before your boss.

  3. Rejecting your good suggestions. You have been pushing a complete conversion to a cutting edge technology to double the productivity of the team, but your boss just won't listen.

  4. Incompetent peers. Your peers are so incompetent and have been hampering the product launch. Even though you have been telling them their problems, they just don't get it.

  5. Being blamed. Your peers are so jealous of your great abilities that they try to isolate you and blame you for everything that has gone wrong.


These signs seemingly indicate that people aren't appreciating your talents, but the fact is you may be just living in your own little world and will probably be fired in a few months! The truth that you may not be understanding right now is:

  1. Late arrival to the office (Lack of commitment). Even if you aren't happy with your job or the way you're treated, you should still demonstrate your commitment to your duties. Arriving late is an obvious way to say that you have no commitment.

  2. Micro-management (Not accepting advise for improvement). Seeing the difficulties you face, your boss is trying to help you by giving you good advice. But you are so attached to your ego and stubborn to see any values in any new approaches.

  3. Rejecting your good suggestions (Not understanding the priorities of the company). Your suggested technology may seem great to yourself, but actually it may be just too premature or is not among the top priorities of the company. Everyone is trying to tell you that but you just won't listen.

  4. Incompetent peers (Destroying harmony). You may be good or not, but it is never a good idea to pick the mistakes of others. You will appear like an asshole to all your peers. Instead, you should help others improve.

  5. Being blamed (Not seeing your own mistakes). Be brave and admit it, those mistakes were yours. If you don't see your own mistakes, you'll never grow.


Fortunately, it is not too late to realize your own mistakes. Stop denying and you'll have a much brighter future.
ps, if you’d like to learn more about IT management and governance, check out IT Governance by Examples.

Sunday, March 27, 2011

A story for development outsourcing clients

Once upon a time there was a client who had contracted a carpenter to make a chair for him. In order to protect his own interests, he spent a lot of time specifying the dimensions of the chair, the material and etc. Then he negotiated with the carpenter to settle on the cost and duration. In addition, he set up a monetary reward for early delivery and a daily penalty for each day late.
Then there was another client who spent a lot of time looking for and selecting a carpenter with good reputation for excellent customer satisfaction. He only told the carpenter that he needed a chair that is comfortable to sit on and then drafted a sketch of the chair. Then he negotiated with the carpenter to settle on the cost and duration. There was no reward for early delivery and no penalty for late delivery. They agreed to discuss to adjust the cost and duration if there turned out to be a need.
Then what was the result? The first client got the chair earlier than the deadline and the carpenter got the reward. However, when the client sat on the chair, it was not that comfortable. Because the carpenter rushed to finish it, the craftsmanship was poor and as a result, the chair was broken in a year. Then, it was found that low-graded wood was used in the inner, hidden part of the chair.
In contrast, the other client found that the chair was not that comfortable during the making. So he discussed with the carpenter to make the necessary change. The cost was increased by a little and the duration was longer by a little, but the carpenter had enough time for him to make a quality chair that he is proud of, which finally lasted for 10 years.

The moral of the story


The moral of the story is that in any project there are four factors to be considered: cost, time, scope and quality. If any of those changes, at least one of the other must change accordingly. The problem is, most people will try to fix/specify all those in planning, but in really only cost and time can be easily fixed, while it is very difficult to fix/specify the scope and quality (they are fuzzy and dynamic). So, from the view of the contractor, to meet the fixed cost and time, he has every incentive to minimize the scope (only make  what is explicitly told and nothing else) and reduce the quality (uncomfortable to sit, poor craftsmanship, low-graded wood).
The reward and the penalty make the matter worse. They double the importance of meeting the time factor, so they double the incentive for the contractor to minimize the scope and reduce the quality.
To solve this problem, many people try to make the scope and quality even better specified. However, this effort is futile as scope and quality are related to the needs of human which is fuzzy and dynamic. In the example of the chair, what is the quality? Perhaps that it should be comfortable to sit on, that it should last long, etc. But these aren't objective (what is comfortable?) nor can be measured immediately (how long it will last?), so they can't be used to bind the behavior of the contractor.
Therefore, there must be a second level of defense to deal with this fuzziness and dynamics. In addition to specifying the scope and quality at our best effort, we must also identify the contractor who really cares for quality. The idea is that he will work for quality on a higher-level (what we really care about) instead of focusing on meeting lower-level but objective metrics which do not necessarily fully reflect quality. That is the best insurance that we can get. Of course, to allow him to work for the fuzzy and dynamic scope and quality, we must be prepared to renegotiate with him to adjust the cost and duration as necessary.
ps, if you'd like to learn more about IT management and governance, check out IT Governance by Examples.

Thursday, December 9, 2010

Study notes on Cobit: Managing projects

Scope, cost and schedule


Suppose that you're the software development manager of a publishing company. To create a new market, the company is considering developing a self-publishing platform for authors to publish their works (initiating a project).To help the CEO to decide to go ahead or not, you have gathered the rough requirements (deliverables) and estimated a rough cost (e.g., MOP1,000,000) and schedule (1 year). So, the CEO decided to go ahead and you have been assigned as the project manager for the project. Your mission is to ensure that the deliverables (scope) are delivered within the allocated cost and schedule (the three most important constraints for a project). This is called project management.

Good planning


Is this mission possible? You must make sure that for the given scope, the cost and schedule are reasonable. At the initiation phase, your estimate may be quite rough because there were no detailed requirements yet (so, you should add a large buffer to it, whose size depends on the level of details available). Now, you need to identify all the requirements in details and get a better estimate on the cost and schedule.
How? You could adopt a divide and conquer approach. First, you can break down the project into:

  1. A short upfront analysis to identify the features (which you will use to estimate the cost & duration): 3 days (according to previous experience)

  2. Development: ???

  3. System testing: ???


For each part, you can further divide it. For example, for the development part, you can break it down into the deliverables (features):

  1. Analysis

  2. Development

    1. Author management

      1. Register account: 2 days (given the previous experience of the same development team)

      2. Edit profile: 1 day

      3. ...



    2. Publication management

      1. Create a publication: ...

      2. Push a publication to Amazon: ...

      3. ...





  3. System testing: ??? (you can estimate it by the number of features, the number of tests, etc.)


You can the cost of each small item similarly. The total cost is just the sum of all item costs. For the schedule, basically you can assume that the analysis, development and system testing will be in sequence, so you can determine their individual schedules (not really 100% true, as system testing could be done before everything is implemented). For the features in development, basically they can be implemented in any order you want. As not all programmers will be working on the same feature, they won't be done in sequence, but it is fare to plan what features will be done in a particular month or week.
Note that with this approach you can plan not only the cost and the schedule, but also other resources needed (e.g., programmers, testers, business analyst, 3rd party software components and tools, hardware) and when.

Uncertainties, changes, monitoring and control


After creating the project plan above, can you just assign people to the tasks and come back again in one year to receive the working system? No. There are way too many uncertainties and changes in a typical project that will throw your project off the track. For example:

  • What if the progress of the development team is slower than planned? (planning risk)

  • What if a programmer quits in the middle of the project? (human risk)

  • What if the framework adopted for the project doesn't work as well as expected? (technology risk)

  • What if the new programmer is not getting along with another programmer? (human risk)

  • What if the testers aren't working well with the programmers? (human risk)

  • What if the testing hardware is delayed by the supplier? (supplier risk)

  • What if the CEO wants to add some new features? (scope change)

  • What if the CEO wants to release the system two months earlier? (schedule change)


Therefore, you (the project manager) must monitor for any potential and actual problems and any deviations from the plan and take actions to correct the problems or deal with changes (control the project). Therefore, in accordance with the project management framework or methodology adopted by your company, you should have phases in the project as inspection and approval points. The phases can be time-based such as monthly or weekly meeting (as in XP or SCRUM) or based on deliverables (e.g., when the author management sub-system is implemented).

Quality as the 4th major constraint


Suppose that the progress of the development team is slower than planned or the CEO wants to add some new features, what would you do? Unfortunately, instead of really fixing the problems by speeding up the team or removing unnecessary features, many project managers will choose to cut the quality by overloading the programmers and decreasing the testing (unit testing embedded in the development, the system testing, etc.). The result is that, the features seem to work, but only in some occasions and will behave incorrectly in others.
Why is quality often the first to get cut? It is because quality is not as visible as the other constraints: scope, cost and schedule. Any deviation in these three can be found easily, but it takes very closed interactions to discover quality deviations. In addition, the longer the problems are covered (e.g., after being deployed), the more money it will cost (e.g., service interruptions, loss of businesses, lots of service calls, training for workarounds, redeployment for the fixes).
Therefore, quality is not an option. It should be considered the 4th top constraints in project management. As mentioned earlier, you should plan, monitor and control for quality in your project (that's why you have all kinds of testing and validation in the project).

Keeping the sponsor happy to fuel the project


What if you only report to the project sponsor (here, the CEO) and other stakeholders in a year? They will lose enthusiasm by then. So, to keep their enthusiasm and more important their commitment and support for the project (that's how to ensure the resources for your project), you should report the project status, deliverables so far and etc. to them regularly. This is like fueling your car regularly on a journey.
Also, after the project is ended (closing), you should provide a final report to the project sponsor and other stakeholders mainly to show that you have delivered the required deliverables in high quality, within cost and schedule. Again, this is to make the project sponsor happy about the project and you for his future support.

Getting long lasting benefits out of the project


Basically, after the project is closed, all you enjoy is the deliverables. However, there is more you can get out of the project. For example, if you have found a best practice with working with that framework or working with a particular stakeholder, you should document it for future use.

Coordination between projects


In addition to the self-publishing platform, your company has other projects supporting the same strategy of enabling authors to self-publish. For example, it has a market research project to identify the needs, a promotion project to promote the service, and etc. Obviously, the projects must be coordinated. For example, it is impossible for you to get the detailed requirements before the market research project identifies them.
Therefore, there needs to be a program manager (e.g., a vice president) to do that (managing the program which consists of the interrelated projects). In addition, the company should adopt a program management framework to ensure proper organization (e.g., a program management committee consisting of the program manager and all the project managers) and processes are in place to support the prioritization and coordination of the projects.

Adopting and tailoring a project management framework


You've seen the key control objectives above for project management. Cobit recommends that your company adopt a project management framework (e.g., based on PMP body of knowledge or PRINCE2) covering the above, with customizations based on project size, risk, complexity and etc.

Wednesday, December 8, 2010

Study notes on Cobit: Assessing and managing IT risks

Life could be at stake


Suppose that you were the CIO of a hospital. To allow the people to quickly locate expensive medical equipment, you had implemented a WiFi tag tracking system and it had been working fine. Until one day, a patient was rushed to the ICU for urgent operation and the surgery doctor was looking for a certain piece of critical but rarely used equipment but it just couldn't be found. As a result, the patient died and the hospital was sued and ordered to pay a million dollars for the damage. The incident was also widely reported in the media. Investigation showed that the WiFi tag on that piece of equipment simply ran out of battery, but the hospital didn't have a procedure for checking for low-battery WiFi tags, so it was considered a negligence.
The above example shows a risk (medical equipment not found when it is urgently needed) that has become true. It had a very serious impact (loss of human life, public image of the hospital, financial damage). So, the question is, how to mitigate the risks?

Identifying and assessing the risks


The most important thing is to identify (find out) the risks first, otherwise you won't even consider them at all. How to identify the risks? As risks are not just about IT, your organization should appoint someone higher up to take overall accountability for risk management in the company. This role could be the chief risk officer. He should form an enterprise risk management committee and the members should include himself, the CIO (or someone in IT responsible for IT risks), compliance officer (for legal risks), and probably other business executives. Then, the members will work together to identify the risks. This should take the form of a brainstorm session or some other forms.
As there are so many possible risks to consider (the Earth hit by a meteor from the outer space?), it is ineffective to list them all. Instead, you should focus on those applicable to your organization's activities and environments (treating patients, laws for hospitals, local labor laws, in earthquake zone? etc.). This is called establishing the risk contexts. Then, you should focus on those risks with a high impact and/or a high probability (so, you're assessing the impacts and probabilities of the risks at the same time). For example:

  1. High impact and high probability such as a baby is stolen (assuming you have very poor security) or a patient dies due to wrong dose of medication (assuming your staff are very lousy). Usually this kind of risks should not exist for very long as the company would have gone out of business.

  2. High impact and medium probability such as the WiFi tag case above.

  3. High impact and low probability such as avian flu pandemic.

  4. Medium impact and a high probability such as hardware failure of a server.


Note that there is no strict definition of what is a high impact (MOP10,000 high impact or just medium impact?) and what is high probability (once a month or once a year?); it all depends on the rough concepts across the risk management committee members.
In addition, it is usually very difficult to quantify the impact to a dollar amount (how much a human life is worth in dollars?) or to quantify the probability to a number (the chances of having avian flu pandemic in this year is 0.1%?). So, in most cases you will just roughly classify them as high, medium or low.

Mitigating the risks


Once you have the list of risks (called the risk register), the risk management committee can prioritize them (by their impact and probability) and consider how to deal with each of them. How? It is simple: either reduce the probability or reduce the impact. For example:

  • For the risk of babies being stolen due to poor security, just enhance the security to reduce the probability of losing a baby. Put security guards at various spots in the hospital (in particular, the baby room). Attach WiFi or RFID tags to the babies for checking whenever they are transported.

  • For the risk of WiFi tags running out of battery, locate all the the equipment everyday to detect low-battery and replace the battery as required. This reduces the probability of running out of battery when the equipment is needed.

  • For the risk of avian flu pandemic, while you can't reduce the probability, you can reduce the impact. For example, set up remote interaction system between the hospital and n quarantined facility for avian flu patients that supports remote diagnosis and automated delivery of medication, so that the medical staff staff members don't need to physically enter that facility and won't get infected.

  • For the risk of a server hardware failure, you can reduce the impact by having a stand-by server, a 2-hour emergency repair service contract, a pool of spare parts and etc.


As you can see above, to mitigate the risks you may need to change your procedures (e.g., locating all the equipment everyday), IT infrastructure (stand-by server), contracts (emergency repair), to integrate risk management into all elements of your enterprise.

Transferring the risks


Sometimes it is just impossible or too difficult to reduce the probability or the impact of a risk in isolation. For example, a patient dies due to a mistake by the doctor. In that case, you can buy insurance. So, you will pay a certain small amount (a small impact but 100% probability). Essentially, you are trading a risk with a high impact (could be millions) and a low probability for a risk with a small impact and a high probability with the insurance company. For a smaller organization with limited cash such as your hospital, the latter is easier to absorb. For a larger organization with a lot of cash such as the insurance company, the former is more profitable.
In addition to insuring, outsourcing is another way to trade the risk: you just pay someone else to do the risky task for you. You pay more but the outsourcer takes the risk.
In either case, the event now has a 100% probability so in common sense is no longer a risk as it will definitely happen. Therefore, you may view it as transferring the risk to the insurance company or the outsourcer by paying them.

Monitoring and reviewing the risks


So, you have taken some measures to mitigate the risks, but do they work? Therefore, you should review regularly to see if the measures are indeed effective enough to reduce the probability or the impact enough. If yes, fine. If no, you need to come up with more mitigation measures. To allow for such reviews, you should record the corresponding mitigation measures for each risk in the risk register.
Will a certain existing or new risk become more prominent? For example, are there indications that an avian flu pandemic is coming? A new law is coming into effect? To deal with these cases, the risk management committee should review and update the risk registry regularly accordingly.

Monday, December 6, 2010

Study notes on Cobit: Managing quality

What is quality?


Are your users happy with, say, your email service? This is what quality is all about. If the email system is so slow or fails to catch spam effectively, the users may be unhappy about it. If you (the CIO) don't know about it and thus aren't doing anything to address the problem, they (probably including the CEO) will lose trust in you and you will have difficulty getting budget for existing or new initiatives. So, getting the users happy about your services (quality) is critical for your career as the CIO.

How to ensure quality?


Take the email service as an example, it is basically an automated service so the quality mainly depends on the email software and the infrastructure (server and network) instead of human being. How to ensure the quality of, e.g., the email software? You may follow such a process:

  1. The CIO, the business analyst and the solution architect discuss with the representative users and other stakeholders on the requirements. For example, you may determine that it needs to support shared and personal address book, anti-spam, anti-virus, web access from anywhere, digital signature, company wide archiving (for legal purpose). There are also non-functional requirements such as: it shouldn't take more than 1 minute to process and deliver an incoming mail (performance), all client communication must be secure (security), the service should be available 99.9% of the time (availability), etc.

  2. The architect evaluates the email packages on the market to identity those that support the above requirements.

  3. The architect selects the one that meets the requirements, at a lower cost with a lower risk.

  4. The architect requests the representative users, in your actual environment with a heavy work load.

  5. The CIO finalizes on the decision with all the stakeholders.

  6. Deploy the solution.

  7. Get user feedback.

  8. Get user feedback regularly to see if the service gets deteriorated (e.g., is it getting slow due to increased volume of emails?) or there are new requirements (e.g., shared calendar?).


If you check carefully, you will note that this process is actually applicable to most types of solution acquisitions and has little with the specifics of email service. The process is basically:

  1. Get requirements (control point for quality).

  2. Evaluate & test possible solutions (control point for quality).

  3. Select a solution.

  4. Validate the solution (control point for quality).

  5. Finalize & deploy on the solution.

  6. Validate the solution again in production (control point for quality).

  7. Monitor the quality regularly and improve as needed (control point for quality).


That is, to ensure quality, all solution acquisitions should adopt this process. Adopting such a process with quality control points is the basis of quality management. Of course, you also need people capable of doing this type of work (in this case, the business analyst and the architect).

Ensuring quality throughout the whole enterprise


The above process deals with the quality of acquired solutions, but what about others such as development of applications, support services and maybe other non-IT products or services? To ensure that everything is covered, there should be someone higher up such as the quality director who is in overall charge of quality (in ISO 9000, this is called the management representative). He should somehow ensure that the processes for the company to develop its products or to deliver its services (including those for internal use which is typically the case for IT) have incorporated control points for quality.
As this is a lot of work and much of the work requires professional knowledge (e.g., it's difficult for a non-IT person to ensure quality in software development), the quality management representative should ignite the care for quality in the minds of all staff members, so that they drive the development of the processes to ensure quality instead of them being driven by the processes.

Summary


As you can see, to ensure quality, your company needs the organization (quality management representative and all other people actively working to ensure quality and their relationships) and the processes in place designed to ensure quality. These two are the main elements of a quality management system (QMS).