答:
I would add that if a "Junior" programmer can not understand a seniors code then that in itself is a good measure of the code. OK there may be times when it just isn't possible to write code that everyone can understand, but hopefully those are exceptions - if only 1 or 2 people can understand the code then what happens when those people are not available and there's a problem with it?

Giving people new challenges helps them develop; it might also be that not everyone is cut out for reviewing code but it seems dogmatic to insist someone has a title (determined by HR politics and games) before they're eligible to help in a review.

As others have pointed out a code review can be a two way process; it helps everyone understand the code base, so shares the knowledge, it helps juniors learn new and better ways and techniques from their seniors and it helps the seniors refine their understanding and by writing to ensure everyone can follow the code you have more eyes that can catch mistakes.


问:
Applying DRY to an inheritance hierarchy
I'm working on refactoring a legacy application where I implemented the State pattern successfully as shown in the following diagram:

As you see there is a common behavior between the 3 states, so I decided to extract the common method Refund() to a parent abstract class RefundableState where I implemented it:

Refactoring further I notice that the Ship() method is common between the 2 states Cancelled and NewOrder, so I go for another round of extracting the common behavior to another parent class ShippableState:

Now I need my Cancelled state to extend 2 classes and in the same time I can't group the Refund() and Ship() function together as not all state permit the 2 actions.

How can I fix this?

Notes:

This question is mainly about applying DRY and refactoring not about how to implement the state pattern.

I'm using PHP 5.3, but I'm open to answers in any other languages.

答:
Why not keeping things simple? You can easily keep your code DRY without any extra classes (your first design), and opposed to the other answers here, IMHO there is no need to sacrifice the DRY principle for this case.

If the "Refund" method is equal in all three cases, or the "Ship" method in just two, implement those methods in "OrderState". If the implementation is only similar, but not identical, refactor the differences to virtual helper methods which are overriden in the subclasses (this is called template method pattern). And if you want to separate the interface from the implementation (which has nothing to do with "DRY", only with "separation of concerns"), then replace the class OrderState by an interface IOrderState, and let OrderState inherit from IOrderState, providing default implementations as well as reusable code for the other subclasses.

If the "Shipped" class does not need a "Ship" implementation at all, put the common functionality into a new method OrderState.DoShip, and call that method from Cancelled.Ship and NewOrder.Ship, but not from Shipped.Ship (the last one should throw an exception or do nothing, whatever is appropriate in your case).

And if the implementation of "Refund" or "Ship" methods reaches a certain size, and needs several helper methods and perhaps some state variables, then it is time to think about extracting those methods to helper classes like "Refunder" or "Shipper" (which are not getting part of your inheritance hierarchy).

ContentLicense: CC BY-SA 3.0


问:
How to convince my coworkers that doing things right will save them time
I recently started at a new company, with a handful of programmers. Its a medium sized company, with around 70 employees, but IT only has 9-10, and there are 3 "programmers" beside myself. However, these guys have very limited experience and are doing a lot of stuff really terribly. For example, one of our projects is a PHP website. The majority of the code is stored in a 20,000 line PHP controller, with ~6000 lines of JavaScript embedded in the PHP.

I keep making small suggestions here and there but nobody has been listening, everyone says they are too busy to implement my suggestions. The thing is, they shouldn't be that busy, and wouldn't be if things were done right. They spend most of their time fixing things that keep breaking. If each project was built correctly, I could do it all myself.

What approach should I take to convince these guys or the manager that things need to change, and that changing things will save a bunch of time? Should I skip trying to convince my coworkers and go straight to the manager, with a business-y proposal on how the company will save a bunch of money if they start doing things correct?

答:
Sit and write the prototype (or some module if the whole project is too big) that uses really good design as you see fit. Then present / discuss it with the team. It may be easier to convince by example.

In this process, you may also discover that some tools, libraries, approaches or the like are not that good. Always evaluate first and ask your team to use that later. Beware of cheap marketing around substandard tools.


问:
Using double dot notation in URL link
I've recently been working on a project and I've been seeing two different forms of url's being used.

```<code>src="../MyLinkUrl"
</code>```

and

```<code>src="/MyLinkUrl"
</code>```

We are using MVC .NET and the times I have seen the .. usages have been in Javascript code files and not when it's been generated by the MVC URL helpers.  Typically the usages range from specifying a controller action to specifying images.

Both seem to work but I'm wondering which is the better practice or if it depends on the context.  Some questions I have are:

What benefits/pitfalls does one have over the other

Is one better practice than the other

Does it depend on context and if so what context?

答: It is probably better to use relative path (../../otherdir/file.html) as it changes less frequently and you may save on maintenance and refactoring. For instance, correcting some spelling mistake in the folder name will always break the absolute path to that folder but may not break the relative path.

Title: Using double dot notation in URL link


问:
Should a service use session information?
As an example, if I have a Post service and have a method to retrieve all posts for the logged in user, is it OK to have a findPosts() method that uses an injected Security service to get the user ID and then pass that user ID to my post DAO to get the records? Or should the findPosts() method explicitly require the user ID as an argument?</p>

答: Your service should get all the information it needs to do its job in its parameters. If your service is calling something else to get a userID or anything else it needs to generate its return object that is a poor design.</p>


问:
How to identify (business) processes for automation?
I recently started at a company and am working on statistical data analysis and data handling (market research). A lot of my tasks were previously done entirely by hand, so I created a few tools to automate much of my work.

My boss asked if I could go ahead and look for other automation-possibilities. I certainly have the time and skill, but I don't know how to find processes which would be good candidates to be automated.

I could ask co-workers, but most of them don't understand what is easy to automate and what isn't. I believe that there are  processes for this sort of thing - but I don't know enough to start Googling.

What comes before requirements discovery and analysis?

How do I identify business processes that will be more efficient as automated tasks?

答:
You should ask your colleagues about the processes they use on a daily basis, where they spend most of their time, or what they do that they wish they didn't have to do.

Don't ask them what they want automated because you'll be less likely to get good feedback.


答: Maybe write usecases for the most common tasks in your organisation and invite your boss (or someone else in the organisation) for an "interpretive review", were he/she reads the cases out loud and explains how he/she understands it (and whether he/she agrees). In my experience, when concrete descriptions of workflows is interpreted by an involved part, patterns and anomalies are recognized, and automatable processes can be identified. </p>

Title: How to identify (business) processes for automation?

Body:
I recently started at a company and am working on statistical data analysis and data handling (market research). A lot of my tasks were previously done entirely by hand, so I created a few tools to automate much of my work.

My boss asked if I could go ahead and look for other automation-possibilities. I certainly have the time and skill, but I don't know how to find processes which would be good candidates to be automated.

I could ask co-workers, but most of them don't understand what is easy to automate and what isn't. I believe that there are  processes for this sort of thing - but I don't know enough to start Googling.

What comes before requirements discovery and analysis?

How do I identify business processes that will be more efficient as automated tasks?


