问:
How to measure the potential value of refactoring
On an old,  large project with technical debt how can you reliably estimate or measure the benefit of refactoring code?

For example, say you have some components within a software stack solution written in an older language, and some later components written in a newer language. New features and bug fixes are constantly being added to this solution by a development team.

The developers suggest that replacing the existing old language components with the new version would be 'a good thing' However, no extra features would be added by this work and it will cost x dev-days.

A sales person suggests adding 'a great new feature'. the company measures the value of his suggestion by using a formula. ie. It will earn the company F million pounds, over t years at a cost of x dev-days work

How can the company cost up the refactoring proposal in a meaningful way? and under what circumstances is it likely to be the most profitable option for the company?

答:
The question you should ask yourself is how is the salesperson know that the feature will cost x developer-days of work. Given that even good project managers with years of professional experience cannot often tell that, such data coming from a salesperson seems extremely... speculative.

According to my experience, salespersons usually don't make estimates, but guesses about how much is too much for management or customer: if management is ready to pay 50 man-weeks of work, but will absolutely reject 75 man-weeks, let's tell that the feature will take 70 man-weeks while being ready to renegotiate (something which is out of question for a real estimate) down to 55 man-weeks.

On one hand, you have estimates done by IT experts telling something like:

According to this specific audit, we are wasting $8 000 per day using an outdated technology compared to similar projects of similar size which use newer technologies. It also appears that it will take from 50 to 80 man-weeks to migrate the whole code base; during this time, there would be no new features released. There is also a 10% risk that migrating a specific component may result in 20-30 additional man-weeks of work.

On the other hand, you have guesses done by salesmen, based on their leverage when negotiating with the person they need to convince.

It's all about how influential you are in your company. Communication is key here, and this is where salesmen usually win over IT professionals when it comes to explaining the benefits of a feature to management (or a customer).

Note that if in the past, your estimates were quite precise, you gain reputation and influence. If your estimates were always wrong, management would probably ignore your proposals.

As for the estimates, it is extremely difficult to make a valuable one here, since there are a huge number of parameters to take in account. Among others:

Do you actually know how skillful is your team in C# compared to VB6? Is it based on actual measurements or just guesses?

Have this team developed large projects in C#? Do they know the tools they should use (IDE, debuggers, profilers, etc.)? Do you need additional licenses (which, in Microsoft's world, mean thousands of dollars per machine)?

Is the current project totally clear and you can guarantee that there will be no surprises when migrating? Is it straightforward to rewrite everything, every feature, or would there be surprises?

Do you have the infrastructure which supports C#? What about continuous integration? What about your build server? Style guides? Static checkers?

In production, are servers (if this is a web app) or customer PCs (if this is a desktop app) able to run the version of the .NET Framework you are expecting to use?

But the most important thing is to know why do you want to rewrite everything. What is the problem you are trying to solve through a rewrite? A loss of productivity? How do you measure it? How do you show this loss of productivity to management?

