答:
I think your approach is just equivalent to modifying the ExistingClass.  If you inline the ExistingClassExtension inside the ExistingClass, you will see you have declared an inner class, which is accessible through a method of the outer class.  If you further inline the inner class' methods and public members (which makes no difference to the callers of this code, except that they save one call to getExtension), you will notice that you have in fact plainly added some new methods underneath the ExistingClass.

Currently you have

```<code>class ExistingClass {
    private ExistingClassExtension extension = new ExistingClassExtension();
    public ExistingClassExtension getExtension() {return extension;}
}

class ExistingClassExtension {
    public boolean extendingMethod() { return false; }
}
</code>```

Inline the class

```<code>class ExistingClass {
    class ExistingClassExtension {
        // ... extendingMethod ...
    }
    public ExistingClassExtension getExtension() {return new ExistingClassExtension();}
}
</code>```

Inline the method

```<code>class ExistingClass {
    public boolean extendingMethod() {
        // ... extendingMethod ...
    }
}
</code>```

I misinterpreted "containment" for "composition" and expected to find a design like this:

```<code>class ExistingClass {
    boolean existingMethod() { return true; }
}

class ExtendingClass {
    private ExistingClass instance = new ExistingClass();
    boolean existingMethod() { return instance.existingMethod();}
    boolean extendingMethod() { return false;}
}
</code>```

while the inheritance option would just declare:

```<code>class ExtendingClass extends ExistingClass {
    boolean extendingMethod() { return false; }
}
</code>```

The criterion to decide whether to compose or inherit was summarized by Scott Myers in "Effective C++" as "Make sure public inheritance models 'is a' relationships".

Without knowing what both classes do or represent, it is impossible to decide whether one 'is a' subtype of the other, but let me remark that in "Effective Java", Joshua Bloch recommends to prefer composition over inheritance in most situations, since inheritance provides your new class with an interface that may be too large, or out of its control.  This may lead to subtle bugs, or broken builds in the future, when one of those minor fixes to the legacy code alters one of the private methods your newMethod1 relies upon.

I would suggest that you consider replacing this "containment" strategy with an actual composition of the legacy classes within new classes.  You will get all the benefits you list in your question, plus the added benefit that you are not inheriting an interface that may not be what you thought, or may change underneath your feet.

Title: Inheritance vs containment while extending a large legacy project

Body:
I have got a legacy Java project with a lot of code. The code uses MVC pattern and is well structured and well written. It also has a lot of unit tests and it is still actively maintained (bug fixing, minor features adding). Therefore I want to preserve the original structure and code style as much as possible.

I aim to inject a new behavior into an existing class. Like a Duck that was trained to jump. Then I ask all my Ducks to jump. Those who can - jump. Those who cannot do nothing which is perfectly OK with me.

The new feature I am going to add is a conceptual one, so I have to make my changes all over the code. In order to minimize changes I decided not to extend existing classes but to use containment:

```<code>class ExistingClass
{
   // .... existing code

   //  my code adding new functionality
   private ExistingClassExtension extension = new ExistingClassExtension();
   public ExistingClassExtension getExtension() {return extension;}
}

...
// somewhere in code
ExistingClass instance = new ExistingClass();

...
// when I need a new functionality
instance.getExtension().newMethod1();
</code>```

All functionality that I am adding is inside a new ExistingClassExtension class.
Actually I am adding only these 2 lines to each class that needs to be extended.

By doing so I also do not need to instantiate new, extended classes all over the code and I may use existing tests to make sure there is no regression.

However my colleagues argue that in this situation doing so isn't a proper OOP approach, and I need to inherit from ExistingClass in order to add a new functionality.

What do you think? I am aware of numerous inheritance/containment questions here, but I think my question is different.

EDIT:
Most of people replying to my question presume that a containment relationship looks like that:

```<code>class NewClass
{
   OldClass instanceOfOldClass;
   void oldFunctionality() { instanceOfOldClass.oldFunctionality();}

   void newFunctionality() { // new code here }
}
</code>```

But isn't this a kind of a containment relationship too?

```<code>class OldClass
{
   void OldFunctionality();
   NewClass instanceOfNewClass;

   void NewFunctionality {instanceOfNewClass.NewFunctionality();}
}
</code>```

Body:
I think your approach is just equivalent to modifying the ExistingClass.  If you inline the ExistingClassExtension inside the ExistingClass, you will see you have declared an inner class, which is accessible through a method of the outer class.  If you further inline the inner class' methods and public members (which makes no difference to the callers of this code, except that they save one call to getExtension), you will notice that you have in fact plainly added some new methods underneath the ExistingClass.

Currently you have

class ExistingClass {
    private ExistingClassExtension extension = new ExistingClassExtension();
    public ExistingClassExtension getExtension() {return extension;}
}

class ExistingClassExtension {
    public boolean extendingMethod() { return false; }
}

Inline the class

class ExistingClass {
    class ExistingClassExtension {
        // ... extendingMethod ...
    }
    public ExistingClassExtension getExtension() {return new ExistingClassExtension();}
}

Inline the method

class ExistingClass {
    public boolean extendingMethod() {
        // ... extendingMethod ...
    }
}

I misinterpreted "containment" for "composition" and expected to find a design like this:

class ExistingClass {
    boolean existingMethod() { return true; }
}

class ExtendingClass {
    private ExistingClass instance = new ExistingClass();
    boolean existingMethod() { return instance.existingMethod();}
    boolean extendingMethod() { return false;}
}

while the inheritance option would just declare:

class ExtendingClass extends ExistingClass {
    boolean extendingMethod() { return false; }
}

The criterion to decide whether to compose or inherit was summarized by Scott Myers in "Effective C++" as "Make sure public inheritance models 'is a' relationships".

Without knowing what both classes do or represent, it is impossible to decide whether one 'is a' subtype of the other, but let me remark that in "Effective Java", Joshua Bloch recommends to prefer composition over inheritance in most situations, since inheritance provides your new class with an interface that may be too large, or out of its control.  This may lead to subtle bugs, or broken builds in the future, when one of those minor fixes to the legacy code alters one of the private methods your newMethod1 relies upon.

I would suggest that you consider replacing this "containment" strategy with an actual composition of the legacy classes within new classes.  You will get all the benefits you list in your question, plus the added benefit that you are not inheriting an interface that may not be what you thought, or may change underneath your feet.


问:
Where to store global enterprise properties?
I'm faced with a crowd of java applications, which need different global enterprise wide properties for operation, for example: hostname of the central RDBMS, hostname and location of the central self-service portal, host location of central LDAP, host location of central mail server etc.

Formally we build each application with a properties file, where all this properties are definied. But that's a very bad solution, because if the hostname of the mail server changes, we need to change the properties files for each application and deploy all applications again.

Our idea is to centralize this properties, so that each application can ask for each property at runtime, for example:

Idea: Put the properties file to an easy accessible file share. So if we need to change a property, each application uses the new properties.

Idea: Put the properties to database. Main disadvantage: we need a dependency to database client libraries for each application.

Idea: Put all applications into one big application server, that provides system properties for each application. Main disadvantage: needs deployment of each application to one application server. But that isn't a realistic scenario.

Idea: Webservice that provides global enterprise wide properties. Main disadvantage: not very secure, because some properties are passwords or user credentials.

What other alternatives are recommended? What is state of the art?

答:
There are three principally different approaches:

Have the applications pull the configuration every time.

Have a tool to push the configuration to the applications when it changes.

Make sure the configuration does not change.

In increasing order of preference. So

3. Make sure configuration does not change.

This is the preferred option. Create suitable aliases for everything that don't need to change.

Domain name for mail server should never change. The host can, but you just redirect the mail.company.com or mail.inranet1 to the new host. The same applies for all other network locations. Just create suitable DNS names for them. The same goes for database.company.com, ldap.company.com, self-service.company.com etc. Each web service and web application should have it's own vhost too, so you can move each independently without having to change the dependent applications.

The only case where the host names would change is when when you for example split the database server to two separate databases, but then you have to configure different applications differently, so the central configuration isn't going to help you anyway.

Similarly, each application should have separate account to the database, named as the application and limited to only the operations the application needs. This is for security reasons to minimize the damage if some of the applications is compromised. As a side-effect, it gives each application it's own username and password that don't need to change often, so no more reason for central configuration. Quite contrary; you want to limit the number of places that have each password so when somebody cracks one, the other applications and their accounts are not compromised.

In a sense, it is a shared configuration, but stored in the DNS server. And don't forget DNS can store various other information. There is the SRV record for recording ports where services run, records for storing various kind of encryption keys etc.

2. Have a tool to push the configuration to the applications

There is various configuration management software. These are tools that take care of installing software and deploying configuration across networks. Any non-trivial network should use one to ensure installing security updates.

If you have one, just add appropriate rules to deploy the properties file to all servers that run some application. If you don't, pick one2 and do the same, plus configure it to take care of the security updates.

Note, that these tools can also take care of restarting the application servers when they deploy new configuration or otherwise notify the applications that they need to reload the configuration.

So this is a good option, because such tool is very useful for administering the network in general.

3. Have the applications to pull the configuration.

This requires changing each application in advance. And it won't solve the issue completely anyway, because it suffers the chicken-and-egg problem. You still have to configure the location from which you should pull the rest of the configuration.

File sharing is obviously easiest regarding size of changes to each application. Just remember you'll have to restart the applications too or implement some mechanism for notifying them when configuration is changed, which also reduces the usefulness of the solution.

