答:
If your algorithm is going to "fail" 80% of the time, how do you know that it is working?  Is this for the same image or that 80% of the images will not work with your algorithm?  If it is the same image not working, how is it that you would know that it is not a problem in your algorithm?

TDD formalizes your coding process, in that you have test code that you use to verify that your code works as expected.  When you are coding your algorithm, you execute it with some image to see what the results are, right?  TDD would have you write something that will automate that process for you.  This way, you don't forget to run through a test case or get lazy and skip some because the "tests" get repetitive.

For your algorithm, the same image should end up with same results each time shouldn't it?  Or if you are using a random generator that is causing the non-determinism, the same image and same seed should result in the same results over and over again.  You would also be able to provide an example of an image that would "fail" and as if it passes this is a sign of a bug in the algorithm.

Your tests are an automation of how you would verify that the program works as you intend it.

At a certain, level most programmers practice TDD.  They just don't write/program their tests so that others can use them.


问:
Why does it seem so hard for non programmers to understand versioning?
In the past I have worked with designers, BAs and project managers, all who regularly produce project artifacts, yet very really do they understand the concept of versioning.  When I try to explain it to them (even in its most simple form of multiple differently named files) they seem to have some kind of mental block.  Why do you think this is?</p>

答: Well, Alice writes a blah. Then Bob gets the blah and makes some edits, and Carol gets the blah and makes some edits. These are versions. Then Dan comes in and tells Alice to make a bunch of changes. This is another version. The next day, Dan comes back and says that everything he said yesterday was a lie, and that management wants Carols version of the blah from Tuesday. Having Carols version and being able to find it easily is called version control.</p>

ContentLicense: CC BY-SA 3.0

ContentLicense: CC BY-SA 2.5


问:
ASP.NET MVC SoC when dealing with back end objects (design decision)
I had a discussion with some peers and even some technical leads in the team around this and Im all for the purist MVC approach. Especially when the project is in its infant stages (its easy to implement a pattern going forward). Im a firm believer that anything to do with the back end should be kept separate from the Views, Models and also the View-Models.

A final decision was made to go with using the objects deemed pass-through because they are used everywhere, from the UI all the way back to the back end platform which handles the actual request.

Here is a sample illustration of what is going to be implemented:
MVC stack <-> Back end platform <-> Can either talk to a database or another 3rd party service
And in the above example, a back end request object can be made in the controller level and passed through the the back end platform and there it can get adapted to suit either a database or another service. And when the database/3rd party service responds, its response is taken and adapted to one of our own types. This type will then be returned to the MVC stack. The Views and the ViewModels just use these back end platform types.

What Id like to see done:
Id like for the controller to pass on the responsibility to an adaptor or indeed a service layer which is responsible for taking in POCOs and creating back end platform objects. Create the request, send it off to the Back end platform. And when it responds, adapt the response into a View or a ViewModel and send it back to the controller. Objects are injected into the controller so its simply a matter of passing the POCOs to another layer to take responsibility of creating requests, sending it off and then returning a response which consists of a View or a ViewModel.

Pros and cons.
With the current implementation, its convenient and given that we (my company) owns the code that goes from front-end to the back end that gets used. It saves time. Which we don't have much of to get the job done. I don't see the separation of layers here.

With the implementation that Id like to see done, I believe it approaches the SoC a bit more and adds down on another layer of adaptation. This is a bit more work. And, from a pure MVC point of view, its using the back end platform objects which are being used in the back end (although it was assumed that these objects will also be used in the front end).

I realise this is long and doest have pretty pictures. Apologies.

Id like to know what you out there would have done. Cheers.

答:
This is a common point of confusion with ASP.NET MVC, mostly because MVC is so un-opinionated about how your application should be built. @MikeSW makes a good point: it's important to realize that MVC is a UI pattern, but more importantly, you should realize that it's just a pattern. It's not law, the framework won't complain if you do something different.

I'll tell you how a typical ASP.NET MVC project develops, because there's a reason why it's typical. You have domain layer. That could include a DAL, services, whatever. For many, this is just Entity Framework, but if you're building anything larger than a ToDo app (and maybe even for that), you're going to want to abstract that out.