答:
In my experience, you really have to walk a mile in their shoes.  Ask if you can help them do their job for a morning.  Walk through everything they do.  Ask questions about what they do in certain circumstances (it's usually the rarely-but-once-a-month stuff that makes it hard to automate).  Then go back and put together a functional specification.  Then walk them through the idea verbally and get their feedback.  Having the discussion will bring up other ideas they didn't think about before.  You might need one or two revisions.

That's the best way I've found.  People rarely come to you with ideas because, as you said, they don't know what's easy and what's hard.  However, once you do this a couple of times, they'll start to get a feel for it and they'll start to suggest small improvements, etc.


答:
It sounds like you're trying to elicit requirements.

There are many techniques for eliciting requirements, but I would suggest observation as a good method. Simply watch people perform their daily jobs and identify manual activities that are repetitive or frequently performed - these may make good candidates for automation. It will also help you better understand the business and the roles of various people.

If there are people who are willing and able to take the time, you may also couple interviewing with observation. Ask questions about what they are doing, why they are doing it, and if they have any complaints or problems with the current process. This may not always be possible if people are extremely busy or have tight deadlines, but you may be able to find some people willing to take a short break or have a working lunch.


答:
It's fine for one service to utilize another service in order to do it's work. That's not a problem. However, if your PostService.FindPosts() method needs a userId, don't pass it a SecurityService, pass it the userId. In fact, you may want to call it FindPostsByUserId() just to be more explicit.

Now, you may have to get the userId from a SecurityService injected into the PostsService, but that's another issue.

Title: Should a service use session information?

Body: As an example, if I have a Post service and have a method to retrieve all posts for the logged in user, is it OK to have a findPosts() method that uses an injected Security service to get the user ID and then pass that user ID to my post DAO to get the records? Or should the findPosts() method explicitly require the user ID as an argument?</p>


答:
There are differing philosophies, but it very much depends on the context and requirements of your work. If multiple asynchronous connections for different service requests are required to share state that the client should not be aware of then you have few options besides some sort of session management (whether the built-in, or your own based on security tokens or other identification mechanisms). Generally speaking, however, sessions are not necessary nearly as often as they are used and often tend to lead to complications later. Session is volatile, not usually inherently thread-safe, and tied to arbitrary client details in the first place (cookies, IPs, etc.) When you don't control the client Sessions can be unreliable. I could, for example, implement a RESTful GET only client with nothing but raw HTTP requests (which someone else has actually done to me before). As a result common implementation details like cookie persistence become a requirement of your service; this isn't all that uncommon, but the less unnecessary requirements you use the more reliable the clients experiences are.

In general, whenever possible, let the state be directly associated with the individual requests. This allows individual clients more flexibility because your design explains itself and does not depend on hidden features the client won't be able to predict. It also more naturally allows multiple concurrent connections from the same client to have entirely different purposes and state. Let's say their website allows individual user logins and they make calls to your service (API) specific to the individual users; if multiple of their users are using the app at the same time you don't want to force them into a single session if they can just provide you a token with each request or something similar. It can be easy to lose track of state mutations when they are in an invisible background space and, even if the service is simple in the beginning, future additions may not realize something was using session a certain way, etc. etc. Really, this is very much the same as web pages. If you rely on session for page specific operations the user cannot use multiple tabs as it will pollute the state, whereas storing state data in a hidden form field or query string allows each tab to maintain its own state.

Generality aside, there are certainly circumstances that call for it. Distributed computing environments like WCF and other RPC system layers leveraging web services make use of service instance tracking, persistent internal fields, shared context, etc. These features either use Session or at least function very similarly from an abstract perspective. Some people disagree with these methods, but the right tool for the right job should always be the aim.

In your specific case, it sounds like you're really just trying to share authentication state between the browser and async backend requests. Authentication state is frequently sustainable in web services. Particular to authentication, it seems like you should be using security checks even if you received a userId (since it shouldn't just hand that information out to anybody) and since you already have the data it sounds perfectly safe to me (less error/hack prone, since you don't give them the option to tell you which user to use). Alternatively you can receive the parameter specifically to verify that they aren't tampering with the requests, though that only goes so far. Again, just like a web page, sharing authentication between browser tabs is not uncommon, even if the tabs have very different pages loaded, but those pages (or associated middleware) are still responsible for determining what the user can see as well as ensuring the user has the right to be on any specific page.

tl;dr - There are merits to both approaches in this context, including the use of both in tandem. Authentication is commonly shared in web services of differing variety. If these are for Ajax requests then it's especially common. In general, however, only use background shared state when necessary (much like with webpages). The same kind of care goes into deciding what will be static, thread-static, etc. Remember kids: only you can prevent forest fires. KISS


问:
How do I learn algorithms and data structures?
This is in continuation to my previous question where I asked is it necessary to learn algorithms and data structures. I feel yes it is.

Now I work in an environment where I won't ever get the chance to learn it by experimenting or practically or in any assignment. What is the right approach like the right books, right kind of problems, right kind of resources that I can go through to give six months or a year or two to learn algorithms and data structures?  And also mold my mind in a way that it can relate problems to data structures and algorithms.

答: See if you can take an online course, or get tutored.  Failing that, this popped up in a quick google search.  I just took a class on it this past spring (first ever, I moved from EE to software) and it wasn't too hard to pick up if you understand pointers well.

ContentLicense: CC BY-SA 2.5


问:
Feasibility of continuous delivery with a mixture of development platforms
What are the major obstacles (and potential solutions, if known) for implementing "continuous delivery" software development when an application relies on varied programming languages or modules... especially when the same version-control and/or automated testing packages do not exist for those disparate platforms?

For example, a Java web application that is deployed and running on a Linux host, talking to a DB2 database back-end via JDBC, with occasional calls to stored-procedures that wrap RPG or COBOL or C programs on that same back-end?  What if the code for all of that cannot be contained in the same version-control/source-control system?

Is it possible to get to the illusive "push-botton release" in this situation?  Or do you have to have EVERYTHING in the SAME VCS?  Additionally, how would one manage the creation/modification of database schema, and so-called soft-code control values in the database?

Is there a more-or-less "canonical" published work on this type of thing?

答:
The fact that you have these different development platforms should not be an obstacle in terms of continuous delivery. The complexity of interacting with these platforms is managed by your build tool and most tools have support for the environments / platforms you mention.

For example with CruiseControl.NET you would have a task that checks out your Java web app (it can interact with git, hg, svn, visual source safe etc), that is then compiled according to the definition in the project build. Deploying it to a Linux host can be done over ftp or UNC paths, in fact if you can script it in a command line then you can just use that in your CCNet build.

The more challenging part of CD is to migrate your database, but again this is not a limitation of the build process - if you can script the task then you can automate it with your build server of choice, be that CCNet, TeamCity, Jenkins or whatever.
In the .NET world the RedGate suite of tools are very helpful here, we use SQL Compare to compare the development copy of a database to the UAT environment and also the version controlled copy using SQL Source Control, it generates a script and we invoke the task with the command line interface provided. This then updates the database. Actually in DEV and locally we drop the database and recreate it, then seed it with data using SQL Data Generator, but it isn't hard to script out the data to populate a clean copy of the database with. For production it's obviously harder as we can't drop the database and migrations are required and these we again lean on red gate for, but can be manually created and dropped into the build resources so the build server can apply them as part of the CD.

In terms of a good source of information check out a series of posts by Roy Osherove that discuss some best practices, or Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation by Jez Humble


问:
System Requirements - Use of Conjunctions
I have come across many blogs and books where it is stated that it is bad for a system requirement to contain conjunctions like "and". However in reality I am often coming across scenario where a requirement is satisfied when a certain set of conditions are met. For instance, Shopkeeper should sell alcohol only if the buyer is older than 18 years, he has the necessary proof and he does not have any alcohol related problems. The requirement would not be complete if I break it down into multiple system requirements and I cannot complete the requirement without use of "and".</p>

答:
You could phrase it as a tree. This avoids any sort of grouping ambiguity in natural language.

Alcohol can be sold if the buyer meets all of the criteria

Buyer is older than 18 years.

Buyer has the necessary proof of age.

Buyer does not have any alcohol related problems.

This approach also works well for or(One of the following), and nested items.


答:
Consider using both approaches (stand-alone and conjunctive) for your rules.

Using the example you cited, you would have three stand-alone rules:

1.  only if the buyer is older than 18 years

2.  has the necessary proof of identification

3.  does not have any alcohol related problems

And then have a conjunctive rule for all three of the stand-alone rules.

1 + 2 + 3  == true

Your stand-alone rules represent the core of your system requirements.  The conjunctive rules represent a higher level or requirements that could change based upon the jurisdiction.

Title: System Requirements - Use of Conjunctions

Body: I have come across many blogs and books where it is stated that it is bad for a system requirement to contain conjunctions like "and". However in reality I am often coming across scenario where a requirement is satisfied when a certain set of conditions are met. For instance, Shopkeeper should sell alcohol only if the buyer is older than 18 years, he has the necessary proof and he does not have any alcohol related problems. The requirement would not be complete if I break it down into multiple system requirements and I cannot complete the requirement without use of "and".</p>


答:
There is no reason that all the conditions have to be one requirement.

The system shall sell alcohol only to those older than 18.

The system shall require proof of age to sell alcohol.

The system Shall not sell alcohol to those with alcohol related problems.

These are all perfectly valid requirements, and the system is not valid unless it meets all the requirements. System requirements are all implicitly connected with an "and" its why the are requirements and not wishes. Furthermore by expanding each condition to its own requirement it is far easier to track what has and hasn't been met this way because each requirement is a binary yes or no.


问:
handling rules applied to a set of checkboxes, radio buttons or form fields
I've been wondering about applications that have a set of checkboxes or radio buttons, even collections of form fields in their UI.

At this moment I'm handling all the choices separately but of course this becomes a complete mess very quickly. There has to be an established way to deal with this that I don't know of.

If check box a is unchecked then check boxes d through e are enabled etc. etc.

How should I be approaching this? Not in the UI of course, that's for sure.
I would love to hear some insights and best practices as well as potential pitfalls.

(BTW: I've tagged this "rules-engine" because I haven't got a clue what to tag this. Please feel free to edit the question, retag and remove this line.)

答:
I built an e-commerce site with a complicated set of product configurations.  When the user went to the individual product's configuration page, it needed to load the available options, enable/disable controls based on the choices made, and update price on-the-fly.

The data model stored all of the possible options for every product.  I wrote a ConfigurationEngine class which contained the logic for all of the allowed combinations (many simple cases were stored in the DB, others had to be coded).  When the user made any change on the product configuration page I made an AJAX call.  The server would put together the product object with its selected configuration and pass it through the ConfigurationEngine.  The product came out validated and priced.  Another function on the engine would tell us which remaining options were still available.  The product price, validation messages, and remaining available options were then passed back to the front-end in response to the AJAX call.


答:
Management's Perspective of the Problem
If they have accepted the time of development in relation to the amount of defects, why would they risk it? When long-term benefits contradict short-term objectives, they usually lose. You are asking them to take a short-step back. They may think this will cause a lengthy delay. You have to convince them it won't along with the added benefits. If they don't think they have a mess, ask them to explain why it takes so long to quickly introduce new bugs with each "fix".

Code quality is contingent on many circumstances and situations. Sales, marketing, and managers will make you believe every failed deadline means the company will miss that one shot at the mega-million venture capital investor. The reality is, they don't want to break the bad news to the 1% of your clients who really didn't need the feature anyway. I'm being extreme and usually it falls somewhere in between, so developers need to learn what is an actual emergency. Then it's easier to convince them to take the time to do it right instead of needing time to do it over. You have to understand the risks.

Like a great novel, code isn't written well the first time, but unfortunately it still gets published too often. Start with something fundamental like establishing a coding standard. Everyone has one, but many like in your situation, they haven't been formalized nor are they very stringent. "Do whatever you want." is a standard that's very easy to maintain. The next step is to determine how you're going to maintain your standards.

You have a major task ahead of you. Maybe a few great programmers have developed their skills and habits to the extent they never have to compromise on the quality of their code or go into technical-debt, but wait and see what happens when that angel investor promises everyone will get rich.

Title: How to convince my coworkers that doing things right will save them time

Body:
I recently started at a new company, with a handful of programmers. Its a medium sized company, with around 70 employees, but IT only has 9-10, and there are 3 "programmers" beside myself. However, these guys have very limited experience and are doing a lot of stuff really terribly. For example, one of our projects is a PHP website. The majority of the code is stored in a 20,000 line PHP controller, with ~6000 lines of JavaScript embedded in the PHP.

I keep making small suggestions here and there but nobody has been listening, everyone says they are too busy to implement my suggestions. The thing is, they shouldn't be that busy, and wouldn't be if things were done right. They spend most of their time fixing things that keep breaking. If each project was built correctly, I could do it all myself.

What approach should I take to convince these guys or the manager that things need to change, and that changing things will save a bunch of time? Should I skip trying to convince my coworkers and go straight to the manager, with a business-y proposal on how the company will save a bunch of money if they start doing things correct?


问:
What is the most egregious waste of money you have seen, and what did you do about it?
Often we as programmers see large organisations wasting huge sums of money on bloated and inefficient solutions to problems. This pains me greatly because I like organisations to benefit from best of breed solutions. However, my abilities as a programmer are limited when it comes to influencing the key decision makers and often my perspective on the matter is constrained to my own little technical world.

So, my question is this. After encountering an egregious waste of money on some software and/or hardware that really got your goat, what did you do about it to get it fixed or were you doomed to bite the bullet and mutter forever under your breath? I'm interested in hearing your overall experiences and especially what lessons you learned about how to tackle this sort of thing in the future. Let's not name names, the experience of how to tackle the problem is more important than the actual offending product.

答:
This answer is somewhat different than most: not firing an employee soon enough, or stated differently, being overly tolerant of an employee's <s>mistakes</s> habits.  These were things I've observed and couldn't do much about as a consultant.

The dev that poorly drove the design decisions of a project that led to its eventual rewrite (it was a complete mess).

The dev that sent sensitive unencrypted data to Google Charts because they thought it would be cool to show a pie chart (was a pie chart a requirement? Nope!).

The dev that consulted with a company in the past and accepted a position with them directly. He did an about face and turned into a prima donna that sought the Technical Lead position and went as far as talking to the lead's manager stating they thought it would be good for him to take over as the lead. Talk about audacity! A lot of devs no longer like the guy and he burnt a lot of bridges within his first 2 weeks as an employee. To top it all off he's a very green dev that only graduated 2 years ago but thinks he's awesome.

A few mistakes are understandable, but when there's a consensus between many devs about someone's attitude or skill level companies ought to get rid of them sooner rather than later.


问:
Should Junior Programmers be involved as code reviewers in the projects of Senior Programmers?
One of my team members, a junior programmer, has impressive programming skills for his level of experience.

And during code reviews, I believe in emphasizing learning, not pointing out mistakes.

But should junior programmers be involved in code reviews for more senior programmers? Or should code reviews be attended only by programmers with corresponding experience?

答:
I'm a strong believer that everyone in the team should be involved on both sides of code reviews. Juniors should review Senior code, and vice-versa. Why both? Because usually it's not just about if code is "solves the problem". I can't tell you how many times I've had to explain a piece of code to someone and suddenly come up with a much better way of doing it by the end of the explanation. Code reviews serve probably 3 purposes:

Ensure code is correct

Get the writer to think about how others will see their code

Get the reader's feedback on what could be improved and a general second pair of eyes

I'm a junior and I commonly review senior written code. It's a general company policy "everything gets code reviewed by someone". I learn a lot from these reviewing their code and having the opporunity to ask questions about why things are done in a certain way. And sometimes, I propose a cleaner way to do a certain piece of code and such. Much more rare than people telling me how to improve my code, but it has happened at least once.

It also matters how formal your code reviews are. Ours are very informal and consist of "hey will you look at my code" being said across cubicles or in a private IRC channel. I could imagine if you review the code in a more formal setting, the junior would probably be much more intemidated about reviewing a senior's code.


问:
Object-Oriented Design: What to do when responsibility of the class is big
I applied principles of the GRASP and ended up having a class called Environment.
This class's responsibilities are to:

Keep information about services in the environment,i.e. environment definition (Service is another class)

Start/stop services meeting some criteria

Apply configuration changes to different service and keep list of updated services

Restart services with configuration change

Revert configuration changes at the end of session

Search/Give  Service class based on criteria (name etc.)

According to OOD, this is not a problem: very cohesive responsibility is assigned to this class.

But on the other hand it's a problem since the class is too big, even though all responsibility assigned to it makes sense. If I want to divide this responsibility to between separate classes, then all these classes need to know about "environment definition", which makes coupling worse and those classes will have "feature envy".

What design patterns are applicable for such situation? Or what other principals can be applied to have cohesive, less coupled classes?

Thanks in advance.

答:
For one, keep in mind that classes do not do things to other classes as in "Apply configuration changes to different service".

I would see the above as a ConfigurationChange class with potentially several derived types such as DbChange, PropertyFileChange, etc.  Service would be a class with an applyConfigurationChange(ConfigurationChange) method.  The environment would mostly be a coordinator, sensing when a ConfigurationChange has occurred, creating the appropriate ConfigurationChange instance and passing it to the effected services.

It also sounds like each Service would "have a" configuration stack which would support a pushConfiguration() and a popConfiguration() methods in order to support numbers 4 and 5 above.

The important thing is to keep your classes singularly focused - if they are performing more than one overall behavior, you should consider breaking each type of behavior out into a specific class - either to encapsulate complexity or for re-use.  I like to think of it like this - code embedded in a class that performs some functionality may work great, but you can't use it anywhere else and you can't relocate it easily when something changes.  Code in a well designed class that performs as advertised (i.e. each function does what it says it does), is easily moved around and can be trusted.  By making behaviors a separate class, you are giving the behavior an API that separates it from the client class, providing your desired decoupling.

Finally, avoid any class that looks like or operate like a Manager class.  In almost all instances I have seen, these classes become huge, bloated monsters.  Rather than have a class that manages a set of classes, design each class to manage itself.  Their typically is no class that knows more about itself than itself, so it should be the one managing itself.  This is especially true of classes that are Threaded.

Another technique which can break up huge monolithic classes is to consider the individual activities that the class performs as unique classes - classes that are instantiated to handle a specific activity, gathering in the required instances, performing the work and then dissolving away - sort of like a dispatch pattern.

OwnerDisplayName: Azho KG


问:
Problems Calculating Big-O Complexity
I'm a complete beginner to Java, only in my second quarter of classes. I'm having trouble understanding our current chapter about calculating big-O for methods. So I thought I was right in saying that the big-O for these two methods is simply O(N), since there is only one loop that loops through the entire list, but apparently they're either O(NlogN) or O(logN). I really can't see why. Can anyone help me understand?

1)