Once you have shown that you are wasting, say, $8 000 per day because of VB6 (which means that you'll save $8 000 per day once you migrate to C#), how do you explain the benefit of holding every new features development and focusing on a complete rewrite? What's the benefit compared to progressive rewrite where you migrate your components in small chunks one by one, while shipping new features?


问:
Semantic web and web UI impedance matching
While developing a web-application (= application with web UI) using semantic web resources / technology like RDF, OWL, SPARQL, there is constantly a feeling that at the same time semantic offers much greater possibilities to make a web more human and less "database-style" (not that I do like "parrot-style" popular with start-ups at the moment), as well as a feeling that means to create UI are somewhat limited in the face of openness of the data.

With a "database" approach the schema is fixed and application UI can be hard-coded around it and according to it. Web designers can apply unique styles to distinguish entities, site/app structure can be custom made, annotations (title-author-teaser-tags-...) are well-established and theme developers have ready solutions. Even users became accustomed to where the basic things are and do like that.

On the semantic side things are flexible and generic, and the UI is limited to faceted search, web-like and/or menu-like navigation (correct me if I missed some essential mode). It seems to work best when the curious user hops from node to node (from one page to another).

For example, if we have an author, then we can have all kinds of information about him or her. It is hard to foresee all possibilities in the UI to make it 'nice', so the authro as a subclass of, say, Person will need to have it's own "page", where those things will be mentioned. And some things aren't even "plain text" but with some structure, which to make UI beautiful would need nested UI structures, etc, etc. My impression is that even the most advanced web UI libraries aren't up to the task of representing the complexity in a robust and appealing way.

Of course, we can always restrict the supported annotations / properties and essentially have the same situation as with "database" approach. But assume we want to be open.

The question is, what is the state of the art on the human-machine boundary (i.e. UI), which does not sacrifice aesthetics and usability for flexibility and web UI tradition with necessary novelty? What practical (and not too costly, laborious) approaches exist today to bridge UI and semantic in the CRUD-heavy webapp (to be more specific)?

I am not even speaking of visualization per se. It's more about how an application can represent new kind of knowledge to the user, which has not been specifically foreseen at the webapp development time (like coming of new-super-something-social identity). To compare with traditional web: we do not need to program in support each time we have new URL in our app, we just need to support certain protocols and any URLs are just content.

Please, do not tell me the whole semantic web thingie is kind of utopia. One way or another there is a need to use stricter knowledge representations than text and google-like search. And whatever technology (semantic web, linked data, etc) will have the same challenges.

There is some research and experimental systems like ActiveRaUL and LESS (not to be confused with Less.js), but it is still unclear what approach should be taken.

It's not about replacing representation technology (which is HTML/CSS/Javascript), but rather UI-building approaches with the least "impedance mismatch" between tree-like / flat web-page space (screen space) and graph-like, dynamic semantic web model for knowledge. Data-heavy apps are challenging in itself, and hypothesis is that graph-like model may actually make more useful UI because it better matches human mental models. WWW itself is a large graph, but what about microlevel, one page.

Update: That said, Semantic Web thinking is forcing to map major classes and individuals to have their own URL in a web application (dereferenceable URI), where classes correspond to listings of individuals and pages for individuals represent their properties / annotations. So, part of the question is, should the temptation be resisted or just to let the mapping in a most natural, "web way"? (This is actually is not special to graph model, but also to hierarchical object systems like Zope.)

Update2: The Fresnel Vocabulary seemed to tackle the problem for tree-like GUIs. In a somewhat related question - https://stackoverflow.com/questions/26733978/how-to-display-rdf-data-described-by-fresnel-vocabulary - it is proposed to take a look at LDP (Linked Data Platform), but I fail to see how it helps. Systems like Callimachus, if I understand correctly, use some kind of conventional RDFa templates with ?vars in it for form templates...

答:
Semantic web is an approach that has made serious steps during the history of World Wide Web. The field of Artificial Intelligence has also progressed so that it has provided Semantic Web with tools capable to link the semantic information and create Agents that will be able to automate a lot of human everyday activities (e.g. shopping-appointments). However, Artificial Intelligence had created "extreme" expectations to the achievements it could make, that most of them are not considered feasible at all nowadays.

However, from your introduction, I felt that you think that Semantic Web is contrary to the modern technologies of Internet nowadays (relational databases, HTML, programming languages etc). This is not completely true. Semantic Web is not competitive to plain Web, it hopes to be complementary. For instance, the evangelists of Semantic Web believe that websites should be structured in the same way (HTML and CSS), however, this information should also be accessible in semantic ways (RDF-OWL). In the same way, the application of the website could be implemented using relational databases (or even noSQL). SPARQL would be used in several components of the Semantic Web (such as Intelligent Agents). To sum up, Semantic Web aspires that the knowledge of Machine Learning can be used so that semantic data are not manually extracted-created, but they would be automatically extracted using algorithms. As a result, Semantic Web can be seen as an enhancement of plain Web.

The real dilemma that delays the implementation of Semantic Web in all areas of World Wide Web is the following : Is the all this effort for creating algorithms that will automatically extract semantic information for the currently existing data worthwile ? Is the field of Artificial Intelligence progressed enough to aid in the development of Semantic Web's tools, such as Agents, or will all this semantic data be redundant ?

ContentLicense: CC BY-SA 3.0


答:
The value of refactoring comes up in multiple different ways.

It helps you make other changes later, so the X days the that feature would have taken would now take 2/3X days to complete. To use the agile terminology it increases velocity.

The explicit change listed would over time help since you would no longer need to maintain developers with VB6 experience, only those with C# experience.

It also helps in other less tangible ways like staff retention and recruiting. Would a job doing C# and VB6 be more or less attractive than a job doing just C#? Would you be more or less likely to take a job or stay at a job working on a nice code base or a lousy one?

Title: How to measure the potential value of refactoring

Body:
On an old,  large project with technical debt how can you reliably estimate or measure the benefit of refactoring code?

For example, say you have some components within a software stack solution written in an older language, and some later components written in a newer language. New features and bug fixes are constantly being added to this solution by a development team.

The developers suggest that replacing the existing old language components with the new version would be 'a good thing' However, no extra features would be added by this work and it will cost x dev-days.

A sales person suggests adding 'a great new feature'. the company measures the value of his suggestion by using a formula. ie. It will earn the company F million pounds, over t years at a cost of x dev-days work

How can the company cost up the refactoring proposal in a meaningful way? and under what circumstances is it likely to be the most profitable option for the company?


问:
What factors should influence how I determine when to abandon a small project with a friend?
I've found myself in a tough spot as of late. Been working on a game with a programming buddy for nearly 8 months now. We both started off as newcomers to programming around August of last year, he is a 2nd year CS student, I'm an IT support tech by trade and am a self-taught programmer with multitudes of books and online subscriptions.

The issue that I've been constantly seeing is that as we write out a chunk of code, it will often be a bit hacked together, have many failings, and if it's a brand new concept to one of us, full of naive solutions. This is fine, we are learning, I expect both of our code to be a bit hacked together on the firs or second pass. The problem presents itself when it comes to actually fixing and refactoring those hacked together behaviors.

My partner will hold onto his freshly cobbled together behavior, blatantly refusing to see any error the moment it starts to work. Claiming near perfection from a piece of structure I can't even try to use even if it had comments and appropriately named methods & fields. No matter how hard I try I just cannot get him to see the glaringly obvious flaws that will prevent any further changes or expansion of the behavior without completely breaking it and everything it's so tightly coupled to they might as well be in the same class. Hacked solutions perpetually stay hacked, poorly thought out designs stay the way they where when first conceived and tested.

I spend as much time babysitting new code as I do writing it myself, I'm a loss of what to do. My partner lost it tonight, and made it clear that no matter what, no matter the benchmark, no matter the common practice, no matter the irrefutable proof, his code will stay the way he first made it. Even if entire books have been written on why you want to avoid doing something, he will refuse to acknowledge their validity claiming it's just someones opinion.

I have a vested interest in our project, however I am not sure if I can continue to work with my partner. I seem to have three options open to me.

Stop caring about the codebase functioning past the point of compiling, and just deal with trying to maintain and parse behavior that's barely limping along. Hoping that once things start to seriously break he will see that and try to do more than just put a bandaid over the fundamentally flawed design.

Keep up the endless arguments over issues that have been figured out a decade ago by other much more capable individuals.

Stop programming on this project, abandoning nearly 10,000 lines of my code and countless hours slaving over design and try and find a new project on my own.

What approach can I take to determine if it is worth continuing on with this project with this person? Or what factors should influence my decision? We have written a lot of code and I do not want to give this up unless necessary.

答:
Shipped, imperfect code is better than perfect code on the whiteboard that never gets shipped.

That being said...

Those of you with more experience, or that have been in similar situations. What did you do? What would you recommend I do?

I would consider the following.

What is the purpose of this project? Fun? Money? To learn?

Are you actually accomplishing this purpose?

Is this person actually enabling you to better accomplish your goals?

How close are you to actually shipping?

Do these issues prevent you from launching? Or are they a matter of personal pride?

Are there benefits to working with someone on a voluntary basis when it's frustrating?

Stop programming on this project, abandoning nearly 10,000 lines of my code and countless hours slaving over design and try and find a new project on my own

Consider the above, try to think through the additional work required.

You need to figure out your priorities and determine if the issues related to working with this person are worth it. We can't figure this out for you.

My partner lost it tonight, and made it clear that no matter what, no matter the benchmark, no matter the common practice, no matter the irrefutable proof, his code will stay the way he first made it.

You know you don't want to work with this type of person.

You're doing a project like this presumably because you want to learn programming and find elegance in the craft itself.


答:
Firstly, you need to estimate the dev cost for the re-factoring as you would the sales driven feature request.

This may well be tricky to get accurate if it's a large job but, assuming you have sufficiently experienced people in the 2 technologies, it should be doable.

Secondly, you need an estimate of the cost of not re-factoring. If you were doing the estimates for me, I'd expect some level of metrics. For example, the difference between the average dev cost for VB code and for C# code over a quarter. Or some such. Will obviously depend on how accurately you track this.

With these 2 numbers, you can estimate the pay back period that the re-factoring will give you i.e. at what point will the re-factoring turn from a net cost to a net gain.

I can only guess as to how persuasive any given result would be. However, if it's less than a year it'll probably be quite strong, much more than 2 years then you may well struggle.

Additionally, it's probably worth adding other dimensions to help build your case. One that I've used in the past is seeing if any exit interviews cited the technology as a driver. If so, you can argue that the re-factoring will retain staff (hiring and training being v expensive).

Obviously, you can argue these things without supporting evidence but I find that it can make a huge difference to the impact of the case.


答:
It will earn the company F million pounds, over t years at a cost of x dev-days work

Which is ignoring maintenance costs, support costs, the cost of sales/marketing, and makes a whole lot of assumptions about how the feature will be taken in the marketplace.

But whatever; your question is clear enough about what you're looking for:

How can I make a business case for refactoring?

The main thing to realize is that time equals money. You can go straight to "5 developers 2 weeks = 80 hours * 5 developers * $50/hr -> $20,000" and that makes sense to business people. Smart business people will note that those 5 developers are being paid either way, with which you counter that it's not spending/saving the $20,000 - it's using the $20,000 in the most profitable manner. Anyways, on with the list.

Efficiency - Presumably, you can get more stuff done with C# than VB6. Better tooling, better libraries, whatever. Newer technologies tend to be better at things than older ones. If you can do stuff in less time, that means you're saving the company money.

Overhead - Coding isn't the only cost of software. Consider what happens when Windows 2020 comes out. How much time and effort are you going to spend getting that VB6 app working on it? How much more time and effort is that than a C# app? That is saving your company money.

Quality - Presumably, you can get stuff done with higher quality in C# than VB6 (or with a cleaner architecture, or whatever else your refactoring target is). Higher quality means less bugs. Less bugs means less cost to fix those bugs, less customer support costs to field those issues, less customer loss due to quality issues, increased sales due to a reputation for quality... all dollars for your company.

HR Savings - Let's face facts: nobody wants to work with that shitty VB6 app. That means more people will leave the company leading to time and money spent to replace them. That means it takes more time and money to hire new employees. Worst of all, it means you'll have developers who are totally fine committing career suicide working with that VB6 app. Those developers in turn hasten the death spiral of quality issues. Cutting turnover and hiring times saves your company money. Keeping complacent, crappy developers away saves your company.

Morale - Similarly, the programmers that are already there hate working in VB6. They'll do it, and they might even do it well. But it sucks. Maybe not for everyone, but certainly for some. That means more time spent browsing the web to recoup motivation. It means longer lunches. It means less getting stuff done while your programmers take longer to recover from the sucky work.

Capability - This is less applicable with technology driven refactors, but applies to architecture sort of refactors. Certain code problems actively prevent you from providing cool feature X to make tons of money. Maybe you can't scale. Maybe you can't get at the data to do cool informatics. Maybe the code is such a rat's nest that it is prohibitively difficult to actually do the work. Whatever. Sometimes you're at that point, sometimes you're driving straight towards that point. It's hard to translate to business-speak, but if you can the "this problem is preventing us from taking advantage of opportunities X, Y and Z" can be powerful.

All in all, it comes down to "this stuff will help us do our jobs better; if we do our jobs better, we can make/save you more money".


问:
Do I need a web-service for this case? Data-synchronization over multiple clients
I'm new in this area and a little bit confused about my current thoughts on a web-service implementation for my application. I want to synchronize all connected clients with the current data on a MySQL DB. I came up to use web-services as for coordination purposes, but I got stuck.

The way I tried to implement it is...

The web-service is running a deamon to check/listen on CRUD operations affecting DB data. Once an CRUD operation has been occured it undetakes to notify all the connected clients and each client in turn refreshes the JTable with current DB data and informs the user with the change that took place on the DB.

This is where I'm stuck...

The way I'm thinking it's (maybe?) wrong, since conceptually web-services are awaiting for client requests and then send him the corresponding response. But here, there is no client requests. The web-service just sends a response (noification), which must multicast since it's unaware of a "calling" client -there's no request.

Therefore, in order a client to send a request it must "cron" all the time the web-service if a change on the DB has been occured. Then the web-service responts as true or false with the CRUD details (CRUDEventFired(event_type, event_details)). But, this is not optimal as it will create big and (much of time) useless traffic especially when there is no CRUD operation occured. Also, there will be two different deamons (one in web-service and the other in client-app) that check/listen for the same type of event and that's redundant.

Also, with that implementation it seems that there's no need for a web-service at all and the code to check the DB for changes could be implemented in the client. On the other hand setting the client responsible for the DB changes would require to code the same functions in different platforms (desktop, ios, android, etc), while setting the web-service as the coordinator for data synchronization between clients would require to code only once the appropriate function and each client simply implement its own NotificationListener().

Is it wrong the way I'm thinking using web-services? How it should be changed? Do I even need to use web-services?

I attach my diagram for your convinience.

答:
I am not a specialist but here are my two cents. I assume that your webservice runs on a Java EE application server.

all the writes to the DB should come from your application server so you should be able to generate events in your code every time you write to the DB

instead of webservice which are best for queries from the client, you could use either websockets or a message queue (typically a JMS queue)

Although having the clients write to the DB directly may seem appealing at first (it's easier to understand) it can quickly become a mess. For example, making changes to your DB going forward may require upgrading all clients.


答:
Here are some ideas even if some of them are mutually exclusive.

Separate source responsibilities. If you work on Module A and him on Module B you can compete with your different styles. Is he releasing working features often? Does he reach a point where he needs to rewrite his code from scratch? Refactor the code from your modules and do not touch him's,

Let him do the maintenance of his worst code. If he does it successfully you have avoided an awful task. If he is not able he will feel the pain.

Consider it from a user or business point of view. In some cases you only need a viable product that google or Microsoft might buy. In other you are launching a product to market and supporting thousand of clients with buggy or hacked code will be hell. Is not the same if your code controls drones with nuclear missiles or makes happy videos for teenagers.

He does the classes, you do the tests. Refactoring code with tests is easier and safer. This way you won't need to look inside the code just the Junit bar. This assumes that A) you are programming tests, B) your colleague code is testeable. If you find hard to build the tests during the coding phase latter will be worse.

Go together to training or events. When you do not know the right way is quite natural use the only way you know. Seeing other's code might not solve everything but won't hurt to try.

Find your complementary strengths. Refactoring can sometimes be fun. If he writes things that at least work you might then do the refactoring. He can do spikes to explore solutions that do not end in production code.

He might not want to rewrite the code but he might agree to write the new code better. I understand that rewritting is hard, boring and can break things. Grow some islands of quality. This way he will have good examples of how to do things.

Use the boy scout rule. Do left things untouched unless you need to work on it. If a module is badly written but works and do not need to change leave it like that. If you need to fix a bug or complete a feature improve it a little. After some time the 20% of classes that you change 80% of the time will improve. More islands of quality.

We cannot suggest what is the best solution without knowing both of you. Good luck.

Title: What factors should influence how I determine when to abandon a small project with a friend?

Body:
I've found myself in a tough spot as of late. Been working on a game with a programming buddy for nearly 8 months now. We both started off as newcomers to programming around August of last year, he is a 2nd year CS student, I'm an IT support tech by trade and am a self-taught programmer with multitudes of books and online subscriptions.

The issue that I've been constantly seeing is that as we write out a chunk of code, it will often be a bit hacked together, have many failings, and if it's a brand new concept to one of us, full of naive solutions. This is fine, we are learning, I expect both of our code to be a bit hacked together on the firs or second pass. The problem presents itself when it comes to actually fixing and refactoring those hacked together behaviors.

My partner will hold onto his freshly cobbled together behavior, blatantly refusing to see any error the moment it starts to work. Claiming near perfection from a piece of structure I can't even try to use even if it had comments and appropriately named methods & fields. No matter how hard I try I just cannot get him to see the glaringly obvious flaws that will prevent any further changes or expansion of the behavior without completely breaking it and everything it's so tightly coupled to they might as well be in the same class. Hacked solutions perpetually stay hacked, poorly thought out designs stay the way they where when first conceived and tested.

I spend as much time babysitting new code as I do writing it myself, I'm a loss of what to do. My partner lost it tonight, and made it clear that no matter what, no matter the benchmark, no matter the common practice, no matter the irrefutable proof, his code will stay the way he first made it. Even if entire books have been written on why you want to avoid doing something, he will refuse to acknowledge their validity claiming it's just someones opinion.

I have a vested interest in our project, however I am not sure if I can continue to work with my partner. I seem to have three options open to me.

Stop caring about the codebase functioning past the point of compiling, and just deal with trying to maintain and parse behavior that's barely limping along. Hoping that once things start to seriously break he will see that and try to do more than just put a bandaid over the fundamentally flawed design.

Keep up the endless arguments over issues that have been figured out a decade ago by other much more capable individuals.

Stop programming on this project, abandoning nearly 10,000 lines of my code and countless hours slaving over design and try and find a new project on my own.

What approach can I take to determine if it is worth continuing on with this project with this person? Or what factors should influence my decision? We have written a lot of code and I do not want to give this up unless necessary.


答:
It sounds pretty hopeless.  I would probably give up and move on if I felt about it as you do; there definitely comes a time to walk away and you may be there.

If you're not ready to walk away yet, you need to find a way to come to better agreement about your process.  It sounds like you have coding standards, but not agreed-upon standards.  Next time you come to a crossroads, next time you want to monkey with a bit of code and your buddy wants to leave it alone, shoot for a conversation along the following lines:

douglas: I want to change it because X, which is right here in our guidelines.

buddy: It's fine how it is.

douglas: So you're saying we should change the guidelines?

buddy: No, I just think it's fine how it is.

douglas: So what are the guidelines for?

buddy: I don't know - you wrote them.

douglas: What guidelines would you write?

buddy: I wouldn't write guidelines.  It's a waste of time.

douglas: So we should just throw away the guidelines and write whatever crap we're thinking at the time?

buddy: This isn't crap.

douglas: Is it perfect? Is it ideal?

buddy: It gets the job done; let's move on to the next feature.

douglas: Is there anything we can agree on, that X is good code and Y is bad code?

buddy: Leave me alone; I just want to code!

Well, that didn't go well, did it?  I guess the feeling I have is that you and Buddy want different things.  If there's anything you can agree on, great; start from there and build on it.  But you can't make him agree to want what you want - any more than you could make yourself want what he seems to want.  If you can find that common desire, and come to common agreement from there, maybe you can work together.

douglas: What do you want?

buddy: I just want to code.

douglas: I want to code, too, but I want to feel proud of my code.

buddy: I'm proud of my code.

douglas: Here's a function I'm proud of - what do you think of it?

buddy: Well, it's OK, but you shouldn't recalculate X inside the loop; it's inefficient.

douglas: So are you saying we should always calculate constant values outside loops?

buddy: Well, duh!

douglas: Would you think that ought to be in our guidelines?

buddy: Of course.

douglas: OK, I'll add it to our guidelines, and I'll update my code...

douglas: How is it now?

buddy: Fine.

Now Buddy is contributing to the guidelines (however indirectly), and so he's got a bit of a sense of ownership.  Maybe - just maybe - he will start to take them more seriously.  I think I'd be inclined to wipe the slate and start over with the guidelines, letting most or all of them come from Buddy at first.  Go ahead and write shit code so he feels the need to add to the guidelines; let them come from him.  Maybe then he'll start to understand the reason for them.

But if you'd rather give up and move on - that might not be such a bad option either.


答:
I like all of the answers so far.  Taking one of the points from enderland's answer:

Are there benefits to working with someone on a voluntary basis when it's frustrating?

I'd like to take this time to plug for the code review stack exchange.  It's a wonderful place where you can get your code critiqued by professionals.  And honestly, a lot of the code reviews there are hugely helpful to those involved - the askers, the answerers, and those who stumble by and read them.  You rarely get such useful reviews in a professional setting(which may just be the case at the places I've worked for whatever reason).

My bit of advice is to post some of your code for review.  I wouldn't suggest using it as ammo to prove this guy wrong - I doubt he'll take it to heart - but you can get very useful information both on code you've written and code he's written.  I'd recommend submitting the pieces of code that you two fight over the most.  In all likelihood, you're both wrong to some degree and you can use the review as a way of getting an objective third party to step in.  This will accomplish a few things:

You can disconnect from the situation's emotional tension.

You get real-time professional advice. A big boost to what you're learning.

Someone will tell you you're wrong.  Which is good, because anyone who does programming for any length of time is going to hear this.  You can handle it poorly like this guy you're working with, or you can learn to deal with it.

I think if you use the code reviews the right way, you have a lot to gain by dealing with this extremely frustrating person.  And it's far more interactive than a book or website that says "do this, because it's the right way most of the time".

Similarly, there's the game developer stack exchange.  Not so much a place to post code for review, but to ask about concepts/ideas you're struggling with.  Again, that place is hugely helpful for all involved.

You may have seen both of these sites before; I just wanted to make sure they're part of your toolset.


问:
How do you pass/fail performance tests?

Example:

A certain test is run five times on the current build, to compare it to release 1.0, where the same test was also run five times.

Build 1.4

22 ms, 26 ms, 23 ms, 25 ms, 20 ms

Release 1.0

15 ms, 18 ms, 16 ms, 20 ms, 17 ms

Question

The requirement is that Build 1.4 is no worse than Release 1.0.

How would I test that? I've seen different methods used, including simple average comparison and statistical T-Tests (assuming normal distributions).

None of the tools, i.e. testing frameworks and CI systems, I've come across provide anything to help with calculating and passing/failing such tests. Why? Performance testing seems to be popular, so how are people approving or rejecting them?

Often it's way too impractical or even impossible to go in and manually determine acceptable ranges or distributions for every test.

答:
The answer to your question is highly case-specific. You already seem to be aware of various performance testing techniques.

You must determine what your expected measurements are. It may be acceptable to start by saying "our expected measurement is the current measurement" and then just track changes over time. If it's "impractical or even impossible" to get an expected value then I don't see how the performance measurement would be meaningful.

Title: How do you pass/fail performance tests?


答:
Performance testing seems to be popular

It's popular in theory. In practice, I've seen only a handful of automated performance tests done and they were done haphazardly.

How would I test that Build 1.4 is a pass/fail for this test?

You define a pass/fail criteria. If you need the tests to be consistent, define some failure criteria and measure. If you need the tests to be at least X fast (where X is ideally some metric gathered by usability testing) then do that. If not X worse than last build (not recommended in automated tests, since it requires memory of past builds) then do that.

It is trivial to write up helper code to deal with measurements and/or statistics. But you still need to define the criteria, just like any other test. It's like asking to automatically define pass/fail criteria for business rules - computers do a poor job at that since all they know about business rules is what you tell them.

Title: How do you pass/fail performance tests?

Body:
Example:

A certain test is run five times on the current build, to compare it to release 1.0, where the same test was also run five times.

Build 1.4

22 ms, 26 ms, 23 ms, 25 ms, 20 ms

Release 1.0

15 ms, 18 ms, 16 ms, 20 ms, 17 ms

Question

The requirement is that Build 1.4 is no worse than Release 1.0.

How would I test that? I've seen different methods used, including simple average comparison and statistical T-Tests (assuming normal distributions).

None of the tools, i.e. testing frameworks and CI systems, I've come across provide anything to help with calculating and passing/failing such tests. Why? Performance testing seems to be popular, so how are people approving or rejecting them?

Often it's way too impractical or even impossible to go in and manually determine acceptable ranges or distributions for every test.


问:
What Type of Report or Documentation to Expect from my Programmers
First, I am not a programmer nor do I have any programming experience. I am an entrepreneur that had a website idea and hired programmers to custom build it. It has been going on for the last one year now. It uses Wordpress with some plugins such as Buddypress, Bbpress, etc, but a lot of custom codings as well.

I give the programmers tasks and they do them and the tasks work as I want, but they don't present any report or documentation as to what they did and how it was all coded, etc.

But my problem is - what if they suddenly disappear and I have to get other programmers to continue working on the site? Can the new programmers do a good job of taking over when there's no report or documentation, etc?

Of course there's report from me to the programmers telling them what to do and what functions I expect the tasks to perform. But when done, they don't present me with any report or documentation. They just say the task is done and I check and it's done.

If such report or documentation is required, what type should I request from these current programmers?

Or am I being unnecessarily paranoid?

答:
Hello if i understand you very well you want to be sure when your current programers are no more there to manage your website you can hire someone else and it will be easy for them to write and not re-inventing the wheel. good one.

good programs are to themselves a good documentation, sorry there might not give you a paper documentation but its in the coding, you might not know it but the programmers will. just always remind them to keep proper documentation.
when the new programmer comes he knows were to find the documentations.


答:
tl;dr you should arguably abandon the project.

Without knowing any more about this then you've told us, I'd speculate that the friction you're experiencing is experience-related.

Even though you're not a programmer by profession as an IT pro you've probably learned the hard way about doing things right the first time, your reference to your future self indicates you've screwed him/her over in the past and learned not to.

Your 2nd year CS student, even if quite gifted, probably lacks the perspective of having done that (if you're like me, repeatedly :).

He/she will never really believe in the value of fixing things as you go until he/she has burn scars from failure to do so or is mentored in a culture with exceptional engineering discipline, or both.

This person may be your programming peer, but is not your project peer, so doing this game as a peer project is likely a lost cause. Unless you are prepared to just eat the future cost. Maybe the relationship is valuable enough to you. In that case give hem/her enough rope to hang himself/herself and step in to help clean up the mess when that person is forced to acknowledge the problem.

Otherwise bail and do a project with a peer, or do a mentor/mentee project where that's the dynamic from the outset.


问:
How to explain design decisions when refactoring code
I am working on a colleague to refactor the following code, I am trying to turn this into a teaching experience as well.

Original Code

```<code>public class WidgetRepository
{
    public Widget GetWidget(int id)
    {
        Widget widget;

        if (HttpContext.Current != null)
        {
            widget = (Widget)HttpContext.Current.Cache["widget_" + id];
        }

        if (widget == null)
        {
            widget = GetWidgetImpl(id); // some db call

            if (HttpContext.Current != null)
            {
                HttpContext.Current.Cache["widget_" + id] = widget;
            }
        }

        return widget;
    }
}
</code>```

The most obvious thing that sticks out is that you have your repository knowing about ASP.NET concepts, which is particularly bad as this repository is used by non-ASP.NET code in some scenarios.

Refactored Code

I decided to refactor the code as follows:

```<code>public class WidgetRepository
{
    private readonly ICacheProvider _cacheProvider;

    public WidgetRepository(ICacheProvider cacheProvider)
    {
        _cacheProvider = cacheProvider;
    }

    public Widget GetWidget(int id)
    {
        var widget = _cacheProvider.Get<Widget>("widget_" + id);

        if (widget == null)
        {
            widget = GetWidgetImpl(id); // some db call

            _cacheProvider.Add("widget_" + id, widget);
        }

        return widget;
    }
}

public interface ICacheProvider
{
    T Get<T>(string key);
    void Add<T>(string key, T item);
}

public HttpCacheProvider : ICacheProvider
{
    private readonly Cache _cache;

    public HttpCacheProvider(Cache cache)
    {
        _cache = cache;
    }

    public T Get<T>(string key)
    {
        return (T)_cache[key];
    }

    public void Add<T>(string key, T item)
    {
        _cache[key] = item;
    }
}

public NullCacheProvider : ICacheProvider
{
    public T Get<T>(string key)
    {
        return null;
    }

    public void Add<T>(string key, T item)
    {
    }
}
</code>```

My Justification

I explained the following benefits to the refactored code:

Promotes Open / Close: we can change the caching implementation if we want to use something else in the future (memcached, etc.)

Lower cyclomatic complexity: less if statements

Not mixing ASP.NET technology with data-access technology

Refutations / Concerns

However, I got the following refutations:

We're not going to use a different caching technology in the foreseeable future.

It's more lines of code (therefore it's more complex)

You need to setup the dependencies (complexity is moved, not removed)

There's already tonnes of code that uses HttpContext.Current, so this code does not follow the existing (anti-)pattern

We're still "using" ASP.NET within data-access code.

My Questions

Personally, I find that the pros outweigh the refutations, however, I would like to be able to address the refutations in order to help educate them.

My questions are:

Am I justified in making the refactoring (assuming we have time allocated for cleaning up code)?

How do I respond to the various refutations?

答:
Am I justified in making the refactoring (assuming we have time allocated for cleaning up code)?

Are you doing anything else in this code?

If not, this seems not worth the effort. Your peer is likely right that you aren't ever going to use other things - and that you should keep things consistent.

If you are, then cleaning this stuff up too seems like a clear benefit for minimal effort/risk (though you might need to add a default constructor that uses the HttpContext to make it minimal impact).

How do I respond to the various refutations?

Yes, but that's no reason to couple something unnecessarily when it's so easy to do things better.

More code is not necessarily more complex. In this case, it is more complex, but trivially so. And in exchange, it makes unit testing much easier and the code more flexible.

Sure, it's just shifting the problem around, but it's shifting the problem to a more decoupled form. It lets you deal with parts of the problem in isolation rather than having a larger more unweildy problem.

"This is what we have always done" is not an excuse to perpetuate bad code/design/anything. Yes, you should aim to keep code consistent, but in this case you should push for consistency with the decoupled pattern rather than the direct HttpContext access. Yes, that's more work - but it's the right thing to do. If your peer pushes that there's not time for all that now (and has an alternative that is better) then maybe agree to do it later (and add a ticket/bug/story to actually do it).

See #4.


答:
Your class is clearly superior because you can inject a mock cache provider.

Although the HttpContext.Current null check will stop an exception being thrown when the repository or classes which use it are tested. So you aren't offering any concrete benefit.

I wouldn't attempt to justify your code, or respond to the refutations. You've spent some time re-factoring, your changes are clearly in tune with accepted practices, re-factoring is a good thing. What's to complain about?

Given that you have had to justify this and the nature of the refutations I think its clear that really there isn't any time allocated for refactoring. This is the classic 'make it fast' AND 'make it good' AND 'don't spend more money' tricotomy.

Title: How to explain design decisions when refactoring code

Body:
I am working on a colleague to refactor the following code, I am trying to turn this into a teaching experience as well.

Original Code

```<code>public class WidgetRepository
{
    public Widget GetWidget(int id)
    {
        Widget widget;

        if (HttpContext.Current != null)
        {
            widget = (Widget)HttpContext.Current.Cache["widget_" + id];
        }

        if (widget == null)
        {
            widget = GetWidgetImpl(id); // some db call

            if (HttpContext.Current != null)
            {
                HttpContext.Current.Cache["widget_" + id] = widget;
            }
        }

        return widget;
    }
}
</code>```

The most obvious thing that sticks out is that you have your repository knowing about ASP.NET concepts, which is particularly bad as this repository is used by non-ASP.NET code in some scenarios.

Refactored Code

I decided to refactor the code as follows:

```<code>public class WidgetRepository
{
    private readonly ICacheProvider _cacheProvider;

    public WidgetRepository(ICacheProvider cacheProvider)
    {
        _cacheProvider = cacheProvider;
    }

    public Widget GetWidget(int id)
    {
        var widget = _cacheProvider.Get<Widget>("widget_" + id);

        if (widget == null)
        {
            widget = GetWidgetImpl(id); // some db call

            _cacheProvider.Add("widget_" + id, widget);
        }

        return widget;
    }
}

public interface ICacheProvider
{
    T Get<T>(string key);
    void Add<T>(string key, T item);
}

public HttpCacheProvider : ICacheProvider
{
    private readonly Cache _cache;

    public HttpCacheProvider(Cache cache)
    {
        _cache = cache;
    }

    public T Get<T>(string key)
    {
        return (T)_cache[key];
    }

    public void Add<T>(string key, T item)
    {
        _cache[key] = item;
    }
}

public NullCacheProvider : ICacheProvider
{
    public T Get<T>(string key)
    {
        return null;
    }

    public void Add<T>(string key, T item)
    {
    }
}
</code>```

My Justification

I explained the following benefits to the refactored code:

Promotes Open / Close: we can change the caching implementation if we want to use something else in the future (memcached, etc.)

Lower cyclomatic complexity: less if statements

Not mixing ASP.NET technology with data-access technology

Refutations / Concerns

However, I got the following refutations:

We're not going to use a different caching technology in the foreseeable future.

It's more lines of code (therefore it's more complex)

You need to setup the dependencies (complexity is moved, not removed)

There's already tonnes of code that uses HttpContext.Current, so this code does not follow the existing (anti-)pattern

We're still "using" ASP.NET within data-access code.

My Questions

Personally, I find that the pros outweigh the refutations, however, I would like to be able to address the refutations in order to help educate them.

My questions are:

Am I justified in making the refactoring (assuming we have time allocated for cleaning up code)?

How do I respond to the various refutations?


问:
How do you manage your knowledge base?
As programmers we have a lot of inputs:

Ebooks

Code snippets

Interesting emails

Documents

Web articles

Blog posts

StackOverflow questions

Podcasts
...

Which tools do you use to store, organize, search and consult all of this stuff?

Is there a silver bullet solution to handle this huge amount of data?

答:
Dropbox for files (http://www.dropbox.com)

PpcSoft iKnow for snippets of information (http://www.ppcsoft.com)

Opera browser for browsing and bookmarks (with built-in RSS reader) (http://www.opera.com)

ContentLicense: CC BY-SA 2.5

Title: How do you manage your knowledge base?


问:
How do I convince my users not to use a sketch UI?
I recently worked on a prototype of a new system using Sketchflow, and now some key stakeholders are pushing for a sketched look & feel in the final product. To make matters worse, the people viewing the prototype were asked to provide feedback on the sketched look & feel by way of a fairly leading survey question, to which 80% of the responses were positive.

It's for an enterprise application that will mostly be for internal clients, but is also intended to be used by some external clients.

The main reasons I have for it thinking it's a bad idea are:

It doesn't look polished or professional

The significant effort involved in skinning an actual application in the sketched style

The sketched style doesn't make efficient use of screen real-estate

I've been trying to figure out what the appeal could possibly be, and the only thing I can come up with is that people are attracted to the simplicity of it -- especially when compared with the existing system(s) it will be replacing.

Can anyone point me in the direction of evidence of why using a sketch look & feel is a bad idea? Ideally something based on UI research. I'm worried that my voice isn't going to be listened to unless I can point to something concrete.

[Edit]

I should probably add that the difficulty of skinning the application is compounded by the fact that it is intended to be delivered as one or more Silverlight webparts in a Sharepoint site. Getting a consistent sketched look & feel across both technologies could be very difficult.

[Edit]

Just in case anyone's not sure about what a Sketchflow prototype looks like (and therefore what the people in question are asking for) they're essentially asking for a production application to have a pencil-sketch wireframe look & feel.

答:
The skinning issue is the biggest problem for the same reason skinning is almost always a bad idea. </p>

<p>Consult the tome and print off a few pages.  I wouldn't go into saying there is a problem with sketchiness since that's just some sort of fad and it works in Michael Cera movies. </p>

Body:
The skinning issue is the biggest problem for the same reason skinning is almost always a bad idea.

Consult the tome and print off a few pages.  I wouldn't go into saying there is a problem with sketchiness since that's just some sort of fad and it works in Michael Cera movies.


问:
How do you balance between "do it right" and "do it ASAP" in your daily work?
I find myself pondering over this question from time to time, again and again. I want to do things the right way: to write clean, understandable and correct code that is easy to maintain. However, what I end up doing is writing patch upon a patch; just because there is no time, clients are waiting, a bug should be fixed overnight, the company is losing money on this problem, a manager is pressing hard etc., etc.

I know perfectly well that in the long term I am wasting more time on these patches, but as this time spans months of work, nobody cares. Also, as one of my managers used to say: "we don't know if there will be a long term if we don't fix it now."

I am sure I am not the only one entrapped in these endless real/ideal choice cycles. So how do you, my fellow programmers, cope with this?

UPDATE:
Thank you all for this interesting discussion.
It is sad that so many people have to choose daily between a quantity and a quality of their code. Still, surprisingly many, people think it is possible to win this battle, so thank you all for this encouragement.

答:
The job is not right for you.

Low quality code written "because there is no time, clients are waiting, a bug should be fixed overnight, the company is losing money on this problem, a manager is pressing hard" is a symptom of a poorly managed company.

If you are willing to take pride in your work and write high quality code, then the best thing to do is find an employer who understands that and will pay you to do it.


答:
To add additional points to all the great answers:

How much more effort will it take to finish the project? Note that finishing the "last 10%" takes much much longer than people expect. That includes play testing/tuning, usability fixing, coping with a variety of target platforms, releasing, ... If it's an iOS game, then there's code signing and getting through Apple's review. Honestly, finishing can take as long as the first "90%". And it'll be extra difficult if the code is as bad as you suggest. (Can you start play testing it now?)

Realistically, how likely is it that people will enjoy your game?

Beware of the "sunk cost heuristic". Evaluate that 10,000 line-of-code investment in light of the big picture, looking back on a finished product, and without undue optimism.

Can you keep going if it takes another 3 years? You two have different development styles (not a good team match). It sounds like you're near the end of your patience and if you keep going, it could be difficult to remain friends.


答:
Honestly if its their application and that is why they want, I would just do it their way.

If you wish to try and influence them otherwise, do a mockup of a different UI and show it to them along with your arguments against the sketchy UI.

Try and put it in terms they'd understand. For example, instead of saying it would take significant effort to reskin the application, just tell them the design adds an additional X days/weeks to the production time. Or instead of talking about screen realestate, show them an example of how cluttered it would look compared to your alternative design. Afterall, a picture is worth a thousand words.

Title: How do I convince my users not to use a sketch UI?

Body:
I recently worked on a prototype of a new system using Sketchflow, and now some key stakeholders are pushing for a sketched look & feel in the final product. To make matters worse, the people viewing the prototype were asked to provide feedback on the sketched look & feel by way of a fairly leading survey question, to which 80% of the responses were positive.

It's for an enterprise application that will mostly be for internal clients, but is also intended to be used by some external clients.

The main reasons I have for it thinking it's a bad idea are:

It doesn't look polished or professional

The significant effort involved in skinning an actual application in the sketched style

The sketched style doesn't make efficient use of screen real-estate

I've been trying to figure out what the appeal could possibly be, and the only thing I can come up with is that people are attracted to the simplicity of it -- especially when compared with the existing system(s) it will be replacing.

Can anyone point me in the direction of evidence of why using a sketch look & feel is a bad idea? Ideally something based on UI research. I'm worried that my voice isn't going to be listened to unless I can point to something concrete.

[Edit]

I should probably add that the difficulty of skinning the application is compounded by the fact that it is intended to be delivered as one or more Silverlight webparts in a Sharepoint site. Getting a consistent sketched look & feel across both technologies could be very difficult.

[Edit]

Just in case anyone's not sure about what a Sketchflow prototype looks like (and therefore what the people in question are asking for) they're essentially asking for a production application to have a pencil-sketch wireframe look & feel.


问:
Why I need to make method of my class private, If I need to access it throughout my application?
I am going through the beginners tutorial for C# from a website
http://www.homeandlearn.co.uk/csharp/csharp_s10p1.html
On chapter of classes, it makes the method of class private and then use property to get and set values. I am unable to understand why I need to make anything private in my class if I have to use/reuse it throughout the projects?

I am not asking for getters and setters, I am more concern about why I need to use Private keyword if all things are working fine with Public in tutorial example.

答:
The most important reason for limiting public access is to reduce the coupling in your application. By only exposing a select set of public methods or properties, you limit the number of connections between different classes.

There is widespread confusion about this, where many people believe that the purpose of private access modifier is to prevent other classes from accidentally breaking your class or data, like some kind of security or data protection. That is at most a very minor benefit in rare circumstances.

The real purpose is to reduce coupling, which in turn makes it easier to make changes to the code later.
Read up on Encapsulation, Indirection, Single responsibility


问:
Implementing "Trending Items" using linear regression in SQL Server
I'm building an MVC .NET website where people can rate and review movies (similar to IMDb). I'm using SQL Server for the back-end.

I'll be implementing a feature where the homepage displays trending movies, i.e. movies which have been positively rated within a particular time-period (let's say last 7 days).

I'll be using a stored procedure which implements linear regression to accomplish that.
My relevant SQL tables are the following:

Movie - PK Movie_ID, stores movie information

User - PK User_ID, stores user information

Rating - stores rating instances in the form of:

PK Rating_ID | FK Movie_ID | FK User_ID | RatingNo | Updated_Dt

```<code>  1             5            10          7     15/12/2014 16:04:24
</code>```

The above row would translate to "User with ID 10 gave movie with ID 5 a rating of 7/10 on 15/12/2014 16:04:24".

I also have a function to calculate the average score of a movie in the form of AVG_Rate = sum of all ratings (for a given movie) / count of ratings (for a given movie).

My question is this: Given the provided table structure above, what would be the best way to implement "movies trending this week"? I can think of two ways at the moment:

Create a permanent table to run linear regression on:

Movie_ID | AVG_Rate | Updated_Dt

Whenever a new rating row is added in Rating, also insert a new row in the new table, but instead of storing the actual rating, store the new calculated AVG_Rate instead:

Movie_ID | AVG_Rate | Updated_Dt

```<code>1           7.8    15/12/14 17:00:00
1           7.6    15/12/14 17:01:00
1           7.9    15/12/14 17:03:00
</code>```

...And so on. I can then use the new table to check for linear regression of a given movie. In terms of the table becoming too large over a period of time, I can have the table only hold 7 days worth of data at any given time (by e.g. backing up every 7 days and deleting data older than a week).

Create a temporary table to run linear regression on:

Same logic as above, except that the table is created temporarily on the fly whenever the stored procedure for getting trending movies is invoked. The AVG_Rate changes for each movie can be calculated directly from the Rating table.

I'm skeptical about which approach would work the best (I'm not advanced in SQL) and also not sure whether any of these two solutions are the way to go.

Any help & guidance would be greatly appreciated. Thanks!

答:
I believe this is a perfect use case for a view, in other words a "virtual table" defined by an SQL query on real tables in the database.

By default a view is generated from the real data every time a query needs to be executed on it, but some RDMSs support views with caching/precomputing/etc. Oracle calls these "materialized views", and SQL Server calls them "indexed views".

To get a little more specific, Improving Performance with SQL Server 2008 Indexed Views says that:

Indexed views can increase query performance in the following ways:

Aggregations can be precomputed and stored in the index to minimize
  expensive computations during query execution.

Tables can be prejoined and the resulting data set stored.

Combinations of joins or aggregations can be stored.

You may not need any of the huge performance improvements they claim, but this gives us a concrete idea of what SQL Server's indexed views are capable of, so I think it's fair to assert that an indexed view is functionally equivalent to your option #1 of creating an additional table, while a non-indexed view is functionally equivalent to your option #2 of creating a temporary table every time. Except that it's probably much easier to switch between a regular view and an indexed view than it is to switch between a permanent table and a temporary table, so at the very least you'll probably save yourself a some time experimenting with your options this way.

This SO answer has some more helpful links on the subject.


答:
Benefits of having a refactored system

You make a business case for refactoring by comparing the business bottom-line benefits between doing and not doing it. It means either reduction of current real costs, or an increase in future real cash inflow.

The key budget items affected by refactoring are the follows:

Maintenance costs - if the current system is a fragile pile of spaghetti, and it is observable in practice that fixing small bugs (both in development and operations) takes a large amount of man-hours, then it could be expected that the costs of such maintenance will be smaller for a "properly re-designed" system.  Take a look at what your annual pure maintenance costs are, and how they could realistically change after the rewrite.

Cost of adding new features - again, if the current system design and structure makes it unreasonably time-consuming to write new features, then a rewrite might provide savings. Take a look at your planned budget for new features, but be realistic - if you claim that you'll see a 50% improvement then expect to actually develop features in x man-months that earlier took 2*x man-months to realize; such promises may be hard to keep.

Software quality impact on sales - if the current system is frequently causing customer-visible problems e.g. crashes or downtime despite adequate maintenance effort, then a rewrite can be a solution. IF this is a major issue, then the same sales people can quantify the value of a 'feature' called 'more stable product'.

If the three points above don't reach the expected cost of rewrite (and more; opportunity cost of spending x dev-days on not-features is equal to the value of those features, which is larger than the pure cost of the x dev-days) then I'm afraid that that's it - the expected savings don't justify the rewrite.

Also, if your roadmap doesn't show a need for 'as much as you can provide' new features, then the savings should be in a form 'it used to take 10 people to do all the required stuff, but after the rewrite we'll be able to do the same with only 6 people'. If you can "sell" more development projects than you have developers, then improving efficiency allows you to develop more things, but if the business with the current resources is already able to develop all the things that bring extra value, then the only financial benefit can come from paying less people or having cheaper people.


答:
Assuming you decide to abandon the project:

Fork the code and refactor it, using it as a 'before/after' portfolio item

Since the goal was (mainly or partly) to learn programming and since learning something takes 2-4x as long as doing something you know already, that work is not really wasted.

'Sunk cost attachment' (the investment you've already made in a venture before learning it was a bad idea) is one of the most common human errors in decision-making

To keep the friendship, frame your decision as prioritizing the friendship over coding


答:
There's more than one way to skin a cat.  Try again until you find a solution that resolves everyone's concerns.  Part of the problem is you haven't really broken the coupling on the caching code all the way.  I would start with something like this:

```<code>public class WidgetRepository
{
  public Widget GetWidget(int id)
  {
    return Cache.GetOrCreate<Widget>("widget_" + id, () => GetWidgetImpl(id));
  }
}

public static class Cache
{
  public static T GetOrCreate<T>(string key, Func<T> createFunc)
  {
    if (HttpContext.Current == null)
    {
      return createFunc();
    }

    T result = (T)HttpContext.Current.Cache[key];

    if (result == null)
    {
      result = createFunc();
      HttpContext.Current.Cache[key] = result;
    }

    return result;
  }
}
</code>```

I don't know C#, so there may be a cleaner way to accomplish this same idea (and please ignore syntax problems), but you get the point.  Here the lines of code are comparable, but I've separated the caching concern out into a function call, one that should be highly reusable if this pattern repeats as often as you've implied.  It follows YAGNI on ever needing a different kind of cache, yet provides a separate place for making that change.

If you really need a separate repository with no connection to caching at all, you can make it a parent class of WidgetRepository.  If you ever need to support multiple kinds of caches simulataneously, then you can do the injection instead of using a static class.  No need to go all interface crazy until you actually need it.

Again this is just a starting point.  My point is, you should be able to find a way to make everyone happy.

Body:
There's more than one way to skin a cat.  Try again until you find a solution that resolves everyone's concerns.  Part of the problem is you haven't really broken the coupling on the caching code all the way.  I would start with something like this:

public class WidgetRepository
{
  public Widget GetWidget(int id)
  {
    return Cache.GetOrCreate<Widget>("widget_" + id, () => GetWidgetImpl(id));
  }
}

public static class Cache
{
  public static T GetOrCreate<T>(string key, Func<T> createFunc)
  {
    if (HttpContext.Current == null)
    {
      return createFunc();
    }

    T result = (T)HttpContext.Current.Cache[key];

    if (result == null)
    {
      result = createFunc();
      HttpContext.Current.Cache[key] = result;
    }

    return result;
  }
}

I don't know C#, so there may be a cleaner way to accomplish this same idea (and please ignore syntax problems), but you get the point.  Here the lines of code are comparable, but I've separated the caching concern out into a function call, one that should be highly reusable if this pattern repeats as often as you've implied.  It follows YAGNI on ever needing a different kind of cache, yet provides a separate place for making that change.

If you really need a separate repository with no connection to caching at all, you can make it a parent class of WidgetRepository.  If you ever need to support multiple kinds of caches simulataneously, then you can do the injection instead of using a static class.  No need to go all interface crazy until you actually need it.

Again this is just a starting point.  My point is, you should be able to find a way to make everyone happy.


问:
How to backup data and images in this project?
I have MS C# and MS SQL 2008 database project. It can capture employees' records with pictures of more than 1000 records.

Presently, I'm able to capture say 150 records on PC1 using my installed C# application, save the records into XML or CSV file format. My friends are able to continue registration or entering (i.e from 151 to 1000) after restoring or uploading the information contained in that XML or CSV using another copy of my C# application installed on their laptops at another location.

How can the content of the file be encrypted or hidden  from users viewing its content except for my C# app reading or writing to this said backup files.?

答:
To answer your first question, that's simple, encrypt the file. Use a symmetric key that is shared between the application you use and that your friends use. Only someone with the key can read the data. Where you store the key depends on how paranoid you are.

The simplest is simply to hardcode the key into the application. If you're concerned about hackers accessing it however, that would be nowhere near secure enough.

To answer your second question, there's two components to what you're storing from what I understand of your question: a picture, and data. The picture you should store as binary, probably PNG format would be the best option. The data I'd store as JSON. You's want some way of bundling the two sets of data to each other, and the whole set of data into a container. Plus some compression for the JSON.

So that screams for a ZIP file, and conveniently, you can also encrypt ZIP files.

So, I'd create two files, with the same name, but different extension for each record (e.g. Record1.json and Record1.png), and place them all into an encrypted ZIP file using SharpZipLib or similar (https://github.com/icsharpcode/SharpZipLib/wiki/Zip-Samples).

You didn't really indicate how many records we're talking here, if it's thousands you might want to create a directory structure using a search tree for the record index. So, if for example you search for records by the surname, you'd use the first letter or two of the surname as the first folder name, to speed access and reduce the time to iterate all the records.


答:
You should just keep doing your code the way you think is right, with comments and such and making a copy of you version of the code (in case he changes your code).

Do not fight, don't get mad, just smile when you see his poor decisions.

Only complain as a user, if it is working don't complain.

Don't give up either, it is important to get used to people that is different from you, that will happen in a real job.


问:
Share some fields but others unique to owner of instance
I've been programming for many years and this is sort of a strange need and I've never seen anything like this but I have a game where there are abilities that you can do. There is an ability class that stores data like Name, DamageType, DamageValue, Cooldown, CurrentCooldown. It's a very generic class where the instances I make really define the ability.

The thing is stuff like Name, DamageType, DamageValue, & Cooldown are values that can be defined once for the ability itself and never changes after that instance is created. However, CurrentCooldown would be owner specific. If 2 actors use this ability then each would need their own instance of CurrentCooldown but not their own instance of the other fields. Yes, I COULD just make 2 instances of this Ability but there is no real need for that as those other fields won't change.

Ideally I would make a list of abilities and just make each ability 1 time, and then tell each actor which ability they have. All the details for that ability is there and will be the same and shared, but the CurrentCooldown needs to be instanced per actor.

It would be nice to be able to make some fields "owner" specific. I guess a solution would be to make a dictionary where the name of the ability the actor has is the key and the value is the cooldown for that. I'm wondering if there are other ideas around this that people have and I'm not able to think about?

答:
This sounds very similar to a flyweight pattern.

What you do is create ability objects that hold the data defining what that ability is and store them in an object pool for easy reuse.

The owner does not directly contain an ability, it creates an object that encapsulates the ability but with owner-specific state such as the current cooldown or any other overrides (maybe the owner has a damage boost?).

Advantages:

You can define an ability once per application run, not once per owner object. Less complexity in the initialization logic.

Ability state is guaranteed to be consistent between owners because they are using the same Ability objects.

Slight memory savings because data is not duplicated. Probably nothing to write home about, compared to 20 years ago when the flyweight pattern was documented and memory was limited and expensive.


问:
In C++, why does the main function use 'char *argv[]'?
I was wondering why C++ uses the following function prototype for the main() function:

```<code>int main(int argc, char *argv[]);
</code>```

instead of something like:

```<code>int main(std::vector<std::string> argv);
</code>```

What's the reasoning behind using the first? Why not just go with the (much more modern) version using vectors and strings? Is it for backwards compatibility, or is there something I'm missing?

答:
A similar question has been asked on Stack Overflow.

In the accepted answer, Nicol Bolas points out that it isn't in the standard because it has to be proposed and voted on. In the way that C++ works, people write proposals for changes, which are voted on. However, he points out that it's a convenience function and doesn't add that much value over the current methods.

In another answer, iammilind suggests that it's against C++'s philosophy. This would add a dependency to the <string> and <vector> libraries. The current implementation uses built-in and independent types, which doesn't force the library on people. In addition, if a system didn't implement the library, then they would be unable to start the application.

Other answers are also provided, but the two mentioned above are the highest scoring.


答:
Unless the sketched look was tested against another look and feel, you can't say with any certainty that the users were responding to the functionality rather than the aesthetics.

On a larger issue, I wouldn't say that a sketched look is a priori bad. It depends on the domain. I don't necessarily agree with you that it can't look polished or professional, but the real-estate issues could certainly be resolved.

In any case, I think you're on the right track of trying to find out what is appealing to your stakeholders. The answer is in there somewhere.


问:
Testing multi-threaded race conditions
Reading the comments to this answer, specifically:

Just because you can't write a test doesn't mean it's not broken. Undefined behaviour which usually happens to work as expected (C and C++ are full of that), race conditions, potential reordering due to a weak memory model... – CodesInChaos 7 hours ago

@CodesInChaos if it cant be reproduced then the code written to 'fix' cant be tested either. And putting untested code into live is a worse crime in my opinion – RhysW 5 hours ago

...has me wondering if there are any good general ways to consistently trigger very infrequently occurring in production problems caused by race conditions in test case.

答:
It seems most of the answers here mistake this question as "how do I automatically detect race conditions?" when the question is really "how do I reproduce race conditions in testing when I find them?"

The way to do it is to introduce synchronization in your code that are used for testing only. For example, if a race condition occurs when Event X happens in between Event A and Event B, then for testing your application, write some code that waits for Event X to happen after Event A happens. You will likely need some way for your tests to talk to your application to tell it ("hey i'm testing this thing, so wait for this event at this location").

I'm using node.js and mongo, where some actions involve creating consistent data in multiple collections. In these cases, my unit tests will make a call to the application to tell it "set up a wait for Event X", and once the application has set it up, the test for event X will run, and the tests will subsequently tell the application ("i'm done with the wait for Event X") so the rest of the tests will run normally.

The answer here explains this type of thing in detail in the context of python: https://stackoverflow.com/questions/19602535/how-can-i-reproduce-the-race-conditions-in-this-python-code-reliably

Title: Testing multi-threaded race conditions


问:
Is there a use for non-const reference parameters?
Given a function like:

```<code>void do_stuff( Thing & thing )
{
    // at this point, I can inadvertently or purposefully change thing
}
</code>```

Is there a reason to purposefully change thing?  Changing thing is possible but is it ill-advised?

答:
There are reasons why you might want to change things in place.  One reason might be performance: it's expensive to make all those new objects for output.

There are reasons why you might write things in a more functional, immutable style.  One reason is referential transparency. Another is easier and more reliable concurrency and function composition.

Everything is a tradeoff.  As with most things in software development, the right choice depends on your specific needs.  C++ is a multi-paradigm language; it allows you to make the choice yourself.


答:
Yes, so the function can change thing.

In general, it is best to put the behavior on the object itself. In other words, prefer this:

```<code>class Thing {
public:
  void do_stuff() {
    ...
  }
};
</code>```

...to this:

```<code>void do_stuff( Thing & thing ) {
  ...
}
</code>```

However, both examples are perfectly valid and usable. One good example of a non-member non-const reference parameter is stream extraction operators. This Stack Overflow question goes into more detail: Does anyone actually use stream extraction operators? The general idea is this:

```<code>operator>>(std::istream &, Thing &)
</code>```

The function cannot exist as part of the Thing class because the left-hand is not an object of the class. It also needs to modify a Thing object so the reference cannot be const.

Title: Is there a use for non-const reference parameters?

Body:
Given a function like:

```<code>void do_stuff( Thing & thing )
{
    // at this point, I can inadvertently or purposefully change thing
}
</code>```

Is there a reason to purposefully change thing?  Changing thing is possible but is it ill-advised?

Body:
Yes, so the function can change thing.

In general, it is best to put the behavior on the object itself. In other words, prefer this:

class Thing {
public:
  void do_stuff() {
    ...
  }
};

...to this:

void do_stuff( Thing & thing ) {
  ...
}

However, both examples are perfectly valid and usable. One good example of a non-member non-const reference parameter is stream extraction operators. This Stack Overflow question goes into more detail: Does anyone actually use stream extraction operators? The general idea is this:

operator>>(std::istream &, Thing &)

The function cannot exist as part of the Thing class because the left-hand is not an object of the class. It also needs to modify a Thing object so the reference cannot be const.


问:
Should I set values using the return or by giving a reference?
Suppose I have a mouse position watcher, which should let the user extract the mouse position.  Should the mouse position be set in the method and returned:

```<code>Mouse_Position Mouse_Watcher::get_mouse_position( void ) const
{
   Mouse_Position return_val = Mouse_Position( this->mp );

   // memory stuff so the value can escape this scope and not cause segmentation faults

   return return_val;
}

Mouse_Position mp = Mouse_Position();
mp = mouse_man::get_mouse_position();
</code>```

or the slightly easier way I've found:

```<code>void Mouse_Watcher::sync_mouse_position( Mouse_Position & destination ) const
{
   // the class handles copying
   // if the stuff is primitive and uses this syncing method,
   //   seems like a ton of avoided memory mishaps
   destination.sync_x( this->mp );
   destination.sync_y( this->mp );
}

Mouse_Position mp = Mouse_Position();
mouse_man::sync_mouse_position( mp );

// at this point mp has position values
</code>```

I've been used to setting values using the return, but I don't like unnecessarily including memory management if I can help it.  Should I go back to using returns to keep up with standards?

答:
Unsurprisingly, this depends on the purpose of the function and the nature of the type it's retrieving/extracting. But it's usually easy to make a choice based on the properties of the type.

1) The value is a primitive such as int or char

Then the choice is effectively between:

```<code>int x = getInt();
</code>```

and

```<code>int x;
setInt(x);
</code>```

I would strongly prefer returning the value, because:

It just looks more natural/normal/intuitive/readable/etc.

Now that the function takes an argument, it's possible that its behavior depends on the current value of that argument. Semantically, the current value of x is completely irrelevant to what this function does, so why give the function access to it?

Copying and assigning ints costs basically nothing. Odds are both versions get optimized to the same instructions anyway.

2) The value is a "trivial" struct/class (eg, no private data, methods or memory management)

I assume your Mouse_Position class falls into this category. This case is basically identical to #1, because a class like this behaves much the same as a primitive.

More formally, when I say this class is like a primitive value, I'm saying this class has "value semantics". That means a lot of things, such as if two objects of that class have the same data members, they are completely interchangeable for all intents and purposes. This is a very nice property to have when it comes to reasoning about your code.

3) The value has methods/private data/memory management, but it implements RAII and still technically has value semantics

This is where STL container classes go. A std::vector definitely contains private data, including a pointer to memory it has to manually manage, but its constructors, destructors and copy operations are implemented in such a way that it still behaves like a primitive value in many ways. In particular, two vectors that compare equal are still interchangeable; it doesn't matter what region of memory they happen to be storing their values in.

In this case, whether you return by value or take a reference parameter mostly comes down to efficiency. In C++ you normally don't want to copy classes like this if you don't have to, because that implies copying all the private data or memory being managed (which may involve allocating more memory). However, move semantics in modern C++ make it so that returning a std::vector does not necessarily perform a copy anymore, so simply returning it by value is becoming more acceptable (I won't try to explain the exact conditions under which copies do/don't happen before/after C++11; that's too complicated).

4) The value has no trace of value semantics, and preserving its identity is important

These are typically classes that represent external dependencies like files, databases, network connections, peripheral devices, rendering contexts and so on. It often does not make sense to copy these objects (you can't give your computer more keyboards by copying a Keyboard class) so functions operating on them basically have to operate on pointers/references to them as a simple matter of correctness. Obviously here the decision is made for you.

Short answer: Don't use pointers/references when they're completely unnecessary. Simply copying/returning values often results in more intuitive and much better-behaved code.

Body:
Unsurprisingly, this depends on the purpose of the function and the nature of the type it's retrieving/extracting. But it's usually easy to make a choice based on the properties of the type.

1) The value is a primitive such as int or char

Then the choice is effectively between:

int x = getInt();

and

int x;
setInt(x);

I would strongly prefer returning the value, because:

It just looks more natural/normal/intuitive/readable/etc.

Now that the function takes an argument, it's possible that its behavior depends on the current value of that argument. Semantically, the current value of x is completely irrelevant to what this function does, so why give the function access to it?

Copying and assigning ints costs basically nothing. Odds are both versions get optimized to the same instructions anyway.

2) The value is a "trivial" struct/class (eg, no private data, methods or memory management)