So I would definitely not recommend this approach of which all your original options are variations.

1You can use arbitrary non-existent top level domain in internal network and it has the advantage that you won't have to change it even if the company is renamed. Just don't use .local, which is reserved for mDNS.

2Or ask your system administrator to pick one; they are the one who will interact the most with it.

ContentLicense: CC BY-SA 3.0


问:
Can an object call a method on its immediate descendant?
I have an inheritance hierarchy three deep : an abstract base class, from which I derive another abstract class, call it the intermediate class, from which will derive possibly a large variety of derived classes.

At one point, the base class calls a this.GenerateXml() method, implemented in the derived class, that returns nothing, but writes xml to a public property. At this point, I would like the intermediate class to do some stuff, without the base class or the derived class having to call a specific method on the intermediate class.

Is this possible in OO languages? Constructors call each other up the chain of inheritance. Can methods? Can an object call a method on its immediate descendant? The language in this case is C#

The obvious solution is to call a method, perhaps a same named method, from the derived class, using "base". This is less than ideal, because every derived class has to remember to make the call.

答:
... the base class calls a this.GenerateXml() method, implemented in the derived class, that returns nothing, but writes xml to a public property. At this point, I would like the intermediate class to do some stuff, without the base class or the derived class having to call a specific method on the intermediate class.

When any of your classes calls "this.GenerateXml()", then your program will use the first implementation of that method that it can find, starting from the current class and working upwards through the Inheritance chain - Derived, Intermediate, Base.  So, what you're looking for will only work if the derived class doesn't implement GenerateXml.

The question is, what is this "stuff" that you want to do?  Is it something that might change from implementation to implementation?  If so, it should be defined in the base class as a protected, virtual (not abstract) method that your Intermediate class implements.  Of course, you will have to change the Base class to call this new method at the right time.


答:
Related to the last approach, using a web service: you may want to have a look at Apache Zookeeper. From its documentation:

ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services.

You are right to fear the security implications of this approach. Please note that Zookeeper comes from the Hadoop ecosystem, so its original intention was to provide configuration synchronization for Hadoop clusters, and other services that interact with Hadoop (like Hive, HBase, etc ...).

IMHO, Hadoop has never been very security-aware, since it expected all of these services to work in a trusted environment, but it is getting better at that and ZK may be an option to consider.  You may configure ZK to perform authentication and authorization prior to giving away all your secrets, but these options seem to be disabled by default.

Title: Where to store global enterprise properties?

Body:
I'm faced with a crowd of java applications, which need different global enterprise wide properties for operation, for example: hostname of the central RDBMS, hostname and location of the central self-service portal, host location of central LDAP, host location of central mail server etc.

Formally we build each application with a properties file, where all this properties are definied. But that's a very bad solution, because if the hostname of the mail server changes, we need to change the properties files for each application and deploy all applications again.

Our idea is to centralize this properties, so that each application can ask for each property at runtime, for example:

Idea: Put the properties file to an easy accessible file share. So if we need to change a property, each application uses the new properties.

Idea: Put the properties to database. Main disadvantage: we need a dependency to database client libraries for each application.

Idea: Put all applications into one big application server, that provides system properties for each application. Main disadvantage: needs deployment of each application to one application server. But that isn't a realistic scenario.

Idea: Webservice that provides global enterprise wide properties. Main disadvantage: not very secure, because some properties are passwords or user credentials.

What other alternatives are recommended? What is state of the art?


问:
What is the best design decision approach?
I have two classes (named MyFoo1 and MyFoo2) that share some common functionality. So far, it does not seem like I need any polymorphic inheritance but, at this point, I am considering the following options:

Have the common functionality in a utility class. Both of these classes call these methods from that utility class.

Have an abstract class and implement common methods in that abstract class. Then, the MyFoo1 and MyFoo2 classes will derive from that abstract class.

Any suggestion on what would be the best design decision?

答: Make sure your design is such that each class has clear responsibilities which can clearly be described by their names.  Consider which modularization will produce code that is easiest to test and modify. Factoring out whatever common code to a class called Utilities is a code smell.

OwnerDisplayName: palm snow


问:
How do you react to non-programmers with ideas of 'The Next Big Thing'?
Recently and quite often, people with no programming background come and say they have this great idea that can be the next big thing and that the idea(s) is worth a fortune by itself. Then as they know I'm a programmer, they ask me if I'm willing to "code it up" for them or find someone willing to do it for next to nothing.

Judging from the enthusiasm, it's like they're drunk on their idea and that that by itself is the most important thing, but they just need a programmer. My response to them, depending on my mood and their general attitude towards what we do, is something along the lines of:

"Having the core of an idea is one thing. Developing it to the point that it becomes a platform that changes the world in which it lives is another, and you're going to be willing to pay proportionately to how big you think your idea is worth."