```<code>public static int[] mystery1(int[] list) {
    int[] result = new int[2 * list.length];
    for (int i = 0; i < list.length; i++) {
        result[2 * i] = list[i] / 2 + list[i] % 2;
        result[2 * i + 1] = list[i] / 2;
    }
    return result;
}
</code>```

2)

```<code>public static void mystery2(int[] list) {
    for (int i = 0; i < list.length / 2; i++) {
        int j = list.length – 1 – i;
        int temp = list[i];
        list[i] = list[j];
        list[j] = temp;
    }
}
</code>```

These aren't homework problems, they were on a test I just took and miserably failed since there were only 4 questions and these two were wrong. I just want to understand why these two aren't O(N) complexity (professor won't give out the answers since someone hasn't done the test yet).

These questions were taken straight from the book for the test... which is why I was confident I was right since I had done them already. It was a multiple choice test, and the only options were a)O(1) b)O(N) c)O(logN) d)O(NlogN).

答:
The first one looks linear to me; given an input array, a result array twice as large is created, and then every element of the input is traversed to produce two elements of the result. Assuming constant access time for arrays in Java (which is true) and constant array/list length checking (also true AFAIK), given N input elements, all N input elements are traversed, 3N input accesses are made, and 2N assignments are made. This is O(N) plain and simple; if this was the code from the test and you said O(N), you are right and your prof is wrong. The fact that there are multiple steps happening for each iteration of the loop is immaterial; it's not an O(NlogN) function just because each element is accessed three times and the list happens to have 1000 elements.