Now, because MVC comes with Entity Framework, the common assumption is that your entities are your Model of MVC. That's a very poor assumption. Entities are dumb - intentionally dumb. They're not really intended for anything but data transfer to and from the database. A Model should be the opposite of that: it should hold all your business logic for the application (or at least that piece of the application. In that way, a view model is closer to the Model of MVC, but even then, it's not all-ecompassing. I would say that your Model is some combo of your view model plus your domain layer. Regardless, the point is that if you intend to use entities as an end-to-end, be-all-end-all Model, at some point, it will bite you in the glutious maximus. It's not a matter of if, but when.

My recommendation is the following:

```<code>Database -> Entity Framework -> Domain Layer -> Controller -> View Model -> View
</code>```

And, back the same way.

Your domain layer will utilize Entity Framework (but this could later be substituted with a Web API, WCF Service, whatever) to retrieve your entities. Your controllers will map your entities to view models and vice versa and then your views will use your view models. For POST operations, your controllers receive view models, map those to entities, and then send them through the domain layer down to be created/updated/whatever. All big MVC projects are built like this or in some minor variation of this, and for a good reason: if you don't do it this way now, you'll only have to do it this way later, with much more time and expense on the tail-end.

OwnerDisplayName: TheRenoRanger

Body:
This is a common point of confusion with ASP.NET MVC, mostly because MVC is so un-opinionated about how your application should be built. @MikeSW makes a good point: it's important to realize that MVC is a UI pattern, but more importantly, you should realize that it's just a pattern. It's not law, the framework won't complain if you do something different.

I'll tell you how a typical ASP.NET MVC project develops, because there's a reason why it's typical. You have domain layer. That could include a DAL, services, whatever. For many, this is just Entity Framework, but if you're building anything larger than a ToDo app (and maybe even for that), you're going to want to abstract that out.

Now, because MVC comes with Entity Framework, the common assumption is that your entities are your Model of MVC. That's a very poor assumption. Entities are dumb - intentionally dumb. They're not really intended for anything but data transfer to and from the database. A Model should be the opposite of that: it should hold all your business logic for the application (or at least that piece of the application. In that way, a view model is closer to the Model of MVC, but even then, it's not all-ecompassing. I would say that your Model is some combo of your view model plus your domain layer. Regardless, the point is that if you intend to use entities as an end-to-end, be-all-end-all Model, at some point, it will bite you in the glutious maximus. It's not a matter of if, but when.

My recommendation is the following:

Database -> Entity Framework -> Domain Layer -> Controller -> View Model -> View

And, back the same way.

Your domain layer will utilize Entity Framework (but this could later be substituted with a Web API, WCF Service, whatever) to retrieve your entities. Your controllers will map your entities to view models and vice versa and then your views will use your view models. For POST operations, your controllers receive view models, map those to entities, and then send them through the domain layer down to be created/updated/whatever. All big MVC projects are built like this or in some minor variation of this, and for a good reason: if you don't do it this way now, you'll only have to do it this way later, with much more time and expense on the tail-end.

OwnerDisplayName: Chris Pratt


问:
How to create a WinForms project that is "WPF-ready"
I'm a C# developer who hasn't had the privilege of learning WPF yet. However, I recently initiated the architecture phase of a new project which I expect will eventually employ WPF (probably; although ASP.Net is still an option) -- but the GUI development won't begin for several months. (We need to get buy-in on a WinForm-based proof-of-concept before we proceed with full production-grade development.) When we are ready to begin implementing the GUI, I will either learn WPF myself or hire someone with experience (preferably both).

So my question is, what are some key fundamentals (design patterns, language essentials, etc) that I could employ right away which would facilitate a smoother migration down the road? For example, my code is a simulation model which will contain a very large number of entities that will eventually need to be "visualized", with interactive user-controls. Are there certain techniques that, if implemented from the ground up, would make wiring up these objects with WPF less painful later on? (Like dependency properties, or what-not.) Similarly, if I stick with the MVC approach that I am familiar with for right now, will it be straight-forward to morph that into an MVVM strategy later? Are there some simple concepts that I could apply now that would make the migration easier, but which won't take two weeks out of my current dev-cycle to master?

Basically, I am trying to follow Uncle Bob's advice to postpone architectural decisions (in this case, the GUI layer) until I absolutely have to make them. But I want to know if there are any unnecessary migration costs that I could avoid if I anticipate them in advance.

答:
I'm glad you are already thinking about a MVVM pattern.  MVVM is very popular in WPF apps.  It is very likely if you are disciplined you can even implement your WinForms app with a MVVM approach.  If you do it will probably be as simple as implementing a the Views and maybe few new ViewModels if the UI designs are similar.

Basically encapsulation will be your friend.  No business logic in the WinForms project.  None at all.  Return basic models from your Core library and try to keep with WinForms as simple as binding models and then calling actions in your core class.


问:
Test Data in a Distributed System
A question that has been vexing me lately has been about how to effectively test (end-to-end) features in a distributed system.  Particuarly, how to effectively manage (through time) test data for feature testing.

The system in question is a typical SOA setup.  The composition is done in JavaScript when call to several REST APIs. Each service is built as an independent block.  Each service has some kind of persistent storage (SQL Server in most cases).

The main issue at the moment is how to approach test data when testing end-to-end features.  Functional end-to-end testing occurs through the UI, and it is therefore necessary for test data to be set up before the test run (this could be manual or automated testing).  As is typical in a distributed system, identifiers from one service are used as a link in another service.  So, some level of synchronization needs to be present in the data to effectively test.

What is the best way to manage and set up this data after a successful deployment to a test environment?

For example, is it better to manage this test data inside each service?  Or package it together with the testing suite?  Does that testing suite exist as a separate project?

I'm interested in design guidance about how to store and manage this test data as the application features evolve.

答:
If your prod, dev, and test environments are seperated then this should be relatively easy. The database should also be in test, which allows you to import a known dataset into the database for testing.  Instead of import, you could restore a db snapshot from backup before starting test.

In the past, I have bundled test data in the application test suite.  This is either a set of SQL scripts to insert data or a db backup to be restored.  My test suite was a seperate project but was always matched the application release.  So, I would not use the v1.7 tests against the v1.9 app, unless I explicitly wanted to simulate an upgrade scenario.

Title: Test Data in a Distributed System


问:
Are long functions acceptable if they have internal structure?
When dealing with complicated algorithms in languages with support for nested functions (such as Python and D) I often write huge functions (because the algorithm is complicated) but mitigate this by using nested functions to structure the complicated code.  Are huge (100+ line) functions still considered evil even if they're well-structured internally via the use of nested functions?

Edit:  For those of you not familiar with Python or D, nested functions in these languages also allow access to the outer function scope.  In D this access allows mutation of variables in the outer scope.  In Python it only allows reading.  In D you can explicitly disable access to the outer scope in a nested function by declaring it static.

答:
A long "straight-line" function can be a clear way to specify a lengthy sequence of steps that always occur in a particular sequence.

However, as others have mentioned, this form is prone to having local stretches of complexity in which the overall flow is less evident. Placing that local complexity into a nested function (ie: defined elsewhere within the long function, perhaps at top or bottom) can restore clarity to the mainline flow.

A second important consideration is controlling the scope of variables that are intended to be used only in a local stretch of a long function. Vigilance is required to avoid having a variable that was introduced in one section of code unwittingly referenced somewhere else (for example, after cycles of editing), as this kind of mistake will not show up as a compile or runtime error.

In some languages, this problem is easily averted: a local stretch of code can be wrapped in its own block, such as with "{...}", within which any newly-introduced variables are only visible to that block. Some languages, such as Python, lack this feature, in which case local functions can be useful to enforce smaller scope regions.


问:
Did the gradual shift in methodology of writing code affect system performance? And Should I care?
TD;DR:

There was some confusion as to what I was asking, so here is the driving idea behind the question:

I always intended the question to be what it is. I may not have articulated it well originally. But intent have always been "is modular, separated, loose coupled, decoupled, refactored code" markedly slower by its own nature than "monolithic single-unit, do-everything in one place, one file, tightly coupled" code. The rest is just details and various manifestations of this that I came across then or now or will later. It is slower for sure on some scale. Like a non-defragged disk, you have to pick up the pieces from everywhere. It's slower. For sure. But should I care?

And the question is not about...

not about micro-optimization, premature optimization, etc.  It is not about "optimize this or that part to death".

What is it then?

It is about the overall methodology and techniques and ways of thinking about writing code that emerged over time:

"inject this code into your class as a dependency"

"write one file per class"

"separate your view from your database, controller, domain".

don't write spaghetti homogenious single codeblock, but write many separate modular components that work together

It is about the way and the style of code that is currently - within this decade - seen and advocated in most frameworks, advocated at conventions, passed on via the community.  It is a shift in thinking from 'monolithic blocks' to 'microservices'.  And with that comes the price in terms of machine-level performance and overhead, and some programmer-level overhead as well.

Original Question follows:

In Computer Science field, I have noticed a notable shift in thinking when it comes to programming.  I come across the advice quite often that goes like this:

write smaller function-wise code (more testable and maintainable this way)

refactor existing code into smaller and smaller chunks of code until most of your methods/functions are just a few lines long and it is clear what is their purpose (which creates more functions, compared to a larger monolithic block)

write functions that only do one thing - separation of concerns, etc (which usually creates more functions and more frames on a stack)

create more files (one class per file, more classes for decomposition purposes, for layer purposes such as MVC, domain architecture, design patterns, OO, etc, which creates more file system calls)

This is a change compared to the "old" or "outdated" or "spaghetti" coding practices where you have methods spanning 2500 lines, and big classes and god objects doing everything.

My question is this:

when it call comes down to machine code, to 1s and 0s, to assembly instructions, to HDD platters, should I be at all concerned that my perfectly class-separated OO code with variety of refactored small-to-tiny functions and methods generates too much extra overhead?

Details

While I am not intimately familiar with how OO code and its method calls are handled in ASM in the end, and how DB calls and compiler calls translate to moving actuator arm on a HDD platter, I do have some idea.  I assume that each extra function call, object call, or "#include" call (in some languages), generate an extra set of instructions, thereby increasing code's volume and adding various "code wiring" overheads, without adding actual "useful" code.  I also imagine that good optimizations can be done to ASM before it is actually ran on the hardware, but that optimization can only do so much too.

Hence, my question -- how much overhead (in space and speed) does well-separated code (code that is split up across hundreds of files, classes, and design patterns, etc) actually introduce compared to having "one big method that contains everything in one monolithic file", due to this overhead?

UPDATE for clarity:

I am assuming that taking the same code and splitting it, refactoring it out, decoupling it into more and more functions and objects and methods and classes will result in more and more parameter passing between smaller code pieces.  Because for sure, refactoring code has to keep the thread going, and that requires parameter passing.  More methods or more classes or more Factory Methods design patterns, results in more overhead of passing various bits of information more than it is the case in a single monolithic class or method.

It was said somewhere (quote TBD) that up to 70% of all code is made up of ASM's MOV instruction - loading CPU registers with proper variables, not the actual computation being done.  In my case, you load up CPU's time with PUSH/POP instructions to provide linkage and parameter passing between various pieces of code.  The smaller you make your pieces of code, the more overhead "linkage" is required.  I am concerned that this linkage adds to software bloat and slow-down and I am wondering if I should be concerned about this, and how much, if any at all, because current and future generations of programmers who are building software for the next century, will have to live with and consume software built using these practices.

UPDATE:  Multiple files

I am writing new code now that is slowly replacing old code.  In particular I've noted that one of the old classes was a ~3000 line file (as mentioned earlier).  Now it is becoming a set of 15-20 files located across various directories, including test files and not including PHP framework I am using to bind some things together. More files are coming as well. When it comes to disk I/O, loading multiple files is slower than loading one large file.  Of course not all files are loaded, they are loaded as needed, and disk caching and memory caching options exist, and yet still I believe that loading multiple files takes more processing than loading a single file into memory.  I am adding that to my concern.

UPDATE: Dependency Inject everything

Coming back to this after a while.. I think my question was misunderstood.  Or maybe I chose to misunderstand some answers.  I am not talking about micro-optimizing as some answers have singled out, (at least I think calling what I am talking about micro-optimization is a misnomer) but about the movement of "Refactor code to loosen tight coupling", as a whole, at every level of the code.  I came from Zend Con just recently where this style of code has been one of the core points and centerpieces of the convention.  Decouple logic from view, view from model, model from database, and if you can, decouple data from the database.  Dependency-Inject everything, which sometimes means just adding wiring code (functions, classes, boilerplate) that does nothing, but serves as a seam/hook point, easily doubling code size in most cases.

UPDATE 2:  Does "separating code into more files" significantly affect performance (at all levels of computing)

How does philosophy of compartmentalize your code into multiple files impact today's computing (performance, disk utilization, memory management, CPU processing tasks)?

I am talking about

Before...

In a hypothetical yet quite real not so distant past, you could easily write one mono-block of a file that does has model and view and controller spaghetti or not-spaghetti-coded, but that runs everything once it is already loaded.  Doing some benchmarks in the past using C code I found out that it is MUCH faster to load a single 900Mb file into memory and process it in large chunks than it is to load a bunch of smaller files and process them in a smaller peace-meal chunks doing the same work in the end.

.. And Now*

Today I find myself looking at code that shows a ledger, that has features like .. if an item is an "order", show order HTML block.  If a line item can be copied, print HTML block that displays an icon and HTML parameters behind it allowing you to make the copy.  If the item can be moved up or down, display the appropriate HTML arrows.  Etc.  I can, through Zend Framework create partial() calls, which essentially means "call a function that takes your parameters and inserts them into a separate HTML file that it also calls".  Depending on how detailed I want to get, I can create separate HTML functions for the tiniest parts of the ledger.  One for arrow up, arrow down, one for "can I copy this item", etc.  Easily creating several files just to display a small part of the webpage.  Taking my code and behind-the-scenes Zend Framework code, the system/stack probably calls close to 20-30 different files.

What?

I am interested in aspects, the wear and tear on the machine that is created by compartmentalizing code into many smaller separate files.

For example, loading more files means having them located in various places of the file system, and in various places of physical HDD, which means more HDD seek and read time.

For CPU it probably means more context switching and loading various registers.

In this sub-block (update #2) I am interested more strictly in how using multiple files to do the same tasks that could be done in a single file, affect system performance.

Using Zend Form API vs simple HTML

I used Zend Form API with latest and greatest modern OO practices, to build an HTML form with validation, transforming POST into domain objects.

It took me 35 files to make it.

```<code>35 files =
    = 10 fieldsets x {programmatic fieldset + fieldset manager + view template}
    + a few supporting files
</code>```

All of which could be replaced with a a few simple HTML + PHP + JS + CSS files, perhaps total of 4 light-weight files.

Is it better? Is it worth? ... Imagine loading 35 files + numerous Zend Zramework library files that make them work, vs 4 simple files.

答:
To my understanding, as you point out with inline, on lower level forms of code like C++ it can make a difference but I say CAN lightly.

The website sums it up - there is no easy answer. It depends on the system, it depends on what your application is doing, it depends on the language, it depends on the compiler and optimization.

C++ for example, inline can increase performance. Many times it might not do anything, or possibly decrease performance but I've personally never encountered that myself though have heard of stories. Inline is nothing more than a suggestion to the compiler to optimize, which can be ignored.

Chances are, if you're developing higher level programs, the overhead shouldn't be a concern if there is one at all to begin with. Compilers are extremely smart these days and should handle this stuff anyway. Many programmers have a code-to-live by: don't ever trust the compiler. If this applies to you, then even slight optimizations you feel are important can be. But, keep in mind, every language differs in this regard. Java does inline optimizations automatically at runtime. In Javascript, inline for your webpage (as opposed to seperate files) is a boost and every milisecond for a webpage might count but thats more of an IO issue.

But on lower level programs where the programmer might be doing a lot of machine code work along with something like C++, the overheard might make all the difference. Games are a good example of where CPU pipelining is critical, especially on consoles, and something like inline can add up a little here and there.

A good read on inline specifically: http://www.gotw.ca/gotw/033.htm


答:
The short answer is "yes".  And, generally, the code will be a bit slower.

But sometimes a proper OO-ish refactoring will reveal optimizations that make the code faster.  I worked on one project where we made a complex Java algorithm much more OO-ish, with proper data structures, getters, etc.  instead of messy nested arrays of objects.  But, by better isolating and restricting access to the data structures, we were able to change from giant arrays of Doubles (with nulls for empty results) to more organized arrays of doubles, with NaNs for empty results.  This yielded a 10x gain in speed.

Addendum: In general, smaller, better structured code should be more amenable to multi-threading, your best way to get major speedups.

Title: Did the gradual shift in methodology of writing code affect system performance? And Should I care?

Body:
TD;DR:

There was some confusion as to what I was asking, so here is the driving idea behind the question:

I always intended the question to be what it is. I may not have articulated it well originally. But intent have always been "is modular, separated, loose coupled, decoupled, refactored code" markedly slower by its own nature than "monolithic single-unit, do-everything in one place, one file, tightly coupled" code. The rest is just details and various manifestations of this that I came across then or now or will later. It is slower for sure on some scale. Like a non-defragged disk, you have to pick up the pieces from everywhere. It's slower. For sure. But should I care?

And the question is not about...

not about micro-optimization, premature optimization, etc.  It is not about "optimize this or that part to death".

What is it then?

It is about the overall methodology and techniques and ways of thinking about writing code that emerged over time:

"inject this code into your class as a dependency"

"write one file per class"

"separate your view from your database, controller, domain".

don't write spaghetti homogenious single codeblock, but write many separate modular components that work together

It is about the way and the style of code that is currently - within this decade - seen and advocated in most frameworks, advocated at conventions, passed on via the community.  It is a shift in thinking from 'monolithic blocks' to 'microservices'.  And with that comes the price in terms of machine-level performance and overhead, and some programmer-level overhead as well.

Original Question follows:

In Computer Science field, I have noticed a notable shift in thinking when it comes to programming.  I come across the advice quite often that goes like this:

write smaller function-wise code (more testable and maintainable this way)

refactor existing code into smaller and smaller chunks of code until most of your methods/functions are just a few lines long and it is clear what is their purpose (which creates more functions, compared to a larger monolithic block)

write functions that only do one thing - separation of concerns, etc (which usually creates more functions and more frames on a stack)

create more files (one class per file, more classes for decomposition purposes, for layer purposes such as MVC, domain architecture, design patterns, OO, etc, which creates more file system calls)

This is a change compared to the "old" or "outdated" or "spaghetti" coding practices where you have methods spanning 2500 lines, and big classes and god objects doing everything.

My question is this:

when it call comes down to machine code, to 1s and 0s, to assembly instructions, to HDD platters, should I be at all concerned that my perfectly class-separated OO code with variety of refactored small-to-tiny functions and methods generates too much extra overhead?

Details

While I am not intimately familiar with how OO code and its method calls are handled in ASM in the end, and how DB calls and compiler calls translate to moving actuator arm on a HDD platter, I do have some idea.  I assume that each extra function call, object call, or "#include" call (in some languages), generate an extra set of instructions, thereby increasing code's volume and adding various "code wiring" overheads, without adding actual "useful" code.  I also imagine that good optimizations can be done to ASM before it is actually ran on the hardware, but that optimization can only do so much too.

Hence, my question -- how much overhead (in space and speed) does well-separated code (code that is split up across hundreds of files, classes, and design patterns, etc) actually introduce compared to having "one big method that contains everything in one monolithic file", due to this overhead?

UPDATE for clarity:

I am assuming that taking the same code and splitting it, refactoring it out, decoupling it into more and more functions and objects and methods and classes will result in more and more parameter passing between smaller code pieces.  Because for sure, refactoring code has to keep the thread going, and that requires parameter passing.  More methods or more classes or more Factory Methods design patterns, results in more overhead of passing various bits of information more than it is the case in a single monolithic class or method.

It was said somewhere (quote TBD) that up to 70% of all code is made up of ASM's MOV instruction - loading CPU registers with proper variables, not the actual computation being done.  In my case, you load up CPU's time with PUSH/POP instructions to provide linkage and parameter passing between various pieces of code.  The smaller you make your pieces of code, the more overhead "linkage" is required.  I am concerned that this linkage adds to software bloat and slow-down and I am wondering if I should be concerned about this, and how much, if any at all, because current and future generations of programmers who are building software for the next century, will have to live with and consume software built using these practices.

UPDATE:  Multiple files

I am writing new code now that is slowly replacing old code.  In particular I've noted that one of the old classes was a ~3000 line file (as mentioned earlier).  Now it is becoming a set of 15-20 files located across various directories, including test files and not including PHP framework I am using to bind some things together. More files are coming as well. When it comes to disk I/O, loading multiple files is slower than loading one large file.  Of course not all files are loaded, they are loaded as needed, and disk caching and memory caching options exist, and yet still I believe that loading multiple files takes more processing than loading a single file into memory.  I am adding that to my concern.

UPDATE: Dependency Inject everything

Coming back to this after a while.. I think my question was misunderstood.  Or maybe I chose to misunderstand some answers.  I am not talking about micro-optimizing as some answers have singled out, (at least I think calling what I am talking about micro-optimization is a misnomer) but about the movement of "Refactor code to loosen tight coupling", as a whole, at every level of the code.  I came from Zend Con just recently where this style of code has been one of the core points and centerpieces of the convention.  Decouple logic from view, view from model, model from database, and if you can, decouple data from the database.  Dependency-Inject everything, which sometimes means just adding wiring code (functions, classes, boilerplate) that does nothing, but serves as a seam/hook point, easily doubling code size in most cases.

UPDATE 2:  Does "separating code into more files" significantly affect performance (at all levels of computing)

How does philosophy of compartmentalize your code into multiple files impact today's computing (performance, disk utilization, memory management, CPU processing tasks)?

I am talking about

Before...

In a hypothetical yet quite real not so distant past, you could easily write one mono-block of a file that does has model and view and controller spaghetti or not-spaghetti-coded, but that runs everything once it is already loaded.  Doing some benchmarks in the past using C code I found out that it is MUCH faster to load a single 900Mb file into memory and process it in large chunks than it is to load a bunch of smaller files and process them in a smaller peace-meal chunks doing the same work in the end.

.. And Now*

Today I find myself looking at code that shows a ledger, that has features like .. if an item is an "order", show order HTML block.  If a line item can be copied, print HTML block that displays an icon and HTML parameters behind it allowing you to make the copy.  If the item can be moved up or down, display the appropriate HTML arrows.  Etc.  I can, through Zend Framework create partial() calls, which essentially means "call a function that takes your parameters and inserts them into a separate HTML file that it also calls".  Depending on how detailed I want to get, I can create separate HTML functions for the tiniest parts of the ledger.  One for arrow up, arrow down, one for "can I copy this item", etc.  Easily creating several files just to display a small part of the webpage.  Taking my code and behind-the-scenes Zend Framework code, the system/stack probably calls close to 20-30 different files.

What?

I am interested in aspects, the wear and tear on the machine that is created by compartmentalizing code into many smaller separate files.

For example, loading more files means having them located in various places of the file system, and in various places of physical HDD, which means more HDD seek and read time.

For CPU it probably means more context switching and loading various registers.

In this sub-block (update #2) I am interested more strictly in how using multiple files to do the same tasks that could be done in a single file, affect system performance.

Using Zend Form API vs simple HTML

I used Zend Form API with latest and greatest modern OO practices, to build an HTML form with validation, transforming POST into domain objects.

It took me 35 files to make it.

```<code>35 files =
    = 10 fieldsets x {programmatic fieldset + fieldset manager + view template}
    + a few supporting files
</code>```

All of which could be replaced with a a few simple HTML + PHP + JS + CSS files, perhaps total of 4 light-weight files.

Is it better? Is it worth? ... Imagine loading 35 files + numerous Zend Zramework library files that make them work, vs 4 simple files.


问:
What is the difference between a Splay Tree and an Optimal Binary Search Tree?
Both these trees try to keep the most frequently accessed element at the top. Is there any difference between these two trees?</p>

答:
A Splay Tree is a specific variation of binary tree, specifying certain attributes of how the tree should be implemented. An Optimal Binary Search Tree is any binary tree for which the lookup cost is minimized.

One describes the implementation, the other describes the result.

So your question is a bit like asking "What's the difference between a Rally Car and a Fast Car?" The answer is that the question doesn't really make sense.

ContentLicense: CC BY-SA 4.0


问:
Which one to choose: XML attribute or Sub node?
We want to export some data from our data base as XML.  For example, a Person can have age, name and some other properties.

We have two choices to define the XML format.

Choice #1:

```<code><Persons>
   <Person>
       <Age>16</Age>
       <Name>Richard</Name>
   </Person>
   <Person>
       <Age>34</Age>
       <Name>Eric</Name>
   </Person>
   ...
</Persons>
</code>```

Choice #2:

```<code><Persons>
   <Person Age="16" Name="Richard"/>
   <Person Age="34" Name="Eric"/>
   ...
</Persons>
</code>```

So what's the difference between definition of sub node or attribute?
And what's the benefit of each choice?

答:
Principles of XML design: When to use elements versus attributes by Uche Ogbuji from IBM is probably one of the best resources on the matter.

At the core of the decision is that attributes are 'done' things.  You can't change them or modify them or nest them.  They are order independent and and distinct within the element (you can't have two of the same thing).

If any of these constraints are things that may change, make the data a child node of the XML.

In your example, you have a person who has a name and an age.  I have a first, middle, and last name... and a nickname.  And some people have maiden names, multiple middle names, or honorifics - how would you put in John Ronald Reuel Tolkien into such a structure?

And so we have someone who has two middle names that have an order to them.  This should clearly show that no, an attribute isn't the best choice for this.

I can't find it currently, but in the above linked document there is a statement that names are things that require a bit of thought leading to "I hope to expand on the treatment of people's names in markup in a future article." If anyone has a lead on this, please leave a comment or edit it into this spot.

On the other hand, the age is something that has a rather fixed structure (I'd suggest the birthday rather than an integer).  As such, representing this information in a well known and understood format makes sense in an attribute.  A person has one, and only one birthday and there is no 'ordering' to it that you want to preserve.

Uche Ogbuji identifies three core principles in properly designing an xml format.  The following are abbreviated quotes from the above linked document.

Principle of structured information

If the information is expressed in a structured form, especially if the structure may be extensible, use elements. On the other hand: If the information is expressed as an atomic token, use attributes

Principle of readability

If the information is intended to be read and understood by a person, use elements. If the information is most readily understood and digested by a machine, use attributes.

Principle of element/attribute binding

Use an element if you need its value to be modified by another attribute

And so, names should elements - they are structured data that is not an atomic token, they are more likely to be read by a human than a computer and they may be modified by another attribute on the name itself.

Dates should be attributes - they are data that is an atomic token, they are more likely the read by a computer than a human (and then transformed into the human's preferred format if need be), and lastly they are unlikely to be modified by other attributes on them.

OwnerDisplayName: ZijingWu


问:
How to measure that a team is doing Test Driven Development
My team is considering a department goal of doing Test Driven Development next (fiscal) year.

TDD sounds good and my manager is on board.  The only problem is measurement.

Our company rules require that department goals be measurable.

Is there any (sane) way to measure if a team is doing TDD?

Note: We had a goal for writing unit tests already, so a code coverage goal will not work. We write the unit tests but we do it after the fact, not before.

Is there a way to measure that TDD is being done?

(NOTE: We use Visual Studio 2013 and TFS in case it matters)

答:
I'm not sure that you'll need a different measure at all. You say:

We had a goal for writing unit tests already....

... presumably you are measuring this in some way. The fact that you now want to write tests before the code should have no effect on your existing metrics. After all, there may have been times when, (for example) to get a better understanding of the problem, someone in the team did write a test before the code. So in that case they were already practising TDD; they just didn't call it that, and management didn't care.

The existing goal is to have unit tests; you will still have unit tests after adopting TDD. It's simply a non-issue from a bean-counter perspective. As others have said, TDD in itself is not a goal.


问:
Testing Framework Selection: xUnit family theory
Background:

I am familiar with xUnit family frameworks and have had experience with (shunit2, PhpUnit and simpletest). I am currently trying to find a testing framework for C++. I did a quick search for frameworks using Wikipedia's list of documented frameworks; however, the framework I would like to use is very difficult to setup and is poorly documented. There is another framework that I have tried that was (IMHO) extremely easy to setup and integrate into my production workflow.

The difference between my framework of choice (the one that is difficult to setup) and the one that I'm currently using (the one that was easy to setup) is compliance with xUnit methodology.

Questions:

1. I have read quite a few articles about xUnit testing frameworks. I believe that they use similar naming conventions and testing methods for their test. Is this true and what are the naming methods utilized?

2. Does staying with xUnit testing frameworks make it easier to run integration tests when using multiple languages?

3. From a training perspective is it more cost effective to teach new programmers a set of tools based on the same concept or different individual tools that do the same thing?

I kept the frameworks that I am looking at anonymous because I am more interested in industry best practices than a comparison of the two said frameworks

答:
I haven't done TDD in C++, but I am currently reading Working Effectively With Legacy Code and my first instinct would be to go with something recommended by Michael Feathers.

In my experience it's the concepts that are more important than the names of things. So in the xUnit style, you have the concept of a test suite which contains a group of tests, a setup procedure, and a teardown procedure. The setup is run before every test in the suite, and the teardown is run after every test. So any framework that has these concepts should be easy for someone with xUnit experience to adapt to.

Integration tests are a different beast than unit tests. The xUnit style frameworks don't really focus on integration. Web folks have developed specialised tools that 'auto-pilot' a Web browser to test website behaviour, but I believe a more general approach is taken by something like Fitnesse, which lets you specify expected inputs to and outputs from a system, and test those are fulfilled.

I will say that you want to keep an eye on automated tooling--especially to see if your build tool can understand your test framework output and present it in reports, notifications, etc. It's not enough for a framework to just print out stuff to the console--it has to be able to give you something that your continuous integration system can use to check for build success and test pass/failure (e.g. Travis CI).

Not sure I understand this--it seems too general. But see # 1.


问:
is it considered plagiarism to comment out code I copied from elsewhere?
If the plagiarized code is commented out because I found another way to solve the problem, but I forgot to remove the comments, is that considered plagiarism?

I used the copied code to help me debug and compare the output between my own code and the copied code. In the final code, I commented out the copied code. Since comments don't affect how the code runs, can comments be considered plagiarism?

答:
The real world doesn't have "plagiarism," it has "copyright infringement."

Plagiarism is a matter for passing others' ideas off as your own. It's not illegal, and for the most part nobody cares. In school, where your ideas determine your grades, plagiarism is a capital sin because it muddies up academic evaluation. But in business the ability to incorporate others' ideas into your own work is a marketable skill.

But in business there's also copyright infringement, which is the violation of a state-granted monopoly on the reproduction of one's work. If you have license to copy, then no harm done as long as you work within the granted license. Otherwise, you best remove the infringing content.

Note that in the academic world of "plagiarism," copying the idea is the offense, not necessarily the content. Rewriting someone else's work into your own words doesn't make the ideas your own, so the plagiarism is not avoided.

But in the business world of "copyright infringement", the copyright exists on the specific implementation, not the idea. Re-implementing a given mechanism in your own clean code (not simply transcribed; you need a "clean-room" implantation to be thoroughly safe) is enough to make the code "yours", and not copied.


问:
How to address the concerns of the software architect but still maintain collective code ownership?
The quality of the code in our software is indeed lacking. When you change a line of code in one component it usually breaks code in other components.

Our software architect blames this on collective code ownership. He believes that if every developer was responsible for his own piece of code then he would tidy it up all the time because he would feel ownership over the component.

In the current situation, developers change code in multiple components and they break other components either because they don't understand how the component works (because they work with so many components) or because they don't care about how their changes will affect the other clients of the component (as long as they are not affected).

How can I address the concerns of the software architect but still maintain collective code ownership?

答:
In the current situation, developers change code in multiple components and they break other components either because they don't understand how the component works (because they work with so many components) or because they don't care about how their changes will affect the other clients of the component (as long as they are not affected).

This sounds like a management problem really - that the developers have not been given the time to learn the skills they need to own the code. Other answers offer practical solutions to this, yet I do not think they solve the root problem.

I'd recommend looking into the 5 whys and applying it to your group to find out why the skills are not being learned - this would be an example of it.

Why don't developers know how the components work?

Maybe because they need training in them?

Why haven't they gotten training in them?

Maybe because they don't have time to do training?

Why don't they have time to do the training?

Maybe because they have too much work to do?

Why do they have too much work to do?

Maybe because their manager prioritized work over training

At this point, you need to convince your manager that the benefit of investing in this training now will allow true code ownership and hopefully improved quality.


答: No, multi-page functions are not desirable, and should not pass code review.  I used to write long functions too, but after reading Martin Fowler's Refactoring, I stopped.  Long functions are hard to write correctly, hard to understand and hard to test.  I have never seen a function of even 50 lines that wouldn't be more easily understood and tested if it were split into a set of smaller functions.  In a multi-page function there are almost certainly entire classes that should be factored out.  It's hard to be more specific.  Maybe you should post one of your long functions to Code Review and someone (maybe me) can show you how to improve it.

Title: Are long functions acceptable if they have internal structure?

Body:
When dealing with complicated algorithms in languages with support for nested functions (such as Python and D) I often write huge functions (because the algorithm is complicated) but mitigate this by using nested functions to structure the complicated code.  Are huge (100+ line) functions still considered evil even if they're well-structured internally via the use of nested functions?

Edit:  For those of you not familiar with Python or D, nested functions in these languages also allow access to the outer function scope.  In D this access allows mutation of variables in the outer scope.  In Python it only allows reading.  In D you can explicitly disable access to the outer scope in a nested function by declaring it static.


问:
Confused about the definition of 'abstraction' in OOP
I am trying to understand the definition of 'abstraction' in OOP.

I have come across a few main definitions. Are they all valid? Is one of them wrong? I'm confused. (I re-wrote the definition with my own words).

Definition 1:

Abstraction is the concept of taking some object from the real world, and converting it to programming terms. Such as creating a Human class and giving it int health, int age, String name, etc. properties, and eat() etc. methods.

Definition 2:

A more general definition. Abstraction is a concept that takes place anywhere in a software system where 'making things more general/simpler/abstract' is involved. A few examples:

An inheritance hierarchy, where the higher classes are simpler or more general,
and define more general and abstract implementation.
While the lower classes in the hierarchy are more concrete and define
more detailed implementations.

Using encapsulation to hide the details of implementation of a class from other classes, thus making the class more 'abstract' (simpler) to the outside software world.

Definition 3

Another general definition: Abstraction is the concept of moving the focus from the details and concrete implementation of things, to the types of things (i.e. classes), the operations available (i.e. methods), etc, thus making the programming simpler, more general, and more abstract. (This can take place anywhere and in any context in the software system).
It takes place for example when encapsulating, because encapsulation means to hide the details of implementation and only show the types of things and their more general and abstract definitions. Anotehr example would be using a List object in Java. this object actually uses the implementation details of an ArrayList or a LinkedList, but this information is abstracted using the more general name List.

Is any of these definitions correct?
(I am referring to the most conventional and accepted definition).

答:
Each of these definitions is fine.

Abstraction is where you focus on only those details that are important for your purpose.

In the first case, you (at present) cannot include real people in your code; you focus on particular details of a person that serve your purpose. In another program you may need to focus on different details. These would be different abstractions of a person, and each can be equally valid in their context.

The second and third definitions continue this idea, applying it to software entities.


答:
Among other things, programming is about trade-offs. Based on this fact, I incline to answer yes, it could be slower. But think about what you get in return. Getting readable, reusable and easily modifiable code is easily overweighs any possible drawbacks.

As @user949300 mentioned, it is easier to spot areas that can be algorithmically or architecturally improved with such approach; improving those are usually far more beneficial and effective than not having possible OO or function-calling overhead (which is already just a noise, I bet).

I also imagine that good optimizations can be done to ASM before it is
  actually ran on the hardware.

Whenever something likes this crosses my mind, I remember that decades spent by smartest people working on compilers are probably making tools like GCC far better than me at generating machine code. Unless you are working on some sort of microcontrollers related stuff, I suggest you don't worry about that.

I am assuming that adding more and more functions and more and more
  objects and classes in a code will result in more and more parameter
  passing between smaller code pieces.

Assuming anything when optimizing is a waste of time, you need facts about code performance. Find where you program spends most of the time with specialized tools, optimize that, iterate.

To sum it all up; let compiler do its job, focus on important things like improving your algorithms and data structures. All the patterns you mentioned in your question exist to help you with that, use them.

P.S.: These 2 Crockford's talks popped in my head and I think they are somewhat related. First one is super brief CS history (which is always good to know with any exact science); and second one is about why we reject good things.

The Early Years

Programming Style & Your Brain


答:
Abstraction is one of the 4 pillars of Object Oriented Programming(OOP). It literally means to  perceive an entity in a system or context from a particular perspective. We take out unnecessary details and only focus on aspects that are necessary to that context or system under consideration.

Here is some good explanation:

You as a person have different relationships in different roles. When you are at school, then you are a "Student". When you are at work, you are an "Employee". When you are at government institution, you can be viewed as a "Citizen". So it boils down to what in what context are we looking at an entity/object.
So if I am modelling a Payroll System, I will look at you as an Employee(PRN, Full Time/Part Time, Designation). If am modelling a Course Enrollment System, then I will consider your aspects and characteristics as a Student(Roll Number, Age, Gender, Course Enrolled). And if I am modelling a Social Security Information System then I will look at your details as a Citizen(like DOB, Gender, Country Of Birth, etc.)

Remember that Abstraction(focussing on necessary details) is different from Encapsulation(hiding details from the outer world). Encapsulation means hiding the details of the object and providing a decent interface for the entities in outer world to interact with that object or entity. For example, if someone want to know my name then he cannot directly access my brain cells to get to know what is my name. Instead that person will either ask my name. If a driver wants to speed up a vehicle then there is an interface(accelerator pedal, gear, etc) for that purpose.

The 1st def s not very clear. Def 2 is good but it tends to confuse the newbie as it tries to link Abstraction with Encapsulation and Inheritance. Def 3 is the best one out of 3 definitions as it clearly defines what is Abstraction precisely.

Title: Confused about the definition of 'abstraction' in OOP

Body:
I am trying to understand the definition of 'abstraction' in OOP.

I have come across a few main definitions. Are they all valid? Is one of them wrong? I'm confused. (I re-wrote the definition with my own words).

Definition 1:

Abstraction is the concept of taking some object from the real world, and converting it to programming terms. Such as creating a Human class and giving it int health, int age, String name, etc. properties, and eat() etc. methods.

Definition 2:

A more general definition. Abstraction is a concept that takes place anywhere in a software system where 'making things more general/simpler/abstract' is involved. A few examples:

An inheritance hierarchy, where the higher classes are simpler or more general,
and define more general and abstract implementation.
While the lower classes in the hierarchy are more concrete and define
more detailed implementations.

Using encapsulation to hide the details of implementation of a class from other classes, thus making the class more 'abstract' (simpler) to the outside software world.

Definition 3

Another general definition: Abstraction is the concept of moving the focus from the details and concrete implementation of things, to the types of things (i.e. classes), the operations available (i.e. methods), etc, thus making the programming simpler, more general, and more abstract. (This can take place anywhere and in any context in the software system).
It takes place for example when encapsulating, because encapsulation means to hide the details of implementation and only show the types of things and their more general and abstract definitions. Anotehr example would be using a List object in Java. this object actually uses the implementation details of an ArrayList or a LinkedList, but this information is abstracted using the more general name List.

Is any of these definitions correct?
(I am referring to the most conventional and accepted definition).


答:
Definition 1 is definitely not an abstraction. That is more closely describing modeling.

Definitions 2 and 3 describe same thing. And both are pretty good descriptions of an abstraction.


答:
Without extreme care, micro optimization such as these concerns leads to unmaintainable code.

Initially it looks like a good idea, the profiler tells you the code is faster and V&V/Test/QA even says works. Soon bugs are found, requirements change and enhancements that were never considered are asked for.

Over the life of a project code degrades and becomes less efficient. Maintainable code will become more efficient than its unmaintainable counterpart
as it will degrade slower. The reason is code builds entropy as it is changed -

Unmaintainable code quickly has more dead code, redundant paths and duplication. This leads to more bugs, creating a cycle of degradation of the code - including its performance. Before long, developers have low confidence that the changes they are making are correct. This slows them down, makes the cautious and generally leads to even more entropy as they address only the detail they can see

Maintainable code, with small modules and unit tests is easier to change, code that is no longer needed is easier to identify and remove. Code that is broken is also easier to identify, can be repaired or replaced with confidence.

SO in the end it comes down to life cycle management and is not as simple as "this is faster so it will always be faster."

Above all, slow correct code is infinitely faster than fast incorrect code.


问:
Do we need Logging when doing TDD?
When doing the Red, Green & Refactor cycle we should always write the minimum code to pass the test. This is the way I have been taught about TDD and the way almost all books describe the process.

But what about the logging?

Honestly I have rarely used logging in an application unless there was something really complicated that was happening, however, I have seen numerous posts that talk about the importance of proper logging.

So other than logging an exception I couldn't justify the real importance of logging in a proper tested application (unit/integration/acceptance tests).

So my questions are:

Do we need to log if we are doing TDD? won't a failing test reveal
what wrong with the application?

Should we add test for the logging process in each method in each class?

If some log levels are disabled in the production environment for example, won't that introduce a dependency between the tests and enviroment?

People talk about how logs ease debugging, but one of the main advantages about TDD is that I always know what's wrong due to a failing test.

Is there something I am missing out there?

答:
In my experience great level of logging is added to the application when we don't do TDD. Then the level of uncertainty becomes high hence we add logging to see what is going on.

Whereas when doing TDD (or maybe test-whenever) I find myself adding a lot less log statements. This in turn means less LOC and can (not always) affect performance.

But we do add entering-exiting logs for functions in a semi-automatic way at my company in most cases regardless of development method. As I know this was considered mandatory for production issue analysis.

Example could be methods of an EJB service bean which are present on the public interface. Another might be a case when a function does complex calculations. It can help a lot to have figures entering the method (for example you can write a unit test to get back to the general topic at hand).

Title: Do we need Logging when doing TDD?


问:
Designing storage service data structure for decoupled models sharing same data
Surely most of you remember the Norton Commander application where similar (sometimes the same) data is displayed in separate decoupled views.

I'm building a web application that follows the same principle. The amount of data is too big to be fetched/displayed entirely on the page, and potentially overlapping subsets of data need to be displayed in separate views.

My architecture looks like this:

```<code>                           ┌──────── EventBus ────────┐
                           │             │            │
                           │      StorageService      │
                           │       ╱          ╲       │
                     PresenterLeft┤            ├PresenterRight
                        ╱     ╲    ╲          ╱    ╱      ╲
                  ViewLeft   ModelLeft      ModelRight   ViewRight
</code>```

The application creates both presenters and passes them the instance of EventBus and StorageService. The presenters, in their turn, create their respective models and views. The StorageService is passed down to models. The communication between presenters is done via the EventBus.

In this scenario the left side has no awareness of the right side, yet models should possess the same information without a need to do a double round trip to the server.

To achieve this I use the StorageService. Models implement the model.fetch() method which asks the storage for data. If the same data was previously requested, the storage will simply return it acting like an in-memory cache.

Here comes the actual question. In the above context, how to design a data structure for a network-wise efficient storage service for the following use case:

Left model requests GET /files?limit=100

Right model requests GET /files?limit=110 (but actually I only need the last 10)

My attempted approach was:

store the requests made by models

for every additional request, do my best to figure out the request diff

do the diff request (e.g. GET /files?offset=100&limit=10)

store the fetched items under {"files": {"id1": item1, ..., "id110": item110}}

Unfortunately the above steps don't help, because there's no relation between the url and the ids. When a model requests the next set of values, I never know if they are actually in the in-memory cache.

Of course, I could use the per-url in-memory caching strategy, but then I would have duplicate entries in the cache, which is something I'd like to avoid.

What are your thoughts? I feel like I'm reinventing the wheel here. Is there a better/simpler/commonly-accepted method? Perhaps my architecture is flawed...

答:
The urls should just map internally to some call to a repository that implements the caching behavior you want.

```<code>LeftViewModel should call IFileRepository getRecentFiles(100) through /files?limit=100
RightViewModel should call IFileRepository getRecentFiles(110) through /files?limit=110
</code>```

Then create something like:

```<code>CachingFileRepository implements IFileRepository
  depends on another IFileRepository for permanent storage
  function getRecentFiles (limit)
    if cacheSize < limit
      get the rest of the files from the permanent repository
      add the files to the cache
    return the files
</code>```

If you want to have 1:1 class to url mapping, you should have more urls (one more for the permanent storage, use the existing one for the cache).

If you want to have one url for the service, you should have more classes behind that one url.

EDIT: In addition, if you want to do this without two roundtrips to storage, you could keep track of the views you are spawning, and request model data once after you know what the models need.  Something like

```<code>BaseFileModel
  limit = 0
  require()
    storageService->requireLimit(limit)
  populate()
    storageService->getFiles(limit)

ModelLeft extends BaseFileModel
  limit = 100

ModelRight extends BaseFileModel
  limit = 110

Application
  createModels() //creates ModelLeft and ModelRight, sending storageService and calling populate
  storageService->getRemoteData() - one call to get data
  populateModels()
  renderViews()
</code>```

Body:
The urls should just map internally to some call to a repository that implements the caching behavior you want.

LeftViewModel should call IFileRepository getRecentFiles(100) through /files?limit=100
RightViewModel should call IFileRepository getRecentFiles(110) through /files?limit=110

Then create something like:

CachingFileRepository implements IFileRepository
  depends on another IFileRepository for permanent storage
  function getRecentFiles (limit)
    if cacheSize < limit
      get the rest of the files from the permanent repository
      add the files to the cache
    return the files

If you want to have 1:1 class to url mapping, you should have more urls (one more for the permanent storage, use the existing one for the cache).

If you want to have one url for the service, you should have more classes behind that one url.

EDIT: In addition, if you want to do this without two roundtrips to storage, you could keep track of the views you are spawning, and request model data once after you know what the models need.  Something like

BaseFileModel
  limit = 0
  require()
    storageService->requireLimit(limit)
  populate()
    storageService->getFiles(limit)

ModelLeft extends BaseFileModel
  limit = 100

ModelRight extends BaseFileModel
  limit = 110

Application
  createModels() //creates ModelLeft and ModelRight, sending storageService and calling populate
  storageService->getRemoteData() - one call to get data
  populateModels()
  renderViews()


问:
Deployment Tools that Integrate with TFS?
So I have this issue.  The Operations team where I work has taken over TFS because they are using MS Build to build and deploy code to production servers.  As a result developers have lost A LOT of functionality from TFS (see earlier question.)

Essentially the operations team has taken owner ship of Trunk in order to manage their deployments. The development cycle thus goes something like this:

Request Operations Team to create a Branch from Main for development work.

Perform Development work on development branch.

Merge from Trunk to development branch prior to release (basically make sure that the development branch has all of the latest changes)

Request Operations Team merge to Trunk from development branch (Developers do not have permissions to do this) -> this request will cause Operations to not only to merge to Trunk but also to deploy to the development environment.

Perform integration Testing, fix defects found in development branch.

Repeat steps 3 - 6 as necessary.

Request Operations Team merge from Trunk to a QA branch (there is only ONE on-going QA branch per project) -> this request will cause a deployment into the QA environment (An MS Build template is used to compile the code from QA branch and then deploy to QA servers)

QA tests, fix defects found in development branch.

Repeat steps 3 - 8 as necessary.

Request Operations Team merge from QA branch into PROD branch (there is only ONE on-going PROD branch per project) -> this request will caus a deployment into the PROD environment (Again an MS Build template is used to re-compile the code from PROD branch and then deploy to PROD servers)

As a result of the Ops team using an MS Build template to deploy to Production servers, the Development team has now lost the "Builders" role.  We cannot create our own MS Build templates, we cannot create or edit a Build definition, and we cannot queue a build -- Even in the Development Environment -- because the Build process runs under a service account which has access to Production servers (since it is use to deploy to production servers).

Besides the removal of TFS permissions, I have some issues with this process:

The assemblies which were compiled and tested in the QA environment are not the assemblies being deployed into the Production environment.  Because the MS Build process is being used to deploy to production, code is recompiled and deployed from the Production branch.  In theory, the resulting assemblies should be the same, however this is depenent upon a) the operations team (who are not developers) properly merging the code from the QA branch to the PROD branch (human error potential) b) the build environment not changing in such a way as to affect the way assemblies are compiled (since this is primarily .Net improbable but not impossible)

Since there is only ONE QA branch, if I have a production issue which needs a "hot fix" after other work has been merged to QA, I have to wait for Ops to rollback changes to the QA branch, merge my changes in and perform the build and then HOPE that operations correctly performed the rollback and merge operations on the QA branch in order to get my "hot fix" into the QA environment.

Many of my projects have multiple outputs (e.g. a web-application and a windows service).  Often I may want to only deploy one or the other.  But if I upgrade one to a new version, I no longer have a PROD branch which represents the one I didn't upgrade.

Operations team has already demonstrated that merge operations are not being performed correctly: Following a recent merge from Development to Trunk I performed a compare on the two branches and they were different.

Because code is recompiled for each environment we cannot use automated versioning, or make use of the "build quality" features of TFS.

Essentially what it comes down to is the Operations Team has attached themselves to using MS Build for deployments and as such have adopted a rediculous Source Control branching and merging strategy to support using MS Build for managing deployments. (I see no benefit in having a QA and PROD branch other than to support MS Build based deployments).

What I am trying to do is convince the powers that be and the operations team that what we're doing is a bad practice, and also give them an alternative deployment strategy.  What I need for this is a Deployment tool that integrates with TFS (e.g. it will show a list of Builds that have a specified "build quality" level (depending upon the environment being deployed into) as a "deployment source" and allow then to maintain a list of "deployment targets" so that at deployment time, they simply pick the build (source) and the target and click the "GO!" button.

A proper deployment tool will hopefully eliminate their dependence upon MS Build, allow them to remove access to QA and Production servers from the MS Build process, follow a more sane approach to branching and merging (e.g adopt a "branch per release" best practices strategy) and restore to the developers the TFS permissions which were revoked to support this rediculous process.

答:
I would suggest the following changes:

Do not deploy from trunk. Trunk is for integration between all project and release branches. Instead, create a branche from trunk for each release. Operations can than build and deploy the results from there. This allows operations to focus on the release.

Use separate team projects for different teams, so you can apply different permissions per project.

Request your own build server (which you can host in development), to build and deploy your development version.


答:
TL;DR: Logging and TDD are orthogonal.  Having one has no bearing on needing the other

Do we need to log if we are doing TDD? won't a failing test reveal what wrong with the application?

By and large most logging that I've implemented, and that I've seen implemented has been for operational troubleshooting, not for development debugging (although it may help).  The primary audience for this logging are the admins and the ops who run your servers, support people who have logs sent to them for analysis, and customers who want to look at the logs and try and figure out what's going on.

These logs are there to help troubleshoot issues largely do to integration points.  This may network services (database, soap, etc), local resources (disk, memory, etc), bad data (customer input, bad/corrupt data sources, etc), etc.  Capturing exceptions, logging faults, and even doing informative logging (settings, configurations, etc) can all help with troubleshooting.

Should we add test for the logging process in each method in each class?

Add testing where ever you need to in order to test logging.  If you have ad hoc calls to log out information then they should be tested.  Although if you implement logging  and log testing using Aspect Oriented Programming or meta programming, that may reduce the burden of testing.

If some log levels are disabled in the production environment for example, won't that introduce a dependency between the tests and enviroment?

If you are writing your code using IoC and you make use of mocks, you should be able to effectively test all your logging without relying on a particular environmental setup.

Title: Do we need Logging when doing TDD?

Body:
When doing the Red, Green & Refactor cycle we should always write the minimum code to pass the test. This is the way I have been taught about TDD and the way almost all books describe the process.

But what about the logging?

Honestly I have rarely used logging in an application unless there was something really complicated that was happening, however, I have seen numerous posts that talk about the importance of proper logging.

So other than logging an exception I couldn't justify the real importance of logging in a proper tested application (unit/integration/acceptance tests).

So my questions are:

Do we need to log if we are doing TDD? won't a failing test reveal
what wrong with the application?

Should we add test for the logging process in each method in each class?

If some log levels are disabled in the production environment for example, won't that introduce a dependency between the tests and enviroment?

People talk about how logs ease debugging, but one of the main advantages about TDD is that I always know what's wrong due to a failing test.

Is there something I am missing out there?


问:
How to document self explanatory setter functions?
Often boolean setters are pretty self-explanatory, like setLogErrors($bool). I do see some benefit of providing some additional information in the documentation, in this instance maybe where these errors are logged. But how much documentation is too much, especially when it comes to documenting the value that is passed to the setter? Documentation tools like phpDocumentor would like that variable to be documented as well, but from the context it is pretty clear that it takes a boolean. Often I personally find it better when the code speaks for itself, especially in situations like this.

What is the best practice in situations like this? Should the argument be documented or not, how about the setter, should it be documented? Wouldn't the code readability improve if there was less documentation in this circumstance? I am not part of a large developing team and I don't read a lot of code written by others. I was hoping to gain some insight into what standards are set in larger organizations and what is the easiest for people to read when the code is not their own.

I hope this questions is not too opinion based.

答:
For the most part I agree with you, but then a different point-of-view occurred to me, which is when using an IDE.

If I'm editing Java code using Eclipse, it's really handy to be able to mouse-over a method and see the JavaDoc. If the method hasn't been documented, say because it's "obvious", I don't get any documentation. That makes me wonder - did the programmer just not bother? Could it be doing something else, even though it looks simple? Whereas by adding the "obvious" JavaDoc, I can quickly check that the method does, indeed, just do what I think (this relies on the JavaDoc being accurate, of course).

Besides that, leaving methods undocumented can be taken by lazy developers as an excuse not to document other, less obvious methods. There's something to be said for keeping up your standards.


问:
Is rapid prototyping incompatible with software requirements specification?
From what I've learned last term on SWE courses, a big part of it is writing documents, so it seems that a software requirements specification (SRS) should earn points for my end-of-course project.

However, I will be more comfortable if I use prototyping, i.e., I make a small thing that works for the most trivial of situations and gradually add up features and improvements. LVS 68:1996 doesn't seem to recommend mixing these two things together.

Is it possible to still maintain my preferred approach to development, and have some usable requirement specification document?

答:
SRS is used to put on paper the requirements for the whole project. Prototyping is used to prove that you're on the right path.

When you write the SRS, you may not always be sure whether:

The feature is feasible,

What if, technically, it is feasible, but your team will spend years developing it, because of the constraints of the language, the platform or the framework? A prototype let you know quickly that you're on the wrong path.

The approach you chose within the SRS is the right one,

There may be several solutions for the same problem, and it may be unclear, without further research, which one of them is right.

While SRS shouldn't enter in the implementation details, it is often difficult to be abstract enough to let developers pick the right approach. In order to avoid losing days, weeks or months later, creating several prototypes may lead you towards the most viable solution. It won't always get it right, but still mitigates the risk to write requirements which encourage the wrong solution.

The feature, as you describe it, is indeed what customers need.

Often, stakeholders don't know what they want.

One way is to write SRS, sign it, ship the product and when stakeholders will tell that it's useless, because it doesn't answer their needs, reply that it's conform to the SRS they signed.

Another way is to use Agile. It gives you the flexibility to adapt your product to the actual needs of the customers, and it gives the stakeholders the flexibility to adjust their needs based on something concrete.

Finally, a third possibility is to prototype parts of the application where stakeholders are not sure of their needs or don't agree among themselves, and only then sign the SRS.

In those cases, prototyping comes prior to SRS to make things clear.


问:
How to assure client that we will complete our project and won't run away with the money
I have decided to work as a freelancer. I have developed a software and have successfully given the presentation demo. The client liked it and has agreed to implement the project in his organisation.

But the client has asked me make it sure that I wont run away with the money  without completing the project. The cost of project is high and it is not possible to complete  it without acquiring the advance from the client.

What are the practice that is usually followed ? I myself somehow agree with the client query. I know I will be able to complete the project. I do not intend to cheat. But how to prove it to client? What to do in such situation?

答:
How do you ensure the builder that you contracted to build an extension to your house won't leave you with a half-finished extension?
You sign a contract in which it is specified that payment occurs in several installments, with final payment only after acceptance of the finished product.

For software development, the same kind of agreement can be used, especially if it is a longer running project (more than a couple of weeks), with the intermediate payments either based on time (monthly?) or on intermediate deliveries.

Regarding the size of payments, the intermediate payments should be enough to cover the costs you make (it shouldn't be needed that you eat into your reserves while working on a paid project), and the final payment should be a significant portion of the total sum to have an incentive to finish the project.


答: I would say bill weekly. If you show him progress every week, and send him a bill at the same time each bill will be small and you both can have some confidence</p>

Title: How to assure client that we will complete our project and won't run away with the money

Body:
I have decided to work as a freelancer. I have developed a software and have successfully given the presentation demo. The client liked it and has agreed to implement the project in his organisation.

But the client has asked me make it sure that I wont run away with the money  without completing the project. The cost of project is high and it is not possible to complete  it without acquiring the advance from the client.

What are the practice that is usually followed ? I myself somehow agree with the client query. I know I will be able to complete the project. I do not intend to cheat. But how to prove it to client? What to do in such situation?


答:
Languages differ in this respect, but I vastly prefer single attributes, which can be documented in one place. Something like:

```<code>"""Whether errors should be logged or pass silently, True by default"""
log_errors = True
</code>```

If you must have a getter and setter, the two should use almost identical docstrings. Document what the variable does, not just that you are setting a variable named log_errors.

Title: How to document self explanatory setter functions?

Body:
Often boolean setters are pretty self-explanatory, like setLogErrors($bool). I do see some benefit of providing some additional information in the documentation, in this instance maybe where these errors are logged. But how much documentation is too much, especially when it comes to documenting the value that is passed to the setter? Documentation tools like phpDocumentor would like that variable to be documented as well, but from the context it is pretty clear that it takes a boolean. Often I personally find it better when the code speaks for itself, especially in situations like this.

What is the best practice in situations like this? Should the argument be documented or not, how about the setter, should it be documented? Wouldn't the code readability improve if there was less documentation in this circumstance? I am not part of a large developing team and I don't read a lot of code written by others. I was hoping to gain some insight into what standards are set in larger organizations and what is the easiest for people to read when the code is not their own.

I hope this questions is not too opinion based.

Body:
Languages differ in this respect, but I vastly prefer single attributes, which can be documented in one place. Something like:

"""Whether errors should be logged or pass silently, True by default"""
log_errors = True

If you must have a getter and setter, the two should use almost identical docstrings. Document what the variable does, not just that you are setting a variable named log_errors.


问:
Unit Testing with an Optimization Problem
Suppose I'm making an algorithm that identifies the subject of a picture. It could be anything that a computer doesn't do that well, but I'm not expecting to get the right answer every time - 80% is fine. Suppose further, that the accuracy of the intermediate steps was also somewhat fuzzy. Is there a way to incorporate unit tests?

The option that immediately comes to mind is to add 1 to a tally and every time a 'test' passes, increment the tally. When that finishes, divide by the total and test 'passes/tests > 0.8', but that seems kludgey.

EDIT: Thank you all for your kind words and well-reasoned responses. My particular problem, while fuzzy, has nothing to do with pictures, and I'm currently getting about 80% pass. The short term value for me in a testing scheme would be knowing whether small adjustments were more globally beneficial or catastrophic. Long term testing value should be obvious.

答:
Unless your code uses some randomized technique, it is  deterministic, even if for a given input it is hard to specify or predict. So when we see a given input produce a given result, if we provide the same input we will see the same result again. This is true even for a learning algorithm or database application, where "the same input" means the same input being applied to the system in the same state.

If your algorithm does use a randomized technique, the usual approach is to turn off the random seed aspect of it for testing, so that tests always give the same "random" result. (We would not hard-code the seed, because the code would need to be changed and tested again every time we did testing, and so on).

So you should have a set of tests that are repeatable. For the same input to the same algorithm you should see the same result.

But you seem to be confusing the fuzzy nature of your algorithm with non-determinism. Even a fuzzy algorithm should give the same results from the exact same inputs.

A second issue seems to be that the algorithm is still being developed. This presents the same problem as regression testing any code under development. With simple changes to the code you should be able to predict the effect on the existing test cases. But because of the complexity of analyzing fuzzy logic code you may not be able to predict the precise result of the change. In this case, you could document each test with it's result against each version of the codebase, and prepare modified tests that exploit the algorithm changes.


问:
Sprint Planning Meetings - determine if a work item is "planned"?
We've been working with Scrum for a while now, generally successfully. However of late, as the pressure has started to mount up we've encountered several situations where items came through planning meetings but when it actually came time to code, it became apparent they were woefully under-specified.

This is an annoying and awkward waste of time. So I'm wondering, is there anything we can do to make sure that a work item is properly understood and planned before it's included in a sprint?

We don't use TDD, but my experiences with it suggest that it's a good way of ensuring a programmer understands a task before beginning work. So I did consider trying to work out some automated testing as a possible approach to this. But not all work items are amenable to automated tests, and it's likely to be difficult/boring for non-programmers in the meeting.

As an aside, out of curiosity, is when one has decided on acceptance criteria, should they go on a work item, or a user story, or both?

答:
INVEST is a good mnemonic to use for measuring the quality of your stories and getting better at writing them. The mnemonic states that a good story should be:

Independent: The user story should be self-contained, in a way that there is no inherent dependency on another user story.

Negotiable: User stories, up until they are part of an iteration, can always be changed and rewritten.

Valuable: A user story must deliver value to the end user.

Estimable: You must always be able to estimate the size of a user story.

Small: User stories should not be so big as to become impossible to plan/task/prioritize with a certain level of certainty.

Testable: The user story or its related description must provide the necessary information to make test development possible

You should also invest time in backlog grooming sessions. These should be well in advance before the sprint planning. Here you improve the stories, find out if you need more information. In sprint planning, you should refuse to take on stories that are too vague. For this evaluation you can use the above mentioned INVEST.

Often I found myself breaking a story in two stories: the first one contains the clear must-have parts and second the more vague or "nice-to-have" features. The first one is accepted to the next sprint and the second is groomed during that sprint with new information gathered from stakeholders and from implementing the first part.


答: I believe the trends you identify point at a truth about developing software - programmer time is more expensive that CPU time. Thus far, computers have only gotten faster and cheaper, but a tangled mess of an application can take hundreds if not thousands of man-hours to change. Given the cost of salaries, benefits, office space, etc, etc, it's more cost-effective to have code that might execute a little slower but is quicker and safer to change.</p>


问:
In git, is it a bad idea to create a tag with the same name as a deleted branch?
I have a project with a git branching model that roughly follows that of nvie's git-flow.

Our release branches are named in a SemVer format, e.g. v1.5.2

Once a release branch is given the green light for production, we close the branch, by merging it into master, applying a tag, and then deleting the branch.

As we immediately delete the release branch, we've been using the same identifier for tagging the branch, e.g. v1.5.2

Here's the commands we'd use to close a release branch:

```<code>$ git checkout master
$ git merge v1.5.2
$ git tag -a v1.5.2 -m "Version 1.5.2 - foo bar, baz, etc"
$ git branch -d v1.5.2
$ git branch -dr origin/v1.5.2
$ git push origin :v1.5.2
$ git push
$ git push --tags
</code>```

This seems to work in the majority of cases, however it's causing an issue in the scenario where another instance of the git repo (e.g. another dev machine, or staging environment) has a local checkout of the v1.5.2 branch.

The git push origin :v1.5.2 command will delete the branch in the remote, but does not delete the local version of the branch (if it exists) in all repos.

This leads to an ambiguous reference, when trying checkout v1.5.2 in those repos:

```<code>$ git checkout v1.5.2
warning: refname 'v1.5.2' is ambiguous.
</code>```

Can this be avoided without using a different syntax for the branches, e.g. release-v1.5.2, or v1.5.2-rc?

Or is it unavoidable, and therefore a fundamentally bad idea to create a tag with the same name as a deleted branch?

答:
If you absolutely want to keep this naming scheme, you might:

Decide that you don't care about these warnings

That is, if you're happy with the fact that:

git checkout <ref> will check out refs/heads/<ref> over refs/tags/<ref> (see git-checkout)

other commands will use refs/tags/<ref> over refs/heads/<ref> (see gitrevisions)

For example, in this test repository, the v1.5.2 branch points to commit B, but the v1.5.2 tag points to commit A.

```<code>% git log --oneline --decorate
8060f6f (HEAD, v1.5.2, master) commit B
0e69483 (tag: v1.5.2) commit A
</code>```

git checkout prefers branch names:

```<code>% git checkout v1.5.2
warning: refname 'v1.5.2' is ambiguous.
Switched to branch 'v1.5.2'
% git log --decorate --oneline -1
8060f6f (HEAD, v1.5.2, master) commit B
</code>```

but git log will use the tag name:

```<code>% git log --decorate --oneline -1 v1.5.2
warning: refname 'v1.5.2' is ambiguous.
0e69483 (tag: v1.5.2) commit A
</code>```

This could be confusing.

Train people to delete their local branches when they see a new tag

This might be hard/awkward depending on the size of your organisation.

Write a wrapper around "git pull" and "git fetch"

That is, write a wrapper that checks if there are any tags that shadow branch names, and warn about (or delete) those branches. This sounds painful, and it could be undesirable if the shadowed branch is currently checked out.

Unfortunately, it sounds like the easiest way to solve this problem might be to change the way you name your branches. The link you posted uses different naming schemes for tags and branches: if you're already mostly following that method, adopting its naming scheme might be the easiest solution.

Body:
If you absolutely want to keep this naming scheme, you might:

Decide that you don't care about these warnings

That is, if you're happy with the fact that:

git checkout <ref> will check out refs/heads/<ref> over refs/tags/<ref> (see git-checkout)

other commands will use refs/tags/<ref> over refs/heads/<ref> (see gitrevisions)

For example, in this test repository, the v1.5.2 branch points to commit B, but the v1.5.2 tag points to commit A.

% git log --oneline --decorate
8060f6f (HEAD, v1.5.2, master) commit B
0e69483 (tag: v1.5.2) commit A

git checkout prefers branch names:

% git checkout v1.5.2
warning: refname 'v1.5.2' is ambiguous.
Switched to branch 'v1.5.2'
% git log --decorate --oneline -1
8060f6f (HEAD, v1.5.2, master) commit B

but git log will use the tag name:

% git log --decorate --oneline -1 v1.5.2
warning: refname 'v1.5.2' is ambiguous.
0e69483 (tag: v1.5.2) commit A

This could be confusing.

Train people to delete their local branches when they see a new tag

This might be hard/awkward depending on the size of your organisation.

Write a wrapper around "git pull" and "git fetch"

That is, write a wrapper that checks if there are any tags that shadow branch names, and warn about (or delete) those branches. This sounds painful, and it could be undesirable if the shadowed branch is currently checked out.

Unfortunately, it sounds like the easiest way to solve this problem might be to change the way you name your branches. The link you posted uses different naming schemes for tags and branches: if you're already mostly following that method, adopting its naming scheme might be the easiest solution.


答:
If you don't have a requirements spec, you don't know what you're supposed to be doing. Requirements come before everything else.

Prototyping is a valid way of proving whether something can be done, but this is not part of the requirements, its part of the solution delivery. Sometimes you're given a specification and tasked to writing a solution document to describe how you will implement the requested features. This is where some prototyping comes in, as you determine your solution (and to be fair, I tend to "prototype" my solution before documenting what I "will do" ;) )

Title: Is rapid prototyping incompatible with software requirements specification?

Body:
From what I've learned last term on SWE courses, a big part of it is writing documents, so it seems that a software requirements specification (SRS) should earn points for my end-of-course project.

However, I will be more comfortable if I use prototyping, i.e., I make a small thing that works for the most trivial of situations and gradually add up features and improvements. LVS 68:1996 doesn't seem to recommend mixing these two things together.

Is it possible to still maintain my preferred approach to development, and have some usable requirement specification document?


问:
Why is ~0 a Sequence of 1s
Why is ~0 a sequence of 1 bits and not just a single bit? Where do the extra 1 bits come from? Does this mean ~1 a sequence of 0 bits or just a single 0 bit?

My understanding was that the ~ operator is applied on the specific bits mentioned.

答:
Because that is what ~ does.

It flips the bits of the operand. If your language of choice treats that literal 0 as a byte value, it is essentially:

```<code>00000000
</code>```

When the bites are flipped using the ~ (bitwise NOT), the result is:

```<code>11111111
</code>```

In the same way that ~10 would turn:

```<code>00001010
</code>```

To:

```<code>11110101
</code>```

Title: Why is ~0 a Sequence of 1s

Body:
Because that is what ~ does.

It flips the bits of the operand. If your language of choice treats that literal 0 as a byte value, it is essentially:

00000000

When the bites are flipped using the ~ (bitwise NOT), the result is:

11111111

In the same way that ~10 would turn:

00001010

To:

11110101