Have you been approached by these business type entrepreneurs (with no technical/developer's knowledge) with such a proposal and how do you react to them?

答:
Turning an idea into a business is a very difficult transition.  It requires thinking about a number of intangible aspects, as well as the very important aspect of how are we going to make money off of the idea.  I would make the person come up with business plan if they are really serious.  It will help them see what holes are in their bright idea.

If the idea is intriguing enough to me, I might even help them come up with a rough estimate of how long the idea would take to build.  They need to see what it is that they are asking for.  Their 1,000 man hour (and more) idea suddenly becomes a non-trivial thing to ask of someone to do in their spare time for little or no pay.  Sure a startup needs passion, but people have to eat as well.  Asking someone to live off their savings for three months is not reasonable.  Getting funding to pay someone to do it properly is reasonable.

ContentLicense: CC BY-SA 2.5


问:
Can I use access used by Visual Basic for building a database
I am the only programmer where I work (summer job) and I am a student with only a few years of programming experience. So I was asked to build a database and I am very excited about this project because hopefully I can learn a lot from this.

Using this database my manager is supposed to be able to assign work (dealing with businesses) to different people within the company using an interface (all workers have a shared drive). When workers are done with that paperwork related to the business, they can check off that its done, add comments at the bottom of the interface, and then move on to the next business. The only experience I've had with databases is some querying with SQL, and I've built GUI interfaces with JAVA. The information on the interface will be populated from Excel so workers know what businesses they are dealing with.

I've done some research and I believe the best way to build this would be building a GUI using Microsoft Visual Studio (Visual Basic) first, then figuring out a way to populate the Interface from Excel. Also because the data is pretty straight forward and not complicated I will be using MS Access to store and track the database. I know this won't be easy, but for all you geniuses out there, is this on the right path? Thanks.

答:
Actually you could use whatever technology you like. Most programming languages and databases would be sufficient for this. But are you going to make a desktop application or a web application?

If you're going to make a desktop application I would pick windows forms (and choose C# as a programming language, because you said you knew java, very similar) and choose sql server express as the database (many times better than access).

Or actually it would not be much harder to make a web application in maybe asp.net with C# and have a sql server express database. The reach for this application would be much greater, because then your users would just browse to the url.


问:
Designing a social network with CQRS, graph databases and relational databases in mind
I have done quite an amount of research on the topic so far, but i couldn't come up with a conclusion to make up my mind.

I am designing a social network and during my research i stumbled upon graph databases, i found neo4j pretty interesting for user relations and traversing through nodes. I also thought of using a relational database such as MS-SQL or MySQL to store entity data only and depending on neo4j for connections between entities. Of course this means more work in my application to store and pull data in and out of 2 different sources.

My first question : Is using this approach (graph + relational) a good approach for designing my social network keeping in mind that users on social networks don't have to in synch with real data by split second ? What are the positives and negatives of this approach ?

My Second question : I've been doing some reading on CQRS and as i understood it is mostly useful for collaborative environments, and environments where users see a lot of "stale" data. social networks has shared comments, events, etc .. and many users query or update the same data. Could CQRS be a helpful approach ? Would it give any performance/scalability benefits or non-useful complexity ? Is it fairly applicable with my possible choice of (graph + relational) databases approach mentioned in the question above ?

My purpose is to know if the approaches i have mentioned above seem good enough for the business context.

答:
I'll weigh-in with some brief thoughts.

Topic 1 : Graph databases are good at modelling/querying hierarchies. Say that in your social app you want to let users know whether any of their Friends - or any of their Friend's Friends - have a birthday today. That can be an enormous query if you're recursing down all levels of Friends. A graph database should do this better than a relational database.

Yet a relational database is really good at a lot of other things - so you might consider utilizing both - relational for your general purposes, and graph for special purposes.

Topic 2 : CQRS is an architecture that helps with highly concurrent systems. In a brief nutshell, writes are thought of as a different problem than reads. Writes are typically dropped into a queue (fire & forget) and picked up when the system is able to / in a load-balanced manner.  If an error such as a deadlock is encountered, the write request remains on the queue and is retried until it (hopefully) succeeds (this is "eventual consistency").


问:
Designs for outputting to a spreadsheet
I'm working on a project where we are tasked to gather and output various data to a spreadsheet.

We are having tons of problems with the file that holds the code to write the spreadsheet. The cell that the data belongs to is hardcoded, so anytime you need to add anything to the middle of the spreadsheet, you have to increment the location for all the fields after that in the code. There are random blank rows, to add padding between sections, and subsections within the sections, so there's no real pattern that we can replicate. Essentially, anytime we have to add or change anything to the spreadsheet it requires a many long and tedious hours.

The code is all in this one large file, hacked together overtime in Perl. I've come up with a few OO solutions, but I'm not too familiar with OO programming in Perl and all my attempts at it haven't been great, so I've shied away from it so far. I've suggested we handle this section of the program with a more OO friendly language, but we can't apparently. I've also suggested that we scrap the entire spreadsheet idea, and just move to a webpage, but we can't do that either.

We've been working on this project for a few months, and every time we have to change that file, we all dread it. I'm thinking it's time to start some refactoring. However, I don't even know what could make this file easier to work with. The way the output is formatted makes it so that it has to be somewhat hardcoded.

I'm wondering if anyone has insight on any design patterns or techniques they have used to tackle a similar problem. I'm open to any ideas. Perl specific answers are welcome, but I am also interested in language-agnostic solutions.

答:
Depending on the library that you are using, you can name the specific ranges/cells that you output data to, then in your code just reference those names. That way if the design of the template spreadsheet changes, you don't need to change any code.

I know this works with PHPExcel, it may work in Perl also. If not, you could always just write a PHP script that Perl works with.

Title: Designs for outputting to a spreadsheet


答:
In my opinion, you are over-engineering the project. I think you do this because you believe you have to rely on cutting-edge techniques to handle business scale, but in many cases you will be better off relying on proven techniques and innovating only in a very focused scope.

A word of caution on graph databases: in my experience, they promise more than they can deliver. My experience is now some years ago, so I can't tell you if they have matured as products; but do you want to find out if something scales by using it as your main workhorse?

Let me remark there are some alternatives for such graph algorithms, some of them with provable scalability because they build on Hadoop's HDFS: see this SO thread or this Spark library.

On the topic of CQRS, it seems to deal with the kind of problems that large websites traditionally handle with a cache layer on top of their database replica sets. Write a wrapper around your queries that first looks into the cache layer, and if that misses its mark, then pulls the data from the database and also writes the result set into the cache. Here is a simple example in Python.

Moreover, splitting your queries into Commands and Queries on top of two database engines means that you have to decide, for each user request, whether it is graph-related or not, and whether it writes or just reads something; usually you will have a mix of all four possibilities.  If you get your decisions right, you will get a faster, more responsive social network; but be aware that you will get the same performance boost by making the right decisions in almost any language and runtime. And even so, response times will almost certainly be dominated by network latency.

In your place, I would concentrate on one of both topics, and I would also concentrate much more on the question: what does this technique enable that is better than existing social networking sites?

Title: Designing a social network with CQRS, graph databases and relational databases in mind

Body:
I have done quite an amount of research on the topic so far, but i couldn't come up with a conclusion to make up my mind.

I am designing a social network and during my research i stumbled upon graph databases, i found neo4j pretty interesting for user relations and traversing through nodes. I also thought of using a relational database such as MS-SQL or MySQL to store entity data only and depending on neo4j for connections between entities. Of course this means more work in my application to store and pull data in and out of 2 different sources.

My first question : Is using this approach (graph + relational) a good approach for designing my social network keeping in mind that users on social networks don't have to in synch with real data by split second ? What are the positives and negatives of this approach ?

My Second question : I've been doing some reading on CQRS and as i understood it is mostly useful for collaborative environments, and environments where users see a lot of "stale" data. social networks has shared comments, events, etc .. and many users query or update the same data. Could CQRS be a helpful approach ? Would it give any performance/scalability benefits or non-useful complexity ? Is it fairly applicable with my possible choice of (graph + relational) databases approach mentioned in the question above ?

My purpose is to know if the approaches i have mentioned above seem good enough for the business context.


问:
End user query syntax?
I'm making a command line tool that allows end users to query a statically-schemed database; however, I want users to be able to specify boolean matchers in their query (effectively things like "get rows where (field1=abcd && field2=efgh) || field3=1234"). I did Googling a solution, but I couldn't find anything suitable for end users--still, this seems like it would be a very common problem so I suspect there is a standard solution.

So:

What (if any) standard query "languages" are there that might be appropriate for end users?

What (if any) de facto standards are there (for example, Unix tools that solve similar problems).

Failing the previous two options, can you suggest a syntax that would be simple, concise, and easy to validate?

答:
This is called faceted search.  There are tools like Solr that can help you do it, but you don't want to use a language unless your users are highly technical (like consumers of a web service API), in which case you just use something SQL-like.

For inspiration on user interfaces, look at search results of companies with huge product lines, like Amazon or Digikey.  Basically after you start a search you are presented with a list of parameters by which you can refine your search, allowing you to drill down until you get the products you want.  This kind of interface is probably so familiar to you that you may not even have realized you were effectively querying specific fields of a database.

Another example of end user searching based on many fields is bug tracking websites.  They generally have a general purpose GUI-based search, and also a SQL-like query language for advanced searches.  If your users are technical or semi-technical, that might be a good model to follow.

Title: End user query syntax?


问:
Should I use my own public API on my site (via JS)?
First of all, this question is far more different other 'public api questions' like this: Should a website use its own public API?, second, sorry for my English. You can find the question summarized at the bottom of this question.

What I want to achieve is a big website with a public api, so who like programming (like me) and likes my website, can replicate my website's data with a much better approach (of course with some restrictions).

Almost everything could be used by the public API.

Because of this, I was thinking about making the whole website AJAX driven.

There would be parts of the API which would be limited only to my website (domain), like login, registering.

There would be only an INTERFACE on the client side, which would use the public and private API to make this interface working.

The website would be ONLY CLIENT SIDE, well, I mean, the website would only use AJAX to use the api.

How do I imagine this?

The website would be like a mobile application, the application only sending a request to a webserver, which returns a json, the application parses it, and uses it to advance in the application. (e.g.: login)

My thoughts:

Pros:

The whole website is built up by javascript, this means I don't need to transfer the html to the client, saving bandwidth. (I hope so)

Anyone can use up the data of my website to make their own cool things. (Is this a con or pro? O_O)

The public API is always in use, so I can see if there are any error.

Cons:

Without Javascript the website is unusable.

The bad guys easily can load the server with requesting too much data (like Request Per Second > 10000), but this can be countered via limiting this with some PHP code and logging.

Probably much more work

So the question in some words is: Should I build my website around my own api? Is it good to work only on the client side? Is this good for a big website? (e.x.: facebook, yeah facebook is a different story, but could it run with an 'architecture' like this?)

答:
If I understand your question correctly, your question is, "should I write a fat client?"

The answer is yes, if you want what a fat client provides you, which is a very high level of interactivity with the end user.  This level of interactivity is provided by a fat client, because you don't have to constantly make round trips to the server to get new pages.  If your app does not require that level of interactivity, then you may not need a fat client.

Your pro about the web server saving bandwidth by only sending data and not HTML does not seem compelling.  Unless you have millions of users, this level of bandwidth is never going to be a problem, and if you do have millions of users, I'd say it's a good problem.

Generally speaking, the more of your app that you can keep on the server, the easier it will be to write, and the more secure it is going to be.  Note that your server can still utilize a public API.

Examples of possible candidates for fat clients

Real-time game

Real-time, interactive business dashboard

Examples of possible candidates for thin clients

Online Survey Form

Billing Address Form (may include some AJAX for looking up city from the zip code, etc.)

Further Reading

Single-Page Application

Model-View-Controller


问:
Where do the responsibilities of build tools end and those of CI tools start?
In the delivery of software, and within the sense of the deployment pipeline, where do the responsibilities of build tools, like Maven, end, and the responsibilities of CI start?

As a rough example of a problem that arises; should build tools have any responsibility to the configuration and execution of acceptance tests when they are further down the pipeline than actually building the artifact?

I'd like an answer that addresses in the sense of deployment lifecycle phases rather than in specifics, like my example.  Although examples would help bolster the answer.

Body:
<a href="https://softwareengineering.stackexchange.com/questions/241223/where-do-the-responsibilities-of-build-tools-end-and-those-of-ci-tools-start/241234#comment484414_241223" title="'The build script is the mechanism that, upon invocation on freshly checked-out source tree, yields a complete build of required targets and dependencies... The build server, or rather continuous integration server, is the automation mechanism responsible for scheduling/triggering, monitoring and reporting of the checkout -> build -> test -> package -> stage -> deploy pipeline... It is important that you can invoke a build without using the CI server... the logic to get the build... needs to be outside of the CI...'">This comment sounds right.

In my opinion, as much of the build code as possible should be in the product's internal build scripts, such as ant's build.xml, maven's pom.xml, etc.  This serves 3 purposes:

Versions the build process along with the product.  If you fork a branch of your product in source control and make a change that requires build changes (like say you are adding a minify step to javascript files that was not there before), nothing outside of your source control needs to change.

Ease of development and on-boarding.  As a developer, it is great for productivity when I can simply checkout the code from source control and run a build command, be it ant clean build or mvn package or whatever.

Removes the dependence on CI for builds.  You should use CI for builds, but if Jenkins is down for any reason, you don't want to be unable to build.  CI should be about automating an existing streamlined build process.

Ideally, a CI server should be configured to simply do this:

Checkout

Run a build command, preferably the same command developers run or perhaps a super-set of those commands.

Archive the build to some official build archive location.

Where this gets less clear is with processes that occur at build time but are not strictly needed to build, such as unit and integration tests.

My preference would be to include unit tests in the core build.  That is, you cannot get a build, even in dev, without the unit tests running and passing.  Of course, that requires a huge amount of discipline and rarely is done.  If you are lucky enough to have an environment that runs automated unit tests, including them in the core build seems like a good idea.

Integration tests, however, can take much longer, so running them any time you just want to compile code can be a huge productivity drain.  Imagine if every compile -> test cycle requires an hour-long integration test suite.  You would compensate by compiling less often which means less testing and naturally no good will come from that.

What I would do is define such functionality in build scripts within source control but not wire them into the core build.  I don't know Maven very well, but for ant, I would define a separate target, like ant integrationTests that you need to explicitly run.  That could be configured in the CI system and that way, developers can choose if/when to run it themselves on their systems.

To put into a pipeline view, perhaps something like this:

Checkout -> Build -> Integration Tests -> System Tests -> Performance Tests -> Load Tests -> Archive Build -> Deploy

The implementation of each of those steps should live inside the product's build scripts in source control (except for checkout, otherwise you have a chicken or egg problem) and the build process owns the decision of which step to call in what order.  Certain steps may not be needed on every build.  Load tests, for instance, maybe only run once release.

That is my 2 cents.  I am by no means an authority on the subject, but I have seen builds done well and builds done poorly.


问:
Should I always encapsulate an internal data structure entirely?
Please consider this class:

```<code>class ClassA{

    private Thing[] things; // stores data

    // stuff omitted

    public Thing[] getThings(){
        return things;
    }

}
</code>```

This class exposes the array it uses to store data, to any client code interested.

I did this in an app I'm working on. I had a ChordProgression class that stores a sequence of Chords (and does some other things). It had a Chord[] getChords() method that returned the array of chords. When the data structure had to change (from an array to an ArrayList), all client code broke.

This made me think - maybe the following approach is better:

```<code>class ClassA{

    private Thing[] things; // stores data

    // stuff omitted

    public Thing[] getThing(int index){
        return things[index];
    }

    public int getDataSize(){
        return things.length;
    }

    public void setThing(int index, Thing thing){
        things[index] = thing;
    }

}
</code>```

Instead of exposing the data structure itself, all of the operations offered by the data structure are now offered directly by the class enclosing it, using public methods that delegate to the data structure.

When the data structure changes, only these methods have to change - but after they do, all client code still works.

Note that collections more complex than arrays might require the enclosing class to implement even more than three methods just to access the internal data structure.

Is this approach common? What do you think of this? What downsides does it have other? Is it reasonable to have the enclosing class implement at least three public methods just to delegate to the inner data structure?

答:
You asked: Should I always encapsulate an internal data structure entirely?

Brief Answer: Yes, most of the time but not always.

Long Answer: I think that classes follow into following categories:

Classes that encapsulate simple data. Example: 2D point. It's easy to create public functions that provide the ability to get/set the X and Y coordinates but you can hide the internal data easily without too much trouble. For such classes, exposing the internal data structure details is uncalled for.

Container classes that encapsulate collections. STL has the classic container classes. I consider std::string and std::wstring among those too. They provide a rich interface to deal with the abstractions but std::vector, std::string, and std::wstring also provide the ability to get access to the raw data. I wouldn't be hasty to call them poorly designed classes. I don't know the justification for these classes exposing their raw data. However, I have, in my work, found it necessary to expose the raw data when dealing with millions of mesh nodes and data on those mesh nodes for performance reasons.

The important thing about exposing the internal structure of a class is that you have to think long and hard before giving it a green signal. If the interface is internal to a project, it will be expensive to change it in the future but not impossible. If the interface is external to the project (such as when you are developing a library that will be used by other application developers), it may be impossible to change the interface without losing your clients.

Classes that are mostly functional in nature. Examples: std::istream, std::ostream, iterators of the STL containers. It's outright foolish to expose the internal details of these classes.

Hybrid classes. These are classes that encapsulate some data structure but also provide algorithmic functionality. Personally, I think these are a result of poorly thought design. However, if you find them, you have to decide whether it makes sense to expose their internal data on a case by case basis.

In conclusion: The only time I have found it necessary to expose the internal data structure of a class is when it became a performance bottleneck.


问:
Help me catch up on what I've missed since Java 1.4.2
I am about to start my first professional career position as a software developer, and I'm likely going to be writing a lot of Java code.  I don't know that much about what specifically I'll be writing, and besides, I have fairly broad interests when it comes to code anyway.

For reasons not worth discussing, my last internship had me coding only for the Java 1.3 and 1.4 SDK's.  Also, my university education has focused mainly on algorithms, data structures, and other theory, not language features or libraries.

So, with the above in mind, what features, classes, etc. in the current version of Java (what number are we on now, anyway?) would be worth my time to read up on and why?  What have I missed since 1.4.2 that makes your life as a programmer easier?

Examples and stories of how you discovered a particular package or some such and put it to use would also be great.

答:
Since I can't comment because I'm below 50 I'll leave an answer. It's been already mentioned but I'll repeat it again: Annotations!
This kind of metadata became the most important thing in my years of Java experience. It well used like some frameworks do it makes the code much more concise and clean. For example, annotations can:

Convert an object into an entity @Entity

Convert a method into a REST service @GET

Explain that a method will never return null @nonnull

Set an object to a field for dependency injection @inject

And of course you can build your own annotations and know if a method, class or field is annotated using reflection.


问:
Why is it an issue that it takes 2 digits to represent the number 10 in decimal?
So we use hexadecimal which has the advantage of going up to 15 in single digits A-F, but why is it an issue that it takes 2 digits to represent the number 10 in decimal?

I was reading up about hexadecimal and I came across these 2 lines:

Base 16 suggests the digits 0 to 15, but the problem we face is that it requires 2 digits to represent 10 to 15. Hexadecimal solves this problem by using the letters A to F.

My question is, why should we care how many digits it takes to represent a number? - Is it slower for the computer to deal with a number with 2 digits compared to 1?

答:
Because 15 was the maximum value of a "word" at one point in time. A "word" refers to (among many other things over the years) the number of bits that a CPU is designed to operate on as a single thing. 4 bits toggled 1111 makes the binary value of 15.

Hexadecimal was created with the explicit purpose of being able to dictate in a single character, the value of a word of memory. With one character you can dictate what is a binary value between 0000 and 1111 which is the full range of a word at the time when it became common place to use.

Nowadays hexadecimal is typically seen in 8 bit groups, thus 8 bits being 2 hexadecimal values you usually see hexadecimal in pairs ranging from 0x00 to denote zero, or 0xFF to denote 255 (the greatest value that can be held in 8 binary digits) etc. These pairs are refered to as octets, named so because they refer to the value of 8 bits.


答: It's an awkward way to phrase it, but it's only a "problem" when you're trying to write hexadecimal numbers.  It's not a problem in decimal.  If you used 10 instead of A in hexadecimal, then 100 could be parsed as 1 0 0 or 10 0, which are two very different numbers.  You would need some other means of separating the digits.  One character per digit avoids that issue.

Title: Why is it an issue that it takes 2 digits to represent the number 10 in decimal?

Body:
So we use hexadecimal which has the advantage of going up to 15 in single digits A-F, but why is it an issue that it takes 2 digits to represent the number 10 in decimal?

I was reading up about hexadecimal and I came across these 2 lines:

Base 16 suggests the digits 0 to 15, but the problem we face is that it requires 2 digits to represent 10 to 15. Hexadecimal solves this problem by using the letters A to F.

My question is, why should we care how many digits it takes to represent a number? - Is it slower for the computer to deal with a number with 2 digits compared to 1?


答:
Without knowing the full context of the statement this is a little speculative, but, the author is likely noting that hexadecimal is just one implementation of Base 16.

In a Base 16 schema, you need 16 symbols. We're already familiar with 10 such symbols in decimal that we can easily "reuse" without confusing ourselves. So, in the hexadecimal implementation of Base 16, we solve the "problem" of the missing 6 symbols by adding A through F to our numeric symbol set.


答:
When it's an issue, it's because it causes a mismatch between the memory required to store a value and the memory required to display a value.

Take HTML color codes, for example. Each of the three red, blue, and green values has an integer value between 0 and 255. In memory, this is represented as a single 8 bit value, with all of the values from 00 to FF requiring the same amount of memory to store or write. Having two digits lets the text parser be very specific on the format, while keeping the number of characters needed at a minimum.  Hexadecimal also exactly matches to numeric memory allocations; a single digit equals a single 4-bit value, two digits equal an eight-bit value, and so on.


问:
How to analyze a scenario where a bug didn't get caught and adjust development workflow to prevent similar errors
I had a bug that was really difficult to track down, because all the unit tests were green, but the production application didn't work properly.

Here's what happened:

I had a filter class that set my application to ignore data that was not in some specified time windows.

The unit test, which seemed thorough to me, turned green.

Additionally, my integration tests also produced results as expected.

Production, however, did not work.

As a result of the first two bullets, this problem was very difficult to find.

It turned out the problem was that my test dates were using my time zone (America/Chicago) but the production data was providing dates in UTC, which I did not realize, and the logic for the filter wasn't correct for UTC dates. (I was using joda time DateTime objects).

Where did my workflow break down?

Did I fail to produce a spec that specified that the logic needed to handle dates in any time zone?

Did I fail to thoroughly consider all cases at the unit test level?

Did I fail to insure the integration test was sufficiently similar to production?

Other?

What changes can I make to my workflow to better prevent this sort of mistake in the future?

How can I more effectively debug a problem when there is an issue in production but not in testing?

答:
@RobertHarvey's comment is dead right: Process will not produce bug-free software, but good process can at least reduce the recurrence of classes of bugs. Sounds like you're attempting to accomplish the latter, so I will make my suggestion of where I think your mistake came in:

You failed to account for all the details of your production environment in your tests. Your tests should run in an environment that is as closely mimicing that of production as possible. In your case, you missed the fact that production deals with time in UTC while your unit tests were running with a different timezone.

Moving forward, just be aware of the way your production environment is configured and how it runs in as many details as possible. Whenever you go to write unit tests, look for things that may vary to effect your unit tests as possible, and try to make those variances match with what occurs in production.

That little forethought when writing your unit tests may help you moving forward catch other ways in which your tests don't run the same way as production does. Write it down in a checklist if you use those, either way just try to be mindful of it when writing your tests.

Process will not stop you from ending up with more bugs, even ones related to this one, but with that mindfulness moving forward hopefully the class of bugs known as "things that fail in production but not in development" will be reduced significantly.

One thing you may be missing that is common, is a document detailing the system that has specifics about all the things that vary. What timezone it runs on, what versions of languages it's written in, whether 64-bit or 32-bit, all of these things effect the behaviour of the system. Having them documented can help a team significantly to know more about the system than they often do individually. An individual developer frequently only knows subsections of the system, and may be unaware of these larger systemic details that effect them in ways they're otherwise unaware of.

Where did my workflow break down?

Where your tests attempted to mimic production

What changes can I make to my workflow to better prevent this sort of mistake in the future?

Document and or account for such variances between your dev and production environments.

How can I more effectively debug a problem when there is an issue in production but not in testing?

Isolate the variables that may differ from system to system and check them between your dev and production environments. If you wish to learn it, using a debugger that can take a memory dump and let you analyze the live processes state can often help in this case, though  learning that is far from an insignificant undertaking.


问:
What non-programming books should a programmer read to help develop programming/thinking skills?
There are a lot of questions about what programming books should be on the programmer's bookshelf. How about non-programming related books that can help you become a better programmer or developer? It would also be interesting to know why they would help.

My first choice would be Sun Tzu's "Art of War" (however cliché), because it made it obvious that the success of any project depends on the strength of its weakest link (and warfare is a big project).

答: Alice In Wonderland and Through The Looking-Glass.  Read Alice's conversation with the White Knight and see if you don't come away with a deeper appreciation for indirection and reference variables!


问:
Using packages (gems, eggs, etc.) to create decoupled architectures
The main issue

Seeing the good support most modern programming platforms have for package management (think gem, npm, pip, etc), does it make sense to design an application or system be composed of internally developed packages, so as to promote and create a loosely coupled architecture?

Example

An example of this would be to create packages for database access, as well as for authentication and other components of the system.  These, of course, use external packages as well.  Then, your system imports and uses these packages - instead of including their code within its own code base.

Considerations

To me, it seems that this would promote code decoupling and help maintainability, almost in a Web-based-vs.-desktop-application kind of way (updates are applied almost automatically, single code base for single functionality, etc.).

Does this seem like a rational and sane design concept?  Is this actually used as a standard way of structuring applications today?

答:
I've been involved in projects like this twice now (both using nuget with .NET), and I would say that on balance it is a good idea. But your mileage may vary.

Don't think for a minute that it's a panacea, that it's going to solve all of your problems without causing new ones. Release management will gain a whole new layer of complexity, you'll need to deal with version-dependency issues you never knew existed, and you will have times when you curse the decision because you've got to upgrade four different packages because of a small bug that you need to fix and release quickly.

On the other hand, you're right that it decouples things nicely. Unless you overdo it, you'll probably find more occasions when you think "oh, that worked out nicely," than "that added a lot of effort." If you have code shared among multiple applications, it's particularly effective because you can easily upgrade your apps independently.

And, if you're anything like me, you'll quickly start writing test apps that use your packages, to remove entire layers of application from your bug-finding process. And that, in itself, can be more than worth the costs.


问:
Restructuring a large Chrome Extension/WebApp
I have a very complex Chrome Extension that has gotten too large to maintain in its current format.  I'd like to restructure it, but I'm 15 and this is the first webapp or extension of it's type I've built so I have no idea how to do it.

TL;DR: I have a large/complex webapp I'd like to restructure and I don't know how to do it. Should I follow my current restructure plan (below)? Does that sound like a good starting point, or is there a different approach that I'm missing? Should I not do any of the things I listed?

While it isn't relevant to the question, the actual code is on Github and the extension is on the webstore.

The basic structure is as follows:

index.html

        <link href="css/style.css" rel="stylesheet" />
        <link href="css/widgets.css" rel="stylesheet" />

```

<p><strong>widgets.js</strong>
</p>

```(initLog || (window.initLog = [])).push([new Date().getTime(), "A log is kept during page load so performance can be analyzed and errors pinpointed"]);

// Widgets are stored in an object and extended (with jQuery, but I'll probably switch to underscore if using Backbone) as necessary
var Widgets = {
    1: { // Widget ID, this is set here so widgets can be retreived by ID
        id: 1, // Widget ID again, this is used after the widget object is duplicated and detached
        size: 3, // Default size, medium in this case
        order: 1, // Order shown in "store"
        name: "Weather", // Widget name
        interval: 300000, // Refresh interval
        nicename: "weather", // HTML and JS safe widget name
        sizes: ["tiny", "small", "medium"], // Available widget sizes
        desc: "Short widget description",
        settings: [
            { // Widget setting specifications stored as an array of objects.  These are used to dynamically generate widget setting popups.
                type: "list",
                nicename: "location",
                label: "Location(s)",
                placeholder: "Enter a location and press Enter"
            }
        ],
        config: { // Widget settings as stored in the tabs object (see script.js for storage information)
            size: "medium",
            location: ["San Francisco, CA"]
        },
        data: {}, // Cached widget data stored locally, this lets it work offline
        customFunc: function(cb) {}, // Widgets can optionally define custom functions in any part of their object
        refresh: function() {}, // This fetches data from the web and caches it locally in data, then calls render. It gets called after the page is loaded for faster loads
        render: function() {} // This renders the widget only using information from data, it's called on page load.
    }
};
```

<p><strong>script.js</strong>
</p>

```(initLog || (window.initLog = [])).push([new Date().getTime(), "These are also at the end of every file"]);

// Plugins, extends and globals go here. i.e. Number.prototype.pad = ....

var iChrome = function(refresh) { // The main iChrome init, called with refresh when refreshing to not re-run libs
    iChrome.Status.log("Starting page generation"); // From now on iChrome.Status.log is defined, it's used in place of the initLog

    iChrome.CSS(); // Dynamically generate CSS based on settings

    iChrome.Tabs(); // This takes the tabs stored in the storage (see fetching below) and renders all columns and widgets as necessary

    iChrome.Status.log("Tabs rendered"); // These will be omitted further along in this excerpt, but they're used everywhere

    // Checks for justInstalled => show getting started are run here

    /* The main init runs the bare minimum required to display the page, this sets all non-visible or instantly need things (such as widget dragging) on a timeout */
    iChrome.deferredTimeout = setTimeout(function() {
        iChrome.deferred(refresh); // Pass refresh along, see above
    }, 200);
};

iChrome.deferred = function(refresh) {}; // This calls modules one after the next in the appropriate order to finish rendering the page

iChrome.Search = function() {}; // Modules have a base init function and are camel-cased and capitalized

iChrome.Search.submit = function(val) {}; // Methods within modules are camel-cased and not capitalized

/*
  Extension storage is async and fetched at the beginning of plugins.js, it's then stored in a variable that iChrome.Storage processes.

  The fetcher checks to see if processStorage is defined, if it is it gets called, otherwise settings are left in iChromeConfig
*/
var processStorage = function() {
    iChrome.Storage(function() {
        iChrome.Templates(); // Templates are read from their elements and held in a cache

        iChrome(); // Init is called
    });
};

if (typeof iChromeConfig == "object") {
    processStorage();
}
```

Objectives of the restructure

Memory usage:  Chrome apparently has a memory leak in extensions, they're trying to fix it but memory still keeps on getting increased every time the page is loaded.  The app also uses a lot on its own.

Code readability: At this point I can't follow what's being called in the code. While rewriting the code I plan on properly commenting everything.

Module interdependence: Right now modules call each other a lot, AFAIK that's not good at all since any change you make to one module could affect countless others.

Fault tolerance: There's very little fault tolerance or error handling right now.  If a widget is causing the rest of the page to stop rendering the user should at least be able to remove it.

Speed is currently not an issue and I'd like to keep it that way.

How I think I should do it

The restructure should be done using Backbone.js and events that call modules (i.e. on storage.loaded => init).

Modules should each go in their own file, I'm thinking there should be a set of core files that all modules can rely on and call directly and everything else should be event based.

Widget structure should be kept largely the same, but maybe they should also be split into their own files.

AFAIK you can't load all templates in a folder, therefore they need to stay inline.

Grunt should be used to merge all modules, plugins and widgets into one file.  Templates should also all be precompiled.

Question:

Should I follow my current restructure plan? Does that sound like a good starting point, or is there a different approach that I'm missing? Should I not do any of the things I listed?

Do applications written with Backbone tend to be more intensive (memory and speed) than ones written in Vanilla JS?

Also, can I expect to improve this with a proper restructure or is my current code about as good as can be expected?

答:
Memory usage: Chrome apparently has a memory leak in extensions, they're trying to fix it but memory still keeps on getting increased every time the page is loaded. The app also uses a lot on its own.

You need to define what "alot" is, and what "too much" is. Memory usage is only a problem when there isn't enough. Investigating memory problems has little to do with refactoring. You need to locate any offending code and plug the leak. If you know your code is leaking memory, than I would try to isolate the offending areas and go to stackoverflow.com to seek advise on fixing it.

Code readability: At this point I can't follow what's being called in the code. While rewriting the code I plan on properly commenting everything.

This is a very subjective issue. Code structure, source code comments and code readability are all matters of opinion.

Module interdependence: Right now modules call each other a lot, AFAIK that's not good at all since any change you make to one module could affect countless others.

Now this is where we can help you. There are multiple platforms and tools out there for Javascript developers to address these issues. There are also multiple design patterns that address these issues. There are package builders, code compilers and dependency injectors.

I use AngularJS with Google's Closure compiler. Angular gives me dependency injection, and closure gives me compile time warnings and packaging.

You'll have to decide what tools work for you. Trust me. It's a painful process to pick a tool.

Fault tolerance: There's very little fault tolerance or error handling right now. If a widget is causing the rest of the page to stop rendering the user should at least be able to remove it.

This is a high-level requirement. It's something to "keep in mind" when you are rewriting it.

Do applications written with Backbone tend to be more intensive (memory and speed) than ones written in Vanilla JS?

No. Backbone does not offer anything that addresses your specific issues. It's designed to be a light-weight library that offers you only a couple of base classes to mimic a MVC pattern. The developers wanted something that had a very light-weight foot-print. I don't think a Chrome extension needs to be light-weight. It's installed on the PC and runs local. You can afford to go with something heavier and offers a more robust framework.

Also, can I expect to improve this with a proper restructure or is my current code about as good as can be expected?

You've made some basic mistakes if fixed will greatly improve your time maintaining the code.

I could create a list of issues, but that's not the point of this answer.

What you want to learn is the building blocks of highly maintainable code.

Have you put code into easy to locate files, or is everything in one big file?

Can you tell by looking at your files what is "new untested code" and "old reliable code"?

Can you test it?

Does each file have a clear name and contain code that is clear of it's purpose.

Is each file simple. Short and to the point.

Are your functions written to prevent misuse.

The list goes on like that, but hopefully you get the idea.


问:
Flags with deferred use
Let's say I have a system. In this system I have a number of operations I can do, but all of these operations have to happen as a batch at a certain time, while calls to activate and deactivate these operations can come in at any time. No matter how many times the doOperation1() method/function is called the operation is done only once in the batch. To implement this, I could use flags like doOperation1 and doOperation2 but this seems like it would become difficult to maintain. Is there a design pattern, or something similar, that addresses this situation?

答: You may want to look at the Visitor Pattern. It allows you to decouple operations from the objects they work on.  If you extend this pattern, to place those operations into a queue, and then process the queue as a batch, this may work.</p>

Title: Flags with deferred use


问:
Should a package manager modify your .bashrc file?
I am writing a package for something that requires an environment variable to be set in order to execute properly.  Should the install step of a package manager modify a user's environment, or simply prompt the user to do so themselves?  My intuition would be the latter, but I can see arguments for the former.</p>

答: You're missing the forest for the trees. Obviously it's more convenient to perform the environment change for the user, but it's also more risky and somewhat invasive. You should combine the best of both worlds by asking the user whether the installer should modify their .bashrc, and otherwise give instructions how they should do it themselves.


答:
I'm getting old and cynical, I'm afraid.  I initially meet those sort of claims with the skepticism of encountering a snake-oil salesman.  Especially if that person's past endeavors have not borne fruit.  The "next big thing" is part research and part leap of faith.  All too often I run into folks who have the last part in spades but haven't done a lick of real research.  If I had hitched my cart to everyone who just "needed a quick website" or some such to be the replacement for Twitter, I'd be broke and out of a job and likely unemployable.

All that gloom and doom being said, I'm very proud of my past ownership with a next big thing company that is still doing well with a great product: http://www.dvdprofiler.com/ .

Title: How do you react to non-programmers with ideas of 'The Next Big Thing'?

Body:
Recently and quite often, people with no programming background come and say they have this great idea that can be the next big thing and that the idea(s) is worth a fortune by itself. Then as they know I'm a programmer, they ask me if I'm willing to "code it up" for them or find someone willing to do it for next to nothing.

Judging from the enthusiasm, it's like they're drunk on their idea and that that by itself is the most important thing, but they just need a programmer. My response to them, depending on my mood and their general attitude towards what we do, is something along the lines of:

"Having the core of an idea is one thing. Developing it to the point that it becomes a platform that changes the world in which it lives is another, and you're going to be willing to pay proportionately to how big you think your idea is worth."

Have you been approached by these business type entrepreneurs (with no technical/developer's knowledge) with such a proposal and how do you react to them?


答:
Question Should the install step of a package manager modify a user's environment?

Answer No. It's a bad idea to modify a user's data, in this case the .bashrc file. User's data should be considered sacred by a package manager?

Question Should the install step of a package manager simply prompt the user to do so themselves?

Answer This is a lot more palatable solution but still not ideal.

I think you should create a wrapper shell script where you can set the necessary environment variables and them run the executable after that.

Title: Should a package manager modify your .bashrc file?

Body: I am writing a package for something that requires an environment variable to be set in order to execute properly.  Should the install step of a package manager modify a user's environment, or simply prompt the user to do so themselves?  My intuition would be the latter, but I can see arguments for the former.</p>


答: Setting a global variable in a package is acceptable if it's a one defined by your own project(and that means the project's name is part of the variable's name!). Even then, you shouldn't touch the user's .bashrc file - instead you should add a script to /etc/profile.d.


问:
Question about casting a class in Java with generics
In Java 6

```<code>Class<? extends ArrayList<?>> a = ArrayList.class;
</code>```

gives and error, but

```<code>Class<? extends ArrayList<?>> b = (Class<? extends ArrayList<?>>)ArrayList.class;
</code>```

gives a warning.

Why is (a) an error?  What is it, that Java needs to do in the assignment, if not the cast shown in (b)?

And why isn't ArrayList compatible with ArrayList<?>  I know one is "raw" and the other is "generic", but what is it you can do with an ArrayList<?> and not with an ArrayList, or the other way around?

答:
Well, a generic class is by definition not equal to a raw class. What you're trying there hides the issue of instantiation of ArrayLists (the actual lists, not their types).

```<code>ArrayList raw = new ArrayList();
</code>```

will work and will allow any kind of element, objects, primitives, anything. On the other hand,

```<code>ArrayList<?> generic = new ArrayList<?>();
</code>```

won't work since it's unclear, at compile time, what actual elements the list will hold. So, in order to make the list (almost) as broadly usable as the raw one, you could instantiate it like this:

```<code>ArrayList<?> generic = new ArrayList<Object>();
</code>```

(That will only hold actual objects, though, no primitives.)

generic and raw will never be equal type-wise and it won't make sense for them to be equal.

What you can do with generic types instead of raw ones? Well, be safe at compile time. :) The other way around? Use primitives (generic types must inherit from Object which primitives do not).

Body:
Well, a generic class is by definition not equal to a raw class. What you're trying there hides the issue of instantiation of ArrayLists (the actual lists, not their types).

ArrayList raw = new ArrayList();

will work and will allow any kind of element, objects, primitives, anything. On the other hand,

ArrayList<?> generic = new ArrayList<?>();

won't work since it's unclear, at compile time, what actual elements the list will hold. So, in order to make the list (almost) as broadly usable as the raw one, you could instantiate it like this:

ArrayList<?> generic = new ArrayList<Object>();

(That will only hold actual objects, though, no primitives.)

generic and raw will never be equal type-wise and it won't make sense for them to be equal.

What you can do with generic types instead of raw ones? Well, be safe at compile time. :) The other way around? Use primitives (generic types must inherit from Object which primitives do not).


答:
It's never acceptable to modify a user's /home structure from the package manager unless that modification is the entire point.

The main approaches to this are:

Notify the user they need to configure it.

Supply defaults so it's not needed

Package a launcher script that sets the values appropriately

(If the distro supports it) Drop a file exporting the environment variable inside /etc/profile.d. On some linux systems, all scripts in this directory are sourced by the default shell setup, so you can safely set the variable there.


答:
Should the install step of a package manager modify a user's
  environment, or simply prompt the user to do so themselves?

Neither.  Package installers should never touch anything in a home directory for an account the package doesn't own.  Packages should also configure themselves so that if they're installed, they're usable without any special effort on the user's part.  (There are exceptional cases where you don't want to do this, but they're few and far between.)

Unixy environments have a place to put configuration files that are read whenever a user starts a login shell.  For the Bourne and C shells, you can insert your configuration into /etc/profile and /etc/csh.cshrc respectively.  (Don't forget to remove it when you uninstall.)

Many systems also support doing this using individual files, which makes it easier to add and remove bits of configuration without having to drop text into some arbitrary place in one file.  (It also gives you all of the control and accountability benefits you get from a package manager.)  Some distributions will configure /etc/profile read all files matching /etc/profile.d/*.sh.


问:
Best books on the theory and practice of software architecture?
I have a couple of developers at my company who wish to move from programming into architecture. What are the best books out there on the theory and practice of software architecture? Include a cover picture if you can.

Feel free to include general books, and also books that relate to a specific technology.

答:
A must read for all programmers:

http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612


问:
Data structure for grid with negative indeces
Sorry if this is an insultingly obvious concept, but it's something I haven't done before and I've been unable to find any material discussing the best way to approach it.

I'm wondering what's the best data structure for holding a 2D grid of unknown size. The grid has integer coordinates (x,y), and will have negative indices in both directions.

So, what is the best way to hold this grid? I'm programming in c# currently, so I can't have negative array indices. My initial thought was to have class with 4 separate arrays for (+x,+y),(+x,-y),(-x,+y), and (-x,-y). This seems to be a valid way to implement the grid, but it does seem like I'm over-engineering the solution, and array resizing will be a headache.

Another idea was to keep track of the center-point of the array and set that as the topological (0,0), however I would have the issue of having to do a shift to every element of the grid when repeatedly adding to the top-left of the grid, which would be similar to grid resizing though in all likelihood more frequent.

Thoughts?

答:
Write a new data structure having an indexer that routes negative indexes into a different list.

```<code>public class PositiveNegativeList<T>
{
    List<T> PositiveList;
    List<T> NegativeList;

    public PositiveNegativeList()
    {
         PositiveList = new List<T>();
         NegativeList = new List<T>();
    }

    public T this[int index]
    {
        get
        {
            if (index < 0)
               return NegativeList[index * -1];
            else
               return PositiveList[index];
        }

        set
        {
            if (index < 0)
               NegativeList[index * -1] = value;
            else
               PositiveList[index] = value;
        }
    }

    public void Add(T item)
    {
        PositiveList.Add(item);
    }
}
</code>```

Code now tested.  Note that nothing is ever as simple as it should be; you will need an Add() method of some kind to get new items into the Lists.

Body:
Write a new data structure having an indexer that routes negative indexes into a different list.

public class PositiveNegativeList<T>
{
    List<T> PositiveList;
    List<T> NegativeList;

    public PositiveNegativeList()
    {
         PositiveList = new List<T>();
         NegativeList = new List<T>();
    }

    public T this[int index]
    {
        get
        {
            if (index < 0)
               return NegativeList[index * -1];
            else
               return PositiveList[index];
        }

        set
        {
            if (index < 0)
               NegativeList[index * -1] = value;
            else
               PositiveList[index] = value;
        }
    }

    public void Add(T item)
    {
        PositiveList.Add(item);
    }
}

Code now tested.  Note that nothing is ever as simple as it should be; you will need an Add() method of some kind to get new items into the Lists.


问:
Developers blocked by waiting on code to merge from another branch using GitFlow
Our team just made the switch from FogBugz & Kiln/Mercurial to Jira & Stash/Git. We are using the Git Flow model for branching, adding subtask branches off of feature branches (relating to Jira subtasks of Jira features). We are using Stash to assign a reviewer when we create a pull request to merge back into the parent branch (usually develop but for subtasks back into the feature branch).

The problem we're finding is that even with the best planning and breakdown of feature cases, when multiple developers are working together on the same feature, say on the front-end and back-end, if they are working on interdependent code that is in separate branches one developer ends up blocking the other.

We've tried pulling between each others' branches as we develop. We've also tried creating local integration branches each developer can pull from multiple branches to test the integration as they develop. Finally, and this seems to work possibly the best for us so far, though with a bit more overhead, we have tried creating an integration branch off of the feature branch right off the bat. When a subtask branch (off of the feature branch) is ready for a pull request and code review, we also manually merge those change sets into this feature integration branch. Then all interested developers are able to pull from that integration branch into other dependent subtask branches. This prevents anyone from waiting for any branch they are dependent upon to pass code review.

I know this isn't necessarily a Git issue - it has to do with working on interdependent code in multiple branches, mixed with our own work process and culture. If we didn't have the strict code-review policy for develop (true integration branch) then developer 1 could merge to develop for developer 2 to pull from. Another complication is that we are also required to do some preliminary testing as part of the code review process before handing the feature off to QA.This means that even if front-end developer 1 is pulling directly from back-end developer 2's branch as they go, if back-end developer 2 finishes and his/her pull request is sitting in code review for a week, then front-end developer 2 technically can't create his pull request/code review because his/her code reviewer can't test because back-end developer 2's code hasn't been merged into develop yet.

Bottom line is we're finding ourselves in a much more serial rather than parallel approach in these instance, depending on which route we go, and would like to find a process to use to avoid this.

Last thing I'll mention is we realize by sharing code across branches that haven't been code reviewed and finalized yet we are in essence using the beta code of others. To a certain extent I don't think we can avoid that and are willing to accept that to a degree.

答:
If developer 1 works on feature A, and developer 2 finished working on feature B that depends on feature A, then there is no way around it - merging feature B is on hold. You can't test it without feature A, and there is no point in reviewing it yet since farther progress in feature A might lead to changes in feature B.

That does not mean, however, that developer 2 is on hold! Developer 2 can start working on feature C, and return to the review-fix cycle of feature B once feature A is complete. I know that context switching is not optimal, but since the time it'll take to complete feature A is probably measured in days it's not that bad(you are not pulling them out of "The Zone" for a 15 minutes side-task)


问:
How do you react to non-programmers with ideas of 'The Next Big Thing'?
Recently and quite often, people with no programming background come and say they have this great idea that can be the next big thing and that the idea(s) is worth a fortune by itself. Then as they know I'm a programmer, they ask me if I'm willing to "code it up" for them or find someone willing to do it for next to nothing.

Judging from the enthusiasm, it's like they're drunk on their idea and that that by itself is the most important thing, but they just need a programmer. My response to them, depending on my mood and their general attitude towards what we do, is something along the lines of:

"Having the core of an idea is one thing. Developing it to the point that it becomes a platform that changes the world in which it lives is another, and you're going to be willing to pay proportionately to how big you think your idea is worth."

Have you been approached by these business type entrepreneurs (with no technical/developer's knowledge) with such a proposal and how do you react to them?

答:
The head of a computer science department recently wrote this article about business majors who would call-in to ask if a programmer would join their projects. He writes that the value of a product comes from its execution, not just the idea.

Another article also mentions that the execution is what matters and that an "ideas guy" is really just deadweight to a business that isn't making any sales.

The best bet is to tell the non-programmer that if he's serious about building his great idea, he should:

Approach potential customers with the idea -- if he doesn't know who they are, then he can't get revenue anyway.

Get them to sign a non-binding letter of interest to raise capital -- if they won't sign, then they aren't really interested.

Pay developers the market rate to build the product -- if he can't convince developers to take less than the market rate, then his idea really isn't cutting edge.


答:
One thing you can do to help the situation is take a good look at ways to shorten the development cycle.

In the case where a developer is waiting on a feature from another developer, is there a way that a portion of the first developers work can go through review and integration prior to the entire feature to free up the block?

Are there ways to break features up into smaller units of work to keep the integration cycle going?

Also, how long does the integration take?  If there's a long turn around on a build or integration, that can slow the entire queue.  See if there's anything that you can do to speed up the build time so that the queues are freed up faster.

Title: Developers blocked by waiting on code to merge from another branch using GitFlow

Body:
Our team just made the switch from FogBugz & Kiln/Mercurial to Jira & Stash/Git. We are using the Git Flow model for branching, adding subtask branches off of feature branches (relating to Jira subtasks of Jira features). We are using Stash to assign a reviewer when we create a pull request to merge back into the parent branch (usually develop but for subtasks back into the feature branch).

The problem we're finding is that even with the best planning and breakdown of feature cases, when multiple developers are working together on the same feature, say on the front-end and back-end, if they are working on interdependent code that is in separate branches one developer ends up blocking the other.

We've tried pulling between each others' branches as we develop. We've also tried creating local integration branches each developer can pull from multiple branches to test the integration as they develop. Finally, and this seems to work possibly the best for us so far, though with a bit more overhead, we have tried creating an integration branch off of the feature branch right off the bat. When a subtask branch (off of the feature branch) is ready for a pull request and code review, we also manually merge those change sets into this feature integration branch. Then all interested developers are able to pull from that integration branch into other dependent subtask branches. This prevents anyone from waiting for any branch they are dependent upon to pass code review.

I know this isn't necessarily a Git issue - it has to do with working on interdependent code in multiple branches, mixed with our own work process and culture. If we didn't have the strict code-review policy for develop (true integration branch) then developer 1 could merge to develop for developer 2 to pull from. Another complication is that we are also required to do some preliminary testing as part of the code review process before handing the feature off to QA.This means that even if front-end developer 1 is pulling directly from back-end developer 2's branch as they go, if back-end developer 2 finishes and his/her pull request is sitting in code review for a week, then front-end developer 2 technically can't create his pull request/code review because his/her code reviewer can't test because back-end developer 2's code hasn't been merged into develop yet.

Bottom line is we're finding ourselves in a much more serial rather than parallel approach in these instance, depending on which route we go, and would like to find a process to use to avoid this.

Last thing I'll mention is we realize by sharing code across branches that haven't been code reviewed and finalized yet we are in essence using the beta code of others. To a certain extent I don't think we can avoid that and are willing to accept that to a degree.


问:
Best practice to collect information from child objects
I'm regularly facing following pattern:

```<code>public abstract class BaseItem
{
    BaseItem[] children;

    // ...

    public void DoSomethingWithStuff()
    {
        StuffCollection collection = new StuffCollection();
        foreach(child c : children) c.AddRequiredStuff(collection);
        // do something with the collection ...
    }

    public abstract void AddRequiredStuff(StuffCollection collection);
}

public class ConcreteItem : BaseItem
{
    // ...

    public override void AddRequiredStuff(StuffCollection collection)
    {
        Stuff stuff;
        // ...
        collection.Add(stuff);
    }
}
</code>```

Where I would prefer something like this, for better information hiding:

```<code>public abstract class BaseItem
{
    BaseItem[] children;

    // ...

    public void DoSomethingWithStuff()
    {
        StuffCollection collection = new StuffCollection();
        foreach(child c : children) collection.AddRange(c.RequiredStuff());
        // do something with the collection ...
    }

    public abstract StuffCollection RequiredStuff();
}

public class ConcreteItem : BaseItem
{
    // ...

    public override StuffCollection RequiredStuff()
    {
        StuffCollection stuffCollection;

        Stuff stuff;
        // ...
        stuffCollection.Add(stuff);

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

What are pros and cons of each solution?

For me, giving the implementation access to parent's information is some how disconcerting. On the other hand, initializing a new list, just to collect the items is a useless overhead ...

What is the better design? How would it change, if DoSomethingWithStuff wouldn't be part of BaseItem but a third class?

PS: there might be missing semicolons, or typos; sorry for that! The above code is not meant to be executed, but just for illustration.

答:
initializing a new list, just to collect the items is a useless overhead

instantiate 2 class-level collections, once. The first is for the cumulative AddStuff() and the other is to pass to the child - and is reused.

```<code>public abstract class BaseItem
{
    BaseItem[] children;
    StuffCollection masterCollection;
    StuffCollection transferCollection;

    // ...

    public void DoSomethingWithStuff()
    {
        masterCollection = masterCollection?? new StuffCollection();
        transferCollection = transferCollection?? new StuffCollection();

        transferCollection.Clear();

        foreach(child c : children) {
            c.RequiredStuff(transferCollection);
            masterCollection.AddRange(transferCollection);
            transferCollection.Clear();
        }

        // do something with the collection ...
    }

    public abstract void RequiredStuff(StuffCollection aTransferCollection);
}

public class ConcreteItem : BaseItem
{
    // ...

    public override void RequiredStuff(StuffCollection collector )
    {
        Stuff stuff;
        // ...
        collector.Add(stuff);
    }
}
</code>```

Body:
initializing a new list, just to collect the items is a useless overhead

instantiate 2 class-level collections, once. The first is for the cumulative AddStuff() and the other is to pass to the child - and is reused.

public abstract class BaseItem
{
    BaseItem[] children;
    StuffCollection masterCollection;
    StuffCollection transferCollection;

    // ...

    public void DoSomethingWithStuff()
    {
        masterCollection = masterCollection?? new StuffCollection();
        transferCollection = transferCollection?? new StuffCollection();

        transferCollection.Clear();

        foreach(child c : children) {
            c.RequiredStuff(transferCollection);
            masterCollection.AddRange(transferCollection);
            transferCollection.Clear();
        }

        // do something with the collection ...
    }

    public abstract void RequiredStuff(StuffCollection aTransferCollection);
}

public class ConcreteItem : BaseItem
{
    // ...

    public override void RequiredStuff(StuffCollection collector )
    {
        Stuff stuff;
        // ...
        collector.Add(stuff);
    }
}


问:
Does it make sense to implement OAuth for a 2 party system?
I'm under the impression that OAuth is for authentication between three parties. Does it make sense to implement OAuth in a context where there is just a client and server.

We have a server, and a client (HTML/javascript). Currently we authenticate via the normal "post credentials to server, get a cookie, use cookie to authenticate all subsequent requests" method. Will implementing OAuth be a benefit in this situation?

答:
Oauth supports different Grant Types for the differing communications you're asking about.

Here is an example in a PHP library , of a  different grant type or two:

Client Credentials Grant Type Trusted Clients and UnTrusted Clients

The Client Credentials grant type is used when the client is requesting access to protected resources under its control (i.e. there is no third party).

```<code># using HTTP Basic Authentication
$ curl -u TestClient:TestSecret https://api.mysite.com/token -d 'grant_type=client_credentials'

# using POST Body
$ curl https://api.mysite.com/token -d 'grant_type=client_credentials&client_id=TestClient&client_secret=TestSecret'
</code>```

You'd get back an access token (like your cookie) and use that on all subsequent calls.

Implicit Grant Type

The Implicit grant type is similar to the Authorization Code grant type in that it is used to request access to protected resources on behalf of another user (i.e. a 3rd party). It is optimized for public clients, such as those implemented in javascript or on mobile devices, where client credentials cannot be stored.

```<code>https://api.mysite.com/authorize?response_type=token&client_id=TestClient&redirect_uri=https://myredirecturi.com/cb
</code>```

Source : http://bshaffer.github.io/oauth2-server-php-docs/grant-types/client-credentials/

Body:
Oauth supports different Grant Types for the differing communications you're asking about.

Here is an example in a PHP library , of a  different grant type or two:

Client Credentials Grant Type Trusted Clients and UnTrusted Clients

The Client Credentials grant type is used when the client is requesting access to protected resources under its control (i.e. there is no third party).

# using HTTP Basic Authentication
$ curl -u TestClient:TestSecret https://api.mysite.com/token -d 'grant_type=client_credentials'

# using POST Body
$ curl https://api.mysite.com/token -d 'grant_type=client_credentials&client_id=TestClient&client_secret=TestSecret'

You'd get back an access token (like your cookie) and use that on all subsequent calls.

Implicit Grant Type

The Implicit grant type is similar to the Authorization Code grant type in that it is used to request access to protected resources on behalf of another user (i.e. a 3rd party). It is optimized for public clients, such as those implemented in javascript or on mobile devices, where client credentials cannot be stored.

https://api.mysite.com/authorize?response_type=token&client_id=TestClient&redirect_uri=https://myredirecturi.com/cb

Source : http://bshaffer.github.io/oauth2-server-php-docs/grant-types/client-credentials/


问:
Fiction that includes BASIC programs
Back in what must've been the mid-80s, when every microcomputer included BASIC and Choose Your Own Adventure Books were really popular, there were some novels that had BASIC programs listed in the text, for you to type in and further enjoy.

For example, as I recall, in one of these books, the adventurers were infiltrating an undersea base (and eventually wiped the bad guy's data storage [I do believe it was a hard drive, even though they were uncommon then]).  One of the programs involved a game were you piloted a submarine and had to avoid or shoot sharks.  The code was in BASIC; minor changes (such as 'CLS' -> 'HOME') had to be made for your specific computer, and it used good old 40-column text-mode to display the action.  IIRC, the plot never depended upon the programs.

My question is, does anyone else recall these sorts of books?  Do you know any titles that I could look for, or of any online?  I am toying with the idea of writing a story like this (no, not in BASIC!), and would really like to see how it was done, back in the day.

答: Read Gateway by Fred Pohl.  A good part of the novel is conversations between the protagonist and his therapist, the therapist being a very sophisticated program.  Every so often, there will be a page in the book that is some sort of BASIC-ish computer code that, if you're a techie and read it, it gives a bit of insight on how the AI therapist is thinking.</p>

Title: Fiction that includes BASIC programs


答:
I am going to start by assuming that you know how to create a grid with X indices 0 to xmax and Y indices 0 to ymax.

If the bounds of your indices are xlower to xupper and ylower to yupper, then you have to map indices in this range to indices in the first range.

If indices in the first range are x1 and y1, and the indices in the second range are x2 and y2, then:

```<code>x1 = x2 - xlower;
y1 = y2 - ylower;
</code>```

Now you have indices that can be used in a regular grid.

This sounds so simple, I am wondering whether I missed some important details.

Title: Data structure for grid with negative indeces

Body:
Sorry if this is an insultingly obvious concept, but it's something I haven't done before and I've been unable to find any material discussing the best way to approach it.

I'm wondering what's the best data structure for holding a 2D grid of unknown size. The grid has integer coordinates (x,y), and will have negative indices in both directions.

So, what is the best way to hold this grid? I'm programming in c# currently, so I can't have negative array indices. My initial thought was to have class with 4 separate arrays for (+x,+y),(+x,-y),(-x,+y), and (-x,-y). This seems to be a valid way to implement the grid, but it does seem like I'm over-engineering the solution, and array resizing will be a headache.

Another idea was to keep track of the center-point of the array and set that as the topological (0,0), however I would have the issue of having to do a shift to every element of the grid when repeatedly adding to the top-left of the grid, which would be similar to grid resizing though in all likelihood more frequent.

Thoughts?

Body:
I am going to start by assuming that you know how to create a grid with X indices 0 to xmax and Y indices 0 to ymax.

If the bounds of your indices are xlower to xupper and ylower to yupper, then you have to map indices in this range to indices in the first range.

If indices in the first range are x1 and y1, and the indices in the second range are x2 and y2, then:

x1 = x2 - xlower;
y1 = y2 - ylower;

Now you have indices that can be used in a regular grid.

This sounds so simple, I am wondering whether I missed some important details.