The second one also appears linear. Given an input collection, the loop traverses half of it, and swaps each of those elements with the "mirrored" element on the other half (basically reversing the collection). Again, neither the fact that 3 reads/writes are made to list elements, nor the fact that only half the items are traversed by the outer loop, makes this a logarithmically-based algorithm; it, like the first, is O(N)-complexity, provided that the collection is constant-time to access.

In fact, I cannot see any way that either of these would be O(logN). Both of them might be O(NlogN), if there's something you're not telling us; that the input collection which you are showing us as an array is actually a Map, using a red-black tree for its internal structure and thus providing log(N) access time. Then the complexity of both of these would be O(NlogN), because for each of the elements traversed by the loop, you spend some constant multiple of logN time reading or writing to elements of the collection.

However, if the problems are exactly as you have stated, your prof is wrong, you are right, and you should make a stink about it to him and to anyone above him that you can get to care, depending on how much of your grade this test represents.

EDIT FROM UPDATE: OK, now we see that the prof marked the wrong two questions wrong:

```<code>public static void mystery3(List<String> list) {
   for (int i = 0; i < list.size() – 1; i += 2) {
      String first = list.remove(i);
      list.add(i + 1, first);
   }
}
</code>```

This one basically swaps each pair of elements; it does so by removing and then re-adding each element to a mutable List collection. Now, if it were a true swap, with a temp variable like you'd use with an array, it would indeed be linear. However, with a List, when you remove or add items in the middle of the collection, the List class automatically rearranges the existing items in the array that it uses behind the scenes to store the elements, by "shifting" each element above the removed element to the next lower index. A removal of element in index X from a collection of N elements will result in N-(X+1) shifts. Same thing in reverse when an element is inserted in between two existing elements; the existing elements to the right of the insertion point are each shifted one place further right to make room.

So, for N elements, it performs N/2 traversals, but N inserts/removals, each of which results in N-(X+1) shifts. As X will, at some point, have the value of every index in the list, this produces a triangular number of total value assignments, N(N-1)/2, which makes it O(N2) complexity. This is a very common breakdown for a quadratic-complexity algorithm; for each index, do something with each higher (or lower) index. Most of the quadratic sorts (e.g. SelectionSort, InsertionSort, BubbleSort) behave in this general way.

```<code>public static void mystery4(List<String> list) {
   for (int i = 0; i < list.size() – 1; i += 2) {
      String first = list.get(i);
      list.set(i, list.get(i + 1));
      list.set(i + 1, first);
   }
}
</code>```

This one performs a similar pair-swapping operation on the elements of the List. However, this implementation is a true "temp swap" as mentioned above. The algorithm swaps pairs, but does so without changing the number of elements in the List; instead, a simple variable first is used to store the variable that is then overwritten in its current position in the List. So, for N/2 traversals, 2N reads/writes are performed, making this algorithm, which does exactly the same thing as the previous one, linear instead of quadratic.

Now, you said you marked this as linear. That's the right answer. Where it might not seem so (and this will be important elsewhere) is that strings in Java are immutable. Once created, they're never changed "in-place"; if the value of a string is modified, it results in the creation of a new String object in memory, and the old one, if nothing else references it, is orphaned for the garbage collector to deal with. So, the modification of a String is an operation linearly time-bound to the total number of characters in the string, because each of those characters must be copied from its current location into the proper new location in the new String. If that were happening, then this would be a linear operation of linear operations, producing a quadratic total time-complexity.

However, that's not happening in this algorithm. Java Strings are also "reference types", meaning that in an assignment of a string from one variable to another (including elements of an array), without any modification, the string is not "cloned"; the memory reference to the string, which is basically a number, is copied between the two variables, and both of them point to the new value. So, the swapping being done is only rearranging these "pointers" actually contained in the array, not creating and deleting the actual strings in memory. That's a constant-time operation, so the dominant term for the Big-Oh notation remains linear.

Title: Problems Calculating Big-O Complexity

Body:
The first one looks linear to me; given an input array, a result array twice as large is created, and then every element of the input is traversed to produce two elements of the result. Assuming constant access time for arrays in Java (which is true) and constant array/list length checking (also true AFAIK), given N input elements, all N input elements are traversed, 3N input accesses are made, and 2N assignments are made. This is O(N) plain and simple; if this was the code from the test and you said O(N), you are right and your prof is wrong. The fact that there are multiple steps happening for each iteration of the loop is immaterial; it's not an O(NlogN) function just because each element is accessed three times and the list happens to have 1000 elements.

The second one also appears linear. Given an input collection, the loop traverses half of it, and swaps each of those elements with the "mirrored" element on the other half (basically reversing the collection). Again, neither the fact that 3 reads/writes are made to list elements, nor the fact that only half the items are traversed by the outer loop, makes this a logarithmically-based algorithm; it, like the first, is O(N)-complexity, provided that the collection is constant-time to access.

In fact, I cannot see any way that either of these would be O(logN). Both of them might be O(NlogN), if there's something you're not telling us; that the input collection which you are showing us as an array is actually a Map, using a red-black tree for its internal structure and thus providing log(N) access time. Then the complexity of both of these would be O(NlogN), because for each of the elements traversed by the loop, you spend some constant multiple of logN time reading or writing to elements of the collection.

However, if the problems are exactly as you have stated, your prof is wrong, you are right, and you should make a stink about it to him and to anyone above him that you can get to care, depending on how much of your grade this test represents.

EDIT FROM UPDATE: OK, now we see that the prof marked the wrong two questions wrong:

public static void mystery3(List<String> list) {
   for (int i = 0; i < list.size() – 1; i += 2) {
      String first = list.remove(i);
      list.add(i + 1, first);
   }
}

This one basically swaps each pair of elements; it does so by removing and then re-adding each element to a mutable List collection. Now, if it were a true swap, with a temp variable like you'd use with an array, it would indeed be linear. However, with a List, when you remove or add items in the middle of the collection, the List class automatically rearranges the existing items in the array that it uses behind the scenes to store the elements, by "shifting" each element above the removed element to the next lower index. A removal of element in index X from a collection of N elements will result in N-(X+1) shifts. Same thing in reverse when an element is inserted in between two existing elements; the existing elements to the right of the insertion point are each shifted one place further right to make room.

So, for N elements, it performs N/2 traversals, but N inserts/removals, each of which results in N-(X+1) shifts. As X will, at some point, have the value of every index in the list, this produces a triangular number of total value assignments, N(N-1)/2, which makes it O(N2) complexity. This is a very common breakdown for a quadratic-complexity algorithm; for each index, do something with each higher (or lower) index. Most of the quadratic sorts (e.g. SelectionSort, InsertionSort, BubbleSort) behave in this general way.

public static void mystery4(List<String> list) {
   for (int i = 0; i < list.size() – 1; i += 2) {
      String first = list.get(i);
      list.set(i, list.get(i + 1));
      list.set(i + 1, first);
   }
}

This one performs a similar pair-swapping operation on the elements of the List. However, this implementation is a true "temp swap" as mentioned above. The algorithm swaps pairs, but does so without changing the number of elements in the List; instead, a simple variable first is used to store the variable that is then overwritten in its current position in the List. So, for N/2 traversals, 2N reads/writes are performed, making this algorithm, which does exactly the same thing as the previous one, linear instead of quadratic.

Now, you said you marked this as linear. That's the right answer. Where it might not seem so (and this will be important elsewhere) is that strings in Java are immutable. Once created, they're never changed "in-place"; if the value of a string is modified, it results in the creation of a new String object in memory, and the old one, if nothing else references it, is orphaned for the garbage collector to deal with. So, the modification of a String is an operation linearly time-bound to the total number of characters in the string, because each of those characters must be copied from its current location into the proper new location in the new String. If that were happening, then this would be a linear operation of linear operations, producing a quadratic total time-complexity.

However, that's not happening in this algorithm. Java Strings are also "reference types", meaning that in an assignment of a string from one variable to another (including elements of an array), without any modification, the string is not "cloned"; the memory reference to the string, which is basically a number, is copied between the two variables, and both of them point to the new value. So, the swapping being done is only rearranging these "pointers" actually contained in the array, not creating and deleting the actual strings in memory. That's a constant-time operation, so the dominant term for the Big-Oh notation remains linear.


答: Try to enroll in an undergraduate level course in data structures and algorithms, it's always good to learn these concepts along side others.</p>

Title: How do I learn algorithms and data structures?

Body:
This is in continuation to my previous question where I asked is it necessary to learn algorithms and data structures. I feel yes it is.

Now I work in an environment where I won't ever get the chance to learn it by experimenting or practically or in any assignment. What is the right approach like the right books, right kind of problems, right kind of resources that I can go through to give six months or a year or two to learn algorithms and data structures?  And also mold my mind in a way that it can relate problems to data structures and algorithms.


问:
var args constructors/methods vs lists
In the long debate of using arrays vs lists in the public API of Java classes, I tend to prefer lists in most situations.
However, I also found convenient to use var arguments in many constructors and methods, which require declaring an argument of the method (the last one) as an array (implicitly adding "..." before the parameter name).