I assume your Mouse_Position class falls into this category. This case is basically identical to #1, because a class like this behaves much the same as a primitive.

More formally, when I say this class is like a primitive value, I'm saying this class has "value semantics". That means a lot of things, such as if two objects of that class have the same data members, they are completely interchangeable for all intents and purposes. This is a very nice property to have when it comes to reasoning about your code.

3) The value has methods/private data/memory management, but it implements RAII and still technically has value semantics

This is where STL container classes go. A std::vector definitely contains private data, including a pointer to memory it has to manually manage, but its constructors, destructors and copy operations are implemented in such a way that it still behaves like a primitive value in many ways. In particular, two vectors that compare equal are still interchangeable; it doesn't matter what region of memory they happen to be storing their values in.

In this case, whether you return by value or take a reference parameter mostly comes down to efficiency. In C++ you normally don't want to copy classes like this if you don't have to, because that implies copying all the private data or memory being managed (which may involve allocating more memory). However, move semantics in modern C++ make it so that returning a std::vector does not necessarily perform a copy anymore, so simply returning it by value is becoming more acceptable (I won't try to explain the exact conditions under which copies do/don't happen before/after C++11; that's too complicated).

4) The value has no trace of value semantics, and preserving its identity is important

These are typically classes that represent external dependencies like files, databases, network connections, peripheral devices, rendering contexts and so on. It often does not make sense to copy these objects (you can't give your computer more keyboards by copying a Keyboard class) so functions operating on them basically have to operate on pointers/references to them as a simple matter of correctness. Obviously here the decision is made for you.

Short answer: Don't use pointers/references when they're completely unnecessary. Simply copying/returning values often results in more intuitive and much better-behaved code.


问:
Ternary operator considered harmful?
For example, would you prefer this one-liner

```<code>int median(int a, int b, int c) {
    return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
</code>```

or an if/else solution involving multiple return statements?

When is ?: appropriate, and when is it not? Should it be taught to or hidden from beginners?

答:
ReSharper in VS.NET sometimes suggests to replace if...else with the ?: operator.

It seems that ReSharper suggests only if the conditions/blocks are below a certain complexity level, otherwise it sticks with if...else.

Title: Ternary operator considered harmful?


答:
In the majority of cases, you should prefer to actually return things from functions. Passing in a non-const reference to hold the state of your value is typically referred to as an out parameter, or an in-out parameter if you are both using its existing state, and then modifying it.

There are a couple of disadvantages of non-const reference parameters:

1) It looks awkward, and is less clear. You don't know whether it's an out parameter or an in/out parameter without documentation. Maybe it's a normal parameter but someone forgot const.

2) You have to construct a value yourself, and then pass it in. Contrast this with returning the value, your first example is better written as

```<code>Mouse_Position mp = mouse_man::get_mouse_position();
</code>```

I never create a pointless object, and reduce noise in my code.

There are only a couple of reasons I would ever consider using the pattern you are suggesting; I will list them from least to most technical.

1) The object is actually an in/out parameter. This means that you want to use the existing state of the object. In/out parameters themselves are often better avoided, but sometimes they are a good choice. This is not the case here.

2) The object you need to return is neither copyable nor movable (or you are using c++03, and it's not copyable, but I'll disregard that). This is exceedingly rare.

3) Performance reasons. This is a pretty involved issue. The general rule of thumb here is that the compiler is smarter than you think. For instance, if your data type is large, you might argue that returning from a function involves a copy, which is expensive, whereas passing in a reference and modifying it in place might be somehow cheaper. In practice, due to wonderful things like the Return Value Optimization (http://en.wikipedia.org/wiki/Return_value_optimization) this cost is elided in most situations. I could talk a lot more about this, but it's a complicated topic and it doesn't really seem to be relevant here.

In short, with the vast majority of types, and without extreme performance considerations, you should just return the type by value, unless you actually care about its prior state.

Title: Should I set values using the return or by giving a reference?

Body:
Suppose I have a mouse position watcher, which should let the user extract the mouse position.  Should the mouse position be set in the method and returned:

```<code>Mouse_Position Mouse_Watcher::get_mouse_position( void ) const
{
   Mouse_Position return_val = Mouse_Position( this->mp );

   // memory stuff so the value can escape this scope and not cause segmentation faults

   return return_val;
}

Mouse_Position mp = Mouse_Position();
mp = mouse_man::get_mouse_position();
</code>```

or the slightly easier way I've found:

```<code>void Mouse_Watcher::sync_mouse_position( Mouse_Position & destination ) const
{
   // the class handles copying
   // if the stuff is primitive and uses this syncing method,
   //   seems like a ton of avoided memory mishaps
   destination.sync_x( this->mp );
   destination.sync_y( this->mp );
}

Mouse_Position mp = Mouse_Position();
mouse_man::sync_mouse_position( mp );

// at this point mp has position values
</code>```

I've been used to setting values using the return, but I don't like unnecessarily including memory management if I can help it.  Should I go back to using returns to keep up with standards?

Body:
In the majority of cases, you should prefer to actually return things from functions. Passing in a non-const reference to hold the state of your value is typically referred to as an out parameter, or an in-out parameter if you are both using its existing state, and then modifying it.

There are a couple of disadvantages of non-const reference parameters:

1) It looks awkward, and is less clear. You don't know whether it's an out parameter or an in/out parameter without documentation. Maybe it's a normal parameter but someone forgot const.