Since in many of these methods I do want to provide a programmer the possibility to either explicitly list the arguments (with var args) or use a pre-defined collection when invoking the method, I often end up defining a constructor or method with var arguments, and an overloaded version that accepts a list instead of the var args array. For example:

```<code>public void myMethod(X ...items) {
    myMethod(Arrays.asList(items));
}

private void myMethod(List<X> items) {
    ...
}
</code>```

I know that in theory I do not need to overload the method replacing the var args array with a list if I want the programmer to send a collection of objects. He could just send an array.

The reason I often do this is because most (if not all) of the methods in my API use lists instead of arrays, and it is a bit weird that for one or two methods requirying collection of objects, the programmer needs to work with arrays (in cases when the var args are not convenient).
So I provide an overloaded version working with list for consistency.

However, since this is a recurrent problem, I have the uncomfortable feeling of being writing boilerplate code too often. I would like to receive feedback if my motivation of keeping my interface consistent (accepting var arrays or lists, but not forcing the programmer to work with arrays if not really required) is valid enough to keep writing overloaded versions using lists for most of my methods requirying var arguments.

I would like to highlight that I know that for certain methods arrays could be more convenient than lists. My question concerns situations where the only motivation for declaring the last argument of the method as an array is because in certain scenarios using var arguments can be convinient.

UPDATE

Thanks for your feedback. My conclusions at the moment are the following:

Reduce the usage of var args as much as possible.

Continue adding an overloaded version of the method with var args, such as the array argument is replaced by a list (or an Iterable, as @Kevin pointed out), in cases where it can be useful to have the choice to invoke the method with either var args or with a collection.

Stop using Java as soon as possible :) (I already knew that one)

答:
You're overthinking the problem.  You want to use a list (array or some other iterable) for your arguments when it's likely the consumer of your function would already have things in a list.  You want to use variable arguments when you might want to call a function with a different number of arguments.

A classic example of when you should use varargs is C's printf().  Using varargs makes sense here because, in the general case, there's no reason to put a bunch of arbitrary values in a list just to print something.  A good example of where you'd probably want a list is a sum() where you're probably operating on a bunch of related values that would likely be stashed away together.

It's not something you need to be dogmatic about or have rules for.  Use some common sense and write code that people can follow & doesn't force you to jump through arbitrary hoops.

Title: var args constructors/methods vs lists


问:
Object-oriented design question
I am using a class through a dll to which I do not have direct control. So in effect, I am only a client of this class.

The class represents a form that can be printed, sent to clients and tracked in the system. I need to calculate two types of dates after which, if the form is received it is considered late.

Rather than simply calculate the late dates in the method where I am already handling the form, I want to extract the algorithm for calculating the late dates in a separate class as it is complicated and can be subject to change for administrative reasons.

Since I cannot modify the original class. I came up with these  possible solutions:

(For reference the code is in C# 4/.Net 4.)

A- Create a FormLateDateCalculator class that has methods to return a late date for a given form.

B- Create a FormLateDate class that takes a form in it's constructor and has a property for each type of late date.

C- Create two extension methods on the Form class that calculate the late dates.

While all three of these methods work (and I am sure there are others), I would like to know which is the best in regards to object-oriented design and why?

答:
Abstract it down first.

Look at the overall behavior before jumping into an implementation.

Forget the details and isolate the behavior - What are you actually trying to do?

If you think you are trying to determine if a form has arrived late, you are not abstracting it enough.  Ask yourself what the code needs to do to be able to identify and handle forms that arrive late?  The code needs to 1) identify if a form is late and 2) handle it.  In other words, you are trying to 1) evaluate a condition and 2) trigger functionality based on that evaluation.

This is the functionality that you should encapsulate for re-use - the first, but almost certainly not the last, implementation being the specific late date issue.

That would speak to me of the following things...
An interface that provides a specification for classes that can evaluate a condition and trigger a method when that condition is true.  I am sure there is a pattern for this even though I couldn't name it.
At least one implementation of that interface that checks for late dates and performs required processing.
A class which represents a list of these, I'll call them validators, which has a performValidations() method that takes the form as input and runs all the validators on it.

Some people will say that you should just code for the specific behavior being asked for, meaning forget the interface and just code the late date specific code in a method or class somewhere - I say that as soon as you do that, you will be asked to provide another thing just like it, or you will discover that there are already many other requirements that could be handled the same way.

Bottom line - identify and isolate the behaviors underlying the functionality you want to provide, and provide the desired functionality as a symptom of the operation of these behaviors.

Title: Object-oriented design question


问:
Print fixed width list sorted by column
I have a list of varying length where items is strings of varying length. I want to print them by (a mirrored N)/order by column.

Major points being:

Columns shall have fixed width == widest data in that column.

It shall be as compact as possible.

Number of columns is varying/induced by available width of canvas.

Order of items should not be rearranged.

(Item lists printed column wise on a horizontal order disgusts me.)

Optionally:

Distribution should optionally favour either lower left or upper right.

I currently use this in terminal by bash, C etc. but other uses is not hard to imagine.

Result of calculations should be:

columns

lines

width of each column

As, by this, one can fairly easy print the data in a fixed with column table.

Main question: Is there is some nifty way to do this. (I'm inspired by Knuth's Computer musings.)

My current approach is rather straight forward. Hard to specify the question without some gory details so here we go:

Data Examples

E.g. (by index of string array):

```<code>0  4  8 12   or    0  4  8 12     or   0  3  6  9 12 15
1  5  9 13         1  5  9 13          1  4  7 10 13
2  6 10 14         2  6 10             2  5  8 11 14
3  7 11 15         3  7 11

favouring lower left     favouring upper right
0  4  8 12               0  4  8 11
1  5  9 13               1  5  9 12
2  6 10                  2  6 10 13
3  7 11                  3  7
</code>```

E.g. (by data - actual output):

```<code>0) Item number 00000 4) Item Number 04        8) Item Number 008   12) Item Number 00012
1) Item Number 00001 5) Item Number 5         9) Item Number 00009 13) Item Number 0013
2) Item Number 02    6) Item Number 00000006 10) Item Number 10
3) Item Number 003   7) Item Number 7        11) Item Number 11
</code>```

Current implementation

As of now I do this by (approximately) e.g. in bash:

Adding the length of each item to array lens and track longest item.

Add width for number + 1 for ) + 1 for space to longest item.

Calculate maximum columns given that width.

Re-calculating width of item number (The one before ')' in the print.) for each column.

Calculating actual longest width for items in each column.

Re-calculating:

```<code> while `lines` > 1 ; do

      * Available width = Canvas width - total print width
      * Test:
            Find longest item in last column as if columns was increased by 1.
      * If longest_in_last_column_test < available width
             increase columns by 1.
             recalculate all column widths.
        Else
             break
        End If
 done
</code>```

Print list.

Thoughts

Cant' help but wonder if there is some way to calculate this by other means. E.g. by using matrix mathematics, - or perhaps some nice algorithm out there.

Perhaps hard in bash, but in C by pointers to structs or object related languages.

Exempli gratia:

```<code>struct item {
    int len;
    char *val;
}

struct item items = {{5, "Hello"}, {3, "You"}, ...}
</code>```

Which would give a matrix of typically

```<code># index:length
0:5 1:2 2:1 3:3 4:5
5:2 6:6 7:9 8:1 9:6
</code>```

Then by having the restraint of sum of each row being <= available width, e.g. 25, rearrange matrix.

```<code>longest: 5 5 9 6 => sum 25
--------------------------
         5 3 6 1 => sum 15
         5 5 9 6 => sum 25
         1 2 1   => sum  4
</code>```

答:
Here's what I've come up with:

```<code>struct Item
{
    uint prefix_length; // for the prefix numbers; e.g. "100) " would be length 5
    uint item_length;   // length of the item
    char *item;         // string contents
}

struct Column
{
    uint starting_index;
    uint num_items;
    uint max_prefix_length;
    uint max_item_length;
}

/*
</code>```

Initialization

Make a list of Items and initialize their prefix_lengths based on where they are in the list and w/e other characters the prefix will have (i.e. number length + paren + buffer space).

Then make a (dynamic) list of Columns, the same length as the number of Items, with the starting_index of each column set to its index in the list (so that it corresponds to an Item) and num_items set to 1. The max_prefix_length and max_item_length should be initialized to the corresponding values of the Item to which the Column is pointing.

```<code>Items: [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [...]
         ^     ^     ^     ^     ^     ^     ^     ^
Cols:    0     1     2     3     4     5     6    ...
</code>```

Main Loop

The first thing to do in the main loop would be to iterate across the Columns, incrementing num_items by 1 and incrementing starting_index by 0 for the first Column, by 1 for the second Column, by 2 for the third Column, etc.

After the first iteration this will give you:

```<code>Items: [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [...]
         ^     ^     ^     ^     ^     ^     ^     ^
Cols:    +--0--+     +--1--+     +--2--+     +--3--+  ...
</code>```

The second iteration would get:

```<code>Items: [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [...]
         ^           ^     ^           ^     ^
Cols:    +-----0-----+     +-----1-----+     +-----2-...
</code>```

Note that you'll have to remove any Columns whose starting_index becomes larger than the number of items in the Items list.