2) You have to construct a value yourself, and then pass it in. Contrast this with returning the value, your first example is better written as

Mouse_Position mp = mouse_man::get_mouse_position();

I never create a pointless object, and reduce noise in my code.

There are only a couple of reasons I would ever consider using the pattern you are suggesting; I will list them from least to most technical.

1) The object is actually an in/out parameter. This means that you want to use the existing state of the object. In/out parameters themselves are often better avoided, but sometimes they are a good choice. This is not the case here.

2) The object you need to return is neither copyable nor movable (or you are using c++03, and it's not copyable, but I'll disregard that). This is exceedingly rare.

3) Performance reasons. This is a pretty involved issue. The general rule of thumb here is that the compiler is smarter than you think. For instance, if your data type is large, you might argue that returning from a function involves a copy, which is expensive, whereas passing in a reference and modifying it in place might be somehow cheaper. In practice, due to wonderful things like the Return Value Optimization (http://en.wikipedia.org/wiki/Return_value_optimization) this cost is elided in most situations. I could talk a lot more about this, but it's a complicated topic and it doesn't really seem to be relevant here.

In short, with the vast majority of types, and without extreme performance considerations, you should just return the type by value, unless you actually care about its prior state.


问:
What process(s) do you often go through when abandoning a team project?
This question is written after insight gained from my previous question here: What factors should influence how I determine when to abandon a small project with a friend?. This question is ideally different, and hopefully written in a less subjective manner. Your answers do not need to be dependent on my previous question.

I'm a bit of a pickle and have decided that one of my major options with my current project is to abandon it and move on. There are currently two of use that started programming a game with the intent of using it as a learning exercise, we had a scope, we had an idea of where we wanted it to end. We expected it to take us 4 months or so.

Feature creep set in and 8 months later it's looking like more than a year before completion. I have been having some very serious issues working with my partner, and at this point would rather take my code, take what I've learned, and move on. I'm not interested in completing the project any more, and would only want my code (~10k lines) for the sake of reference and adaptation for future projects.

I have become friends with my teammate, we of course naively made plans for release and to make an LLC so that there was a name to release it under. Obviously I do not want to throw that friendship away with the project. He strongly believes in the project much more than I do, and I am hesitant to single handedly destroy his aspirations for the game. It's our first big project, and we are both understandably attached, I would consider him my friend and do not want to cause him too much grief.

My questions are:

What approach can I take to abandon this project in such a way that maintains professionalism, as well as my personal integrity.

If at all possible what methods are commonly used to abandon a project and maintain a healthy relationship with your previous teammate(s).

If there is a hint of salvagability, what actions would you definitely try first before deciding abandonment is the only available option?

答:
Business is Business:

LegallyIANAL assign all your work over to them and all your interest in the corporate entity to them and wish them luck and walk away and never mention the project again.

Business always requires lawyers, and failed businesses require more lawyers than successful ones!

Learning Experience:

Quickest way to end a friendship is to work with a friend as equals. - Jarrod Roberson

That Said:

What you tell this person on why you are want to do this is your decision, no one here can advise you on that, from your previous post, honesty probably will not keep this person as a friend and honestly I would not want someone like that as a friend. Taking the one sided version of what you posted at face value that person is not a peer and probably will never be.

Since they can probably google your screen name just as easily as I can they will probably find this question after the fact and be pissed anyway.

From your previous post you do not seem to have a healthy relationship with this person now, why worry about keeping something you do not have?

If you are asking this question you have already decided there is nothing of value enough to salvage to make it worth your time.

IANAL

In a way that is legally binding, only an actual corporate lawyer can tell you what is and is not legally binding in your specific case.