After incrementing these values, set the max_prefix_length of each Column to the corresponding value of the last Item it points to. For the max_item_length, sadly, you'll have to iterate over the Items the Column spans to find the max item_length.

The termination condition of the main loop will be to see whether the sum of the max_prefix_length + max_item_length of all the columns (plus whatever buffer space between the columns you want) is less than the total width you have. (Don't forget the edge condition of an Item that has a length greater than the total width.) EDIT: Sadly this termination condition would require you to keep the result of the last iteration around, since the loop would only terminate after an invalid result was found.

If there were some way of doing a walking maximum for the items spanned by each column, that would be awesome (but sadly I can't think of one at the moment).

Of course, after writing all this out I see that it's basically coming at this from the opposite direction as your algorithm; maybe it'll give you some ideas though.

Title: Print fixed width list sorted by column

Body:
Here's what I've come up with:

struct Item
{
    uint prefix_length; // for the prefix numbers; e.g. "100) " would be length 5
    uint item_length;   // length of the item
    char *item;         // string contents
}

struct Column
{
    uint starting_index;
    uint num_items;
    uint max_prefix_length;
    uint max_item_length;
}

/*

Initialization

Make a list of Items and initialize their prefix_lengths based on where they are in the list and w/e other characters the prefix will have (i.e. number length + paren + buffer space).

Then make a (dynamic) list of Columns, the same length as the number of Items, with the starting_index of each column set to its index in the list (so that it corresponds to an Item) and num_items set to 1. The max_prefix_length and max_item_length should be initialized to the corresponding values of the Item to which the Column is pointing.

Items: [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [...]
         ^     ^     ^     ^     ^     ^     ^     ^
Cols:    0     1     2     3     4     5     6    ...

Main Loop

The first thing to do in the main loop would be to iterate across the Columns, incrementing num_items by 1 and incrementing starting_index by 0 for the first Column, by 1 for the second Column, by 2 for the third Column, etc.

After the first iteration this will give you:

Items: [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [...]
         ^     ^     ^     ^     ^     ^     ^     ^
Cols:    +--0--+     +--1--+     +--2--+     +--3--+  ...

The second iteration would get:

Items: [ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [...]
         ^           ^     ^           ^     ^
Cols:    +-----0-----+     +-----1-----+     +-----2-...

Note that you'll have to remove any Columns whose starting_index becomes larger than the number of items in the Items list.

After incrementing these values, set the max_prefix_length of each Column to the corresponding value of the last Item it points to. For the max_item_length, sadly, you'll have to iterate over the Items the Column spans to find the max item_length.

The termination condition of the main loop will be to see whether the sum of the max_prefix_length + max_item_length of all the columns (plus whatever buffer space between the columns you want) is less than the total width you have. (Don't forget the edge condition of an Item that has a length greater than the total width.) EDIT: Sadly this termination condition would require you to keep the result of the last iteration around, since the loop would only terminate after an invalid result was found.

If there were some way of doing a walking maximum for the items spanned by each column, that would be awesome (but sadly I can't think of one at the moment).

Of course, after writing all this out I see that it's basically coming at this from the opposite direction as your algorithm; maybe it'll give you some ideas though.


问:
Event Driven Programming: A sequence of unfortunate events
I have a very basic game loop whose primary purpose is to check for updates & changes to a list.

I have contemplated using event driven programming to replace the game loop/list idea with an ObservableCollection, however I just have this big cloud of doubt on event driven programming.  I'm posing these questions to those with experience with event driven programming:

What are good ways to test & build an event driven programming design?

That is, how will I know that I cannot run into "a sequence of unfortunate events"?  I want to avoid the events I didn't plan for.

Are there unit tests schemes to test event driven programming?

Observable collections are found at:

http://msdn.microsoft.com/en-us/library/ms668604.aspx

答:
I used XSLT as a general purpose programming language for 6 years at work.  XSLT is not exactly "event" driven, but it is input-driven - meaning that there is no pre-defined order of execution or limited number of paths that the execution of the code can take.  Rather, each node in the input data tree triggers some code to be executed.  It's totally data driven, which I imagine is similar to your event-driven model.

Anyone who has spent a few years writing software for a large organization knows that there is no end to the variety of data that gets into big systems.  Every time you account for one condition, a new one pops up that no-one ever imagined.  When your input data defines the order of execution of your code, then the paths you need to test are equal to the total number of data conditions that your code can be exposed to - a number which grows daily.  The people using XSLT to write batch data crunching processes would be paged repeatedly at home, at night, pretty much every night as new data conditions were "discovered" by the program.

When you let your data drive your software, you will often run into a "sequence of unfortunate events."  Fault tolerance is a big deal.  Emergent behaviors rule the day.  Limits are your friends.  Obviously for a game universe to feel real, the fewer limits, the better.  You must choose your limits very wisely.  After all, a game is art, and an important part of any artistic statement is its limits.

Speaking of art, John Cage wrote a piece of music, "Four minutes and thirty three seconds" where the performer sits, making no sound, for that length of time.  The point of this artistic composition, as far as I'm concerned, is not the picture, but the frame.  Everything has limits.  You are making a game about one thing, not another thing.  It is one game, not another game.  The better you can choose limits, and the more appropriate those limits are for your art/game/project, the easier it's going to be, and the better the experience will be for your users/gamers.

All software (like all music and art) has limits.  Choosing those limits wisely may be the single most determining factor of the success of any software design.  But with event- or data-driven programming, this is perhaps even more critical, if such a thing is possible, because every bit of non-essential flexibility that you allow in such a system will punish your development team with bugs and unimaginably complicated testing.  First make as many limits on your event-driven system as possible, and only remove or extend a limit when doing so has a major, positive effect on the system as a whole.

Unit testing (generally black-box testing) usually takes the form of, "given certain inputs, does the software being tested return the expected outputs."  For a very versatile event-driven system, you need a lot of variety in those inputs.  Maybe you could capture all the interesting kinds of input data that you've seen in your game so far and make tests from those.  Maybe you can add a new test whenever you encounter a new and interesting data condition.  But with a sufficiently complicated system, there is no way to test every data condition, only the currently known conditions.

Maybe it would be good to build that kind of sanity testing (bounds-checking, things null or not null, no exceptions, etc.) into some sort of logging utility that would alert you when your method sees something new in the wild?

Hopefully a statistician will answer your question too and tell you how to cover a high percentage of the possible data conditions in a meaningful way.  But until then, choosing the limits of your data- or event-driven software wisely is the only way I know to control the complexity of a meaningful set of unit tests.


答:
The purpose of code reviews is to catch problems that testing can't catch, like maintainability problems and corner cases.  I would argue that in many ways junior programmers are better suited for that purpose:

They have more time available in general.

They are more likely to take it slowly, line by line, out of necessity to understand the code.

When you talk about code being maintainable, that means by everyone in the company, not just your top programmers.  That means your junior programmers must be able to understand the code in order to declare it maintainable.

They are often less likely to make bad assumptions, trusting that something works the way they assume it should work.

Their education in a programming language is more recent, and less likely to be muddled together with years of experience in another language.  For example, a senior might accidentally use a habit he picked up from C++ that compiles but works subtly different in Java.  Juniors pick up on those sorts of errors more easily.

Code reviewers only need to identify problems, not necessarily propose a better solution.  They will often make comments along the lines of, "I can't really figure out how to do it better, but this part is really confusing because of all the repetition."  A more experienced programmer can then easily make the improvements even though they may not have noticed the problem at first.

That's not to say there aren't other ways in which senior programmers are better suited for doing reviews, but my point is you are doing a disservice if you aren't taking full advantage of the diversity of your team.

Title: Should Junior Programmers be involved as code reviewers in the projects of Senior Programmers?

Body:
One of my team members, a junior programmer, has impressive programming skills for his level of experience.

And during code reviews, I believe in emphasizing learning, not pointing out mistakes.

But should junior programmers be involved in code reviews for more senior programmers? Or should code reviews be attended only by programmers with corresponding experience?


答: If you aren't able to take a course on this, I'd recommend The Algorithm Design Manual.  There's a free PDF here, but it's worth getting the actual book if you plan on programming professionally.</p>


答:
I will leave aside the wisdom (or not) of this particuar design for a game engine, I will address the core concern about the testability of event-driven designs.

When you state

I want to avoid the events I didn't plan for.

I presume you mean a sequence that you did not plan for, like Create/Delete/Update instead of the expected Create/Update/Delete, where the former might try and update a non-existant object and therefore crash or otherwise fail.

The entire nature of event-driven programming has to actually presume a near-random order of events, and so effectively your pre- and post- conditions become very important.  Since you cannot fully qualify the order of events, you need to be robust against accidental ordering.  So long as your Delete leaves no stray pointers, then a delayed Update should unambiguously fail, or at least have some well-defined behavior.

As far as unit-testing goes, most of the common suggestions would still apply.  Generate test cases for various boundary conditions, as well as common cases to try and achieve appropriate coverage and interaction testing.

Perhaps in your game, I should be able to PickUp an item, which would add it to my inventory.  If I attempt to PickUp an item, which was just destroyed for some reason (perhaps an ogre stepped on it), I should not somehow get an undamaged object due to a race condition.  Either I got the object before it was crushed, or it is now gone, but nothing inbetween.  If each event is atomic with respect to game state, then you won't get a partial object someplace it should not be.

Good Luck

Title: Event Driven Programming: A sequence of unfortunate events

Body:
I have a very basic game loop whose primary purpose is to check for updates & changes to a list.

I have contemplated using event driven programming to replace the game loop/list idea with an ObservableCollection, however I just have this big cloud of doubt on event driven programming.  I'm posing these questions to those with experience with event driven programming:

What are good ways to test & build an event driven programming design?

That is, how will I know that I cannot run into "a sequence of unfortunate events"?  I want to avoid the events I didn't plan for.

Are there unit tests schemes to test event driven programming?

Observable collections are found at:

http://msdn.microsoft.com/en-us/library/ms668604.aspx


答:
Absolutely, junior engineers should review senior engineers' code, at least some of the time.

In my experience, it's pretty rare that the reviewer in a one-on-one code review actually sees an error that the original coder misses, whether the reviewer is senior or junior; the reviewer doesn't even have to be human. It's very common, on the other hand, that the original coder recognizes a mistake while trying to explain the code, and the more junior the reviewer, the more likely this is, because of the required depth of explanation.

Some more often overlooked benefits of code review, in my opinion, that are possibly more important in the long run than catching errors:

Sharing knowledge of what's actually going in the code base - "Wait, I think Bill had a class that does X, we don't need to write a new one."

Sharing knowledge of good techniques and programming style.

In both these aspects, a junior reviewer tends to benefit more than a senior one.


问:
How to avoid "managers" in my code
I'm currently re-designing my Entity System, for C++, and I have a lot of Managers. In my design, I have these classes, in order to tie my library together. I've heard a lot of bad things when it comes to "manager" classes, perhaps I'm not naming my classes appropriately. However, I have no idea what else to name them.

Most of the managers, in my library, are composed of these classes (although it does vary a little bit):

Container - a container for objects in the manager

Attributes - attributes for the objects in the manager

In my new design for my library, I have these specific classes, in order to tie my library together.

ComponentManager - manages components in the Entity System

ComponentContainer

ComponentAttributes

Scene*  - a reference to a Scene (see below)

SystemManager - manages systems in the Entity System

SystemContainer

Scene*  - a reference to a Scene (see below)

EntityManager - manages entities in the Entity System

EntityPool - a pool of entities

EntityAttributes - attributes of an entity (this will only be accessible to ComponentContainer and System classes)

Scene*  - a reference to a Scene (see below)

Scene - ties all the managers together

ComponentManager

SystemManager

EntityManager

I was thinking of just putting all the container/pools in the Scene class itself.

i.e.

Instead of this:

```<code>Scene scene; // create a Scene

// NOTE:
// I technically could wrap this line in a createEntity() call in the Scene class
Entity entity = scene.getEntityManager().getPool().create();
</code>```

It would be this:

```<code>Scene scene; // create a Scene

Entity entity = scene.getEntityPool().create();
</code>```

But, I am unsure. If I were to do the latter, that would mean I would have a lot of objects and methods declared inside my Scene class.

NOTES:

An entity system is simply a design that is used for games. It is composed of 3 major parts: components, entities, and systems. The components are simply data, which may be "added" to the entities, in order for the entities to be distinctive. An entity is represented by an integer. Systems contain the logic for an entity, with specific components.

The reason I'm changing my design for my library, is because I think it can be changed quite a lot, I don't like the feel/flow to it, at the moment.

答:
Well, I had a read through some of the code you linked to, and your post, and my honest summary is that the majority of it is basically completely worthless. Sorry. I mean, you have all of this code, but you haven't achieved anything. At all. I'm going to have to go into some depth here, so bear with me.

Let's start with ObjectFactory. Firstly, function pointers. These are stateless, the only useful stateless way to create an object is new and you don't need a factory for that. Statefully creating an object is what's useful and function pointers are not useful for this task. And secondly, every object needs to know how to destroy itself, not having to find that exact creating instance to destroy it. And in addition, you must return a smart pointer, not a raw pointer, for the exception and resource safety of your user. Your whole ClassRegistryData class is just std::function<std::unique_ptr<Base, std::function<void(Base*)>>()>, but with the aforementioned holes. It does not need to exist at all.

Then we have AllocatorFunctor- there are already Standard allocator interfaces provided- Not to mention that they're just wrappers on delete obj; and return new T;- which again, is already provided, and they won't interact with any stateful or custom memory allocators which exist.

And ClassRegistry is simply std::map<std::string, std::function<std::unique_ptr<Base, std::function<void(Base*)>>()>> but you wrote a class for it instead of using the existing functionality. It's the same, but completely needlessly global mutable state with a bunch of crappy macros.

What I'm saying here is that you've created some classes where you could replace the entire thing with functionality built from Standard classes, and then made them even worse by making them global mutable state and involving a bunch of macros, which is the worst thing you could possibly do.

Then we have Identifiable. It's a lot of the same story here- std::type_info already performs the job of identifying each type as a run-time value, and it doesn't require excessive boilerplate on the part of the user.

```<code>    template<typename T, typename Y>
    bool isSameType(const X& x, const Y& y) { return typeid(x) == typeid(y); }
    template <class Type, class T>
    bool isType(const T& obj)
    {
            return dynamic_cast<const Type*>(std::addressof(obj));
    }
</code>```

Problem solved, but without any of the preceeding two hundred lines of macros and whatnot. This also marks your IdentifiableArray as nothing but std::vector but you have to use reference-counting even if unique ownership or non-ownership would be better.

Oh, and did I mention that Types contains a bunch of absolutely useless typedefs? You gain literally no advantage whatsoever over using the raw types directly, and lose a good chunk of readability.

Next up is ComponentContainer. You can't choose the ownership, you can't have separate containers for derived classes of various components, you can't use your own lifetime semantics. Delete without remorse.

Now, the ComponentFilter might actually be worth a little, if you refactored it a lot. Something like

```<code>class ComponentFilter {
    std::unordered_map<std::type_info, unsigned> types;
public:
    template<typename T> void SetTypeRequirement(unsigned count = 1) {
        types[typeid(T)] = count;
    }
    void clear() { types.clear(); }
    template<typename Iterator> bool matches(Iterator begin, Iterator end) {
        std::for_each(begin, end, [this](const std::iterator_traits<Iterator>::value_type& t) {
            types[typeid(t)]--;
        });
        return types.empty();
    }
};
</code>```

This doesn't deal with classes derived from the ones you're trying to deal with, but neither did yours.

The rest of this is pretty much the same story. There is nothing here that could not be done much better without the use of your library.

How would you avoid managers in this code? Delete basically all of it.

ContentLicense: CC BY-SA 4.0

Title: How to avoid "managers" in my code

Body:
Well, I had a read through some of the code you linked to, and your post, and my honest summary is that the majority of it is basically completely worthless. Sorry. I mean, you have all of this code, but you haven't achieved anything. At all. I'm going to have to go into some depth here, so bear with me.

Let's start with ObjectFactory. Firstly, function pointers. These are stateless, the only useful stateless way to create an object is new and you don't need a factory for that. Statefully creating an object is what's useful and function pointers are not useful for this task. And secondly, every object needs to know how to destroy itself, not having to find that exact creating instance to destroy it. And in addition, you must return a smart pointer, not a raw pointer, for the exception and resource safety of your user. Your whole ClassRegistryData class is just std::function<std::unique_ptr<Base, std::function<void(Base*)>>()>, but with the aforementioned holes. It does not need to exist at all.

Then we have AllocatorFunctor- there are already Standard allocator interfaces provided- Not to mention that they're just wrappers on delete obj; and return new T;- which again, is already provided, and they won't interact with any stateful or custom memory allocators which exist.

And ClassRegistry is simply std::map<std::string, std::function<std::unique_ptr<Base, std::function<void(Base*)>>()>> but you wrote a class for it instead of using the existing functionality. It's the same, but completely needlessly global mutable state with a bunch of crappy macros.

What I'm saying here is that you've created some classes where you could replace the entire thing with functionality built from Standard classes, and then made them even worse by making them global mutable state and involving a bunch of macros, which is the worst thing you could possibly do.

Then we have Identifiable. It's a lot of the same story here- std::type_info already performs the job of identifying each type as a run-time value, and it doesn't require excessive boilerplate on the part of the user.

    template<typename T, typename Y>
    bool isSameType(const X& x, const Y& y) { return typeid(x) == typeid(y); }
    template <class Type, class T>
    bool isType(const T& obj)
    {
            return dynamic_cast<const Type*>(std::addressof(obj));
    }

Problem solved, but without any of the preceeding two hundred lines of macros and whatnot. This also marks your IdentifiableArray as nothing but std::vector but you have to use reference-counting even if unique ownership or non-ownership would be better.

Oh, and did I mention that Types contains a bunch of absolutely useless typedefs? You gain literally no advantage whatsoever over using the raw types directly, and lose a good chunk of readability.

Next up is ComponentContainer. You can't choose the ownership, you can't have separate containers for derived classes of various components, you can't use your own lifetime semantics. Delete without remorse.

Now, the ComponentFilter might actually be worth a little, if you refactored it a lot. Something like

class ComponentFilter {
    std::unordered_map<std::type_info, unsigned> types;
public:
    template<typename T> void SetTypeRequirement(unsigned count = 1) {
        types[typeid(T)] = count;
    }
    void clear() { types.clear(); }
    template<typename Iterator> bool matches(Iterator begin, Iterator end) {
        std::for_each(begin, end, [this](const std::iterator_traits<Iterator>::value_type& t) {
            types[typeid(t)]--;
        });
        return types.empty();
    }
};

This doesn't deal with classes derived from the ones you're trying to deal with, but neither did yours.

The rest of this is pretty much the same story. There is nothing here that could not be done much better without the use of your library.

How would you avoid managers in this code? Delete basically all of it.


答:
Juniors will often be asked to maintain the code, it is critical that they can understand it.

At times juniors are the only people available to review the code of the senior developers. Should code wait to go to QA (we don't push anything out of dev without a code review and I am assuming this type of code review as well) because the senior's boss is on vacation?

I have also specifically asked juniors to code review something when I knew they would be doing something similar for a different client shortly or if I knew they had worked on something else that was similar or that they had a particular skill set.

If the code is fairly straightforward, I often get a junior person to do the review. Why waste the seniors person's time if the junior person is quite capable of doing the job? If juniors feel intimidated by reviewing senior's code, get them to look at the easier pieces initially. After all you cant get past being junior until you stop feeling intimidated.

I have often found that if I have to explain the code to a junior person who doesn't understand it, I will see an error I made (usually in an assumption) and that no experienced code reviewer would have caught because the code does run but doesn't do exactly what was intended. So just the act of explaining things will often help the developer see an issue without the code reviewer finding it. Since more experienced people are not often taken through the code step by step, these types of things are found more easily when a junior does the review.

I find that having junior involved in reviews has several good effects. First it makes them more confident when they can understand a senior person's code. It makes them even  more confident when they can find a bug in that code.

It exposes them to thinking processes outside their own and lets them see other ways of handling things. Even as a senior person, this has happened to me - seeing a different way of solving a problem can be an eye opener to new possibilities.

It helps them learn to read other people's code and it gives them a chance to ask what the code is doing while it is still fresh in the minds of the author. That's a lot better than having to maintain the thing six months later when the author is long gone or is busy on another project and doesn't have time for questions.

It's good for the seniors because the questions both expose potential areas where the junior is weak and needs mentoring (so they can take more responsibility and give the seniors more time to do other types of tasks) or areas where the code is simply not clear to anyone except the author (which means it might not even be clear to the author a year from now when it needs to be changed). It also helps seniors realize that the juniors might be smarter than they have been giving them credit for being. It helps keep everyone on a professional footing. After all if you exclude juniors then you are clearly implying that you don't think they are capable of understanding the code which is psychologically unfortunate.

Juniors reviewing seniors code can generate more professional respect in your organization. Seniors may realize they have been underestimating the juniors and juniors may realize that the seniors do know more than they gave them credit for.
Juniors sometimes think they have greater skills than they have. Being exposed to code they can't write is good for these people because they start to realize they have much more to learn. It also will spur the best of them on to get the skills. In school sometimes the B students don't understand why they didn't get an A until someone shows them a sample of the A level of work. Same with juniors to seniors in code review.


答:
The problem with Manager classes is that a manager can do anything. You can't read the class name and know what the class does. EntityManager....I know it does something with Entities but who knows what.  SystemManager...yep, it manages the system. That's very helpful.

My guess is that your manager classes probably do a lot of things. I'll bet if you were to segment those things into closely related functional pieces, then you'll probably be able to come up with class names related to the functional pieces that anybody can tell what they do simply by looking at the class name. This will make for a far easier to maintain and understand design.

Title: How to avoid "managers" in my code

Body:
I'm currently re-designing my Entity System, for C++, and I have a lot of Managers. In my design, I have these classes, in order to tie my library together. I've heard a lot of bad things when it comes to "manager" classes, perhaps I'm not naming my classes appropriately. However, I have no idea what else to name them.

Most of the managers, in my library, are composed of these classes (although it does vary a little bit):

Container - a container for objects in the manager

Attributes - attributes for the objects in the manager

In my new design for my library, I have these specific classes, in order to tie my library together.

ComponentManager - manages components in the Entity System

ComponentContainer

ComponentAttributes

Scene*  - a reference to a Scene (see below)

SystemManager - manages systems in the Entity System

SystemContainer

Scene*  - a reference to a Scene (see below)

EntityManager - manages entities in the Entity System

EntityPool - a pool of entities

EntityAttributes - attributes of an entity (this will only be accessible to ComponentContainer and System classes)

Scene*  - a reference to a Scene (see below)

Scene - ties all the managers together

ComponentManager

SystemManager

EntityManager

I was thinking of just putting all the container/pools in the Scene class itself.

i.e.

Instead of this:

```<code>Scene scene; // create a Scene

// NOTE:
// I technically could wrap this line in a createEntity() call in the Scene class
Entity entity = scene.getEntityManager().getPool().create();
</code>```

It would be this:

```<code>Scene scene; // create a Scene

Entity entity = scene.getEntityPool().create();
</code>```

But, I am unsure. If I were to do the latter, that would mean I would have a lot of objects and methods declared inside my Scene class.

NOTES:

An entity system is simply a design that is used for games. It is composed of 3 major parts: components, entities, and systems. The components are simply data, which may be "added" to the entities, in order for the entities to be distinctive. An entity is represented by an integer. Systems contain the logic for an entity, with specific components.

The reason I'm changing my design for my library, is because I think it can be changed quite a lot, I don't like the feel/flow to it, at the moment.


问:
Agile Development & Interaction with Developers
I have read in few blogs that as part of agile development , the product owner closely interact with developers to state their requirements and come up with a solution. However in case of a large project (in terms of number of applications involved) involving multiple systems , is this possible? Shouldn't the project have a business analyst / solution designer in order to capture the requirements properly and come up with a solution which states how the the requirement could be fulfilled and which systems must do what activity?</p>

答:
"Product Owner" is a term from Scrum, which is only one form of Agile.  Scrum is really designed around the notion of small teams of seven plus or minus two, who do all the development and testing of the project solution.  The Team would work with a Product Owner, who owns what goes into the project and what does not.

To scale Scrum, organizations have formed what is known as a Scrum of Scrums where there are numerous teams, each the size mentioned above, and each with a Product Owner.  A representative of each team (or possibly the Product Owner) then participates as a member of a sort of meta-team, which coordinates what the individual teams are doing.  This team would have its own Product Owner, who owns the larger solution.  In a huge project, there may be another tier (a Scrum of Scrums of Scrums), but that's really risky.

You could follow this model, giving each system a team and a PO, and then coordinating between the POs.  Or you could try a different Agile approach, such a Kanban or Crystal.


问:
Best practice to sync long paths to filesystems where path length is limited?
I wrote a sync tool to synchronize folders/files from Alfresco to Windows.

PROBLEM:

In Alfresco, /files/can/have/very/very/very/long/filepaths/like/this.txt

The Windows API prevents me from creating a path with more than 260 characters.

In addition to telling the user there is a problem, what is the best practice in such a case?

Shorten the file's name?

Skip the file?

Create a sort of "folder's carriage return", a special folder from which the path can continue?

Something else?

Files need to be 100% usable by other applications. If necessary directory names can be modified, I can keep a mapping.

答: If you really do need to shrink the path down (dubious - see other answers) what about some kind of hash?  If you need to preserve the bi-directional mapping mapping of file names you could store that somewhere else, such as a database.  Not super convenient but if you must shorten the file names it's just not going to be as convenient as you would like.</p>


答:
DeadMG is spot on on the specifics of your code but I feel like it misses a clarification. Also I don't agree with some of his recommendation that don't hold in some specific contexts like most high performance-videogame development for example. But he's globally right that most of your code is not useful right now.

As Dunk says, Manager classes are called like this because they "manage" things. "manage" is like "data" or "do", it's an abstract word that can contain almost anything.

I was mostly in the same place than you around 7 years ago, and I started to think that there was something wrong in my way of thinking because it was so much efforts to code to do nothing yet.

What I changed to fix this is to change the vocabulary I use in code. I totally avoid generic words (unless it's generic code, but it's rare when you're not making generic libraries). I avoid to name any type"Manager" or "object".

The impact is direct in code: it forces you to find the right word corresponding to the real responsibility of your type. If you feel like the type does several things (keep an index of Books, keep them alive, create/destroy books) then you need different types that each will have one responsibility, then you combine them in the code that uses them. Sometime I need a factory, sometime not. Sometime I need a registry, so I setup one (using standard containers and smart pointers). Sometime I need a system that is composed of several different sub system so I separate everything as much as I can so that each part do something useful.

Never name a type "manager" and make sure all your type have a single unique role is my recommendation. It might be hard to find names sometime, but it's one of the hardest thing to do in programming generally

Title: How to avoid "managers" in my code