问:
Should we create classes just to group properties
I am designing a bit of software that will integrate with our enterprise system using web services. We are dealing with work orders that are needed to maintain equipment.

We have a bit of a disagreement in regards to the structure of the contract. There are two methods on my side, I would like a single work order class with all properties related to the work order in it.

example (simplified)

```<code>WO - class
  Number - property
  Description - property
  WarrantyStatus - property
  WarrantySettlementDate - property
  LabourSteps<LabourStep>[] - list property
  Children<WO>[] - list property
</code>```

On their side, they want to create a work order class, but for each logical group of data,   they want to create another class to wrap the properties.

example (simplified)

```<code>WO - class
  WOHeader - class
    Number - property
    Description - property
  Warranty - class
    WarrantyStatus - property
    WarrantySettlementDate - property
  LabourSteps<LabourStep>[] - list property
  Children<WO>[] - list property
</code>```

Now they will have approx 8 classes in the full definition that they want to create all with a few properties in each. This seems a bit over the top to me and has a bit of a code smell or anti pattern feel to it.

For my example, I have two classes, WO and LabourStep.

They have 4 classes for the same thing WO,WOHeader,Warranty,LabourStep. There will only ever be one WOHeader per WO and the same for Warranty.

My one seems far simpler to manage changes (add a new property to WO and thats it), but is less human readable.
On their side, The structure is a little more easier to read by a human, but it feel like its pushing a logical view onto the contract the doesn't really belong. And to add a new property potentially requires a modification to the WO and the creation of a new class if a new logical group was added. These extra classes are only there to group properties.

What is the right way to go?

======EDIT==========

Frank - I completely agree with your thoughts and it is the way I approach my development. Except in this case, the third party monolithic enterprise system we are integrating with has been written in a very generic way to try and cater for as many businesses as possible. The data is spread across three tables in a one to one mapping with the majority in one table. There is barely any validation. There is no concept of a "Warranty" object/thing in that system. Its just 3 properties against a WO. All the web service will do is act like a data store, with the WO persisted as a whole. e.g. getWO() updateWO() createWO(). There will never be get/updateWarranty() methods. It's all just one blob of data to read/persist.

On our side, we never use the result directly from web services even if they are our own. We convert them into proper models and then use those. To us a data contract is very different to a model. There is no business logic in the data contract, its purely a container to get data from one part of the system to another without closely coupling them. That means we can easily change to persist to a database instead of a web service and all its needs to do is match the interface of the web service. This also allows us to modify our own models which may even include results from multiple web services without having to worry about being restricted to or changing the format of the data contracts.

So when I think in those terms, Having the data contracts split into WOHeader or WOWarranty classes just doesn't make any sense. It will never used in that way, not even by them. Its just there for a nice logical group of properties that mean nothing by themselves. A region block around those properties would have the same net effect. Labour steps and equipment details however, make a lot of sense to be in separate classes as they are separate entities and not just properties of work orders.

答:
To be honest, your approach is more of a code smell to me than theirs. The point of OO is that you can break down your "big" work order thingy into smaller, and better manageable, parts.

I do not say that the way your colleagues break things down is "correct", or the "best" way - as that requires a lot more knowledge about the problem domain. However, I do already agree from the list of attributes you have given that your work order class is too large. It's prime to become a God-class very soon.

Let's consider one example in more detail: Warranty. You may be thinking "warranty only applies to our work orders, so we cannot reuse it anywhere else" and this may be true, or not. What will be true either way is that your WO class will have methods that specifically deal only with the warranty attributes and are independent of a work order in all but their placement inside that class.

With your approach, you will get a class that has loads of methods, which do not have much in common. By simply recognizing warranty as its own thing/class, you end up with a Warranty class that is very focused, extremely easy to understand and maintain and all that at a very small cost - you just need a Warranty attribute in your WO.

A follow-up question that you or your team may ask next is whether you want to refactor out an interface as well. Is Warranty really limited to work orders, or is it occurring somewhere else too? Do you really need to expose the Warranty class's methods to clients of the WO class? etc. etc.

And a final side note: When you start with your idea of the WO class, then moving towards your colleague's version is a simple matter of refactoring (extract class) and if it shows that you went the wrong way with that you can go back again just as well (inline class). Simply keep in mind, that no design decision will ever survive the test of time. It all should remain fluent and provide you with the ability to make such refactorings, so that you can adapt the design when next requirement (change) comes around the corner.


问:
Can *any* program task be expressed without state?
This is a theoretical question, but after many years of programming in what I now realize is "normal" imperative technique, using C++ mainly, I've discovered this other world of functional programming, which I stumbled upon accidentally while casually learning JavaScript.

This has led me to wonder if you could technically replace any complete state-oriented program with a different implementation that is purely functional and without state?

It's an intriguing idea and I must admit that there is a clarity and elegance in functional programming that has really blown my mind.

答:
Short answer: yes. According to Wikipedia, the equivalence of lambda calculus to Turing machines as an universal model of computation was shown 1937 by Alan Turing. The computational model of a Turing machine is what you typically have in mind when talking about imperative or stateful programming, and lambda calculus is a mathematically formalization of "pure functional programming".

It is conjected that every effective model of computation is able to carry out the same calculations as a Turing machine, and vice versa. This is called Church-Turing thesis. This conjection, however, cannot be proven, because of the more or less intuitive term "effective model of computation" (perhaps someone will invent a new model in the future?)

ContentLicense: CC BY-SA 3.0


答:
In whatever dynamic system, the "state" is what make your present to be influenced by your past or future (the arrow of time is not a mathematical issue, just a physical constrain).

Whether you have something to "remember" or that depends on what you did, you have a state.

A system with no state is not "dynamic": it is just a combinatorial function. That may not have a state, but -to produce different results- need a state to be somehow supplied.

Now, depending on the computational model you refer to, a state can be represented explicitly (in the form of variable) or implicitly (in the form of "return addresses").

when you do fna(fnb(x)) you are giving a state to fnb that in turn will produce a state for fna. This is due to the fact that x exist before fnb is called (so, it comes from it's own "past").

It's not a matter of "state exisit" or "state don't exist". It's a mater of "I care" or "I don't".

Title: Can *any* program task be expressed without state?

Body:
This is a theoretical question, but after many years of programming in what I now realize is "normal" imperative technique, using C++ mainly, I've discovered this other world of functional programming, which I stumbled upon accidentally while casually learning JavaScript.

This has led me to wonder if you could technically replace any complete state-oriented program with a different implementation that is purely functional and without state?

It's an intriguing idea and I must admit that there is a clarity and elegance in functional programming that has really blown my mind.


问:
Why would one prefer C# (ASP.NET MVC) or Java (JSP) instead of PHP for web applications/projects
I'm wondering, why would one (consider it not just a single developer, but a company) prefer C# or Java for web applications? What's their considerations regarding the question. I mean, a company, has an assignment to make a web-site for customer, or online game, or web-portal, how does the project management or/and the software architect (and the core team) came to the conclusion - "we will do it in ASP.NET MVC" for example? I know it's specific, but what are the common reasons? Especially, why instead of PHP? As PHP is purely designed for web. Maybe if it is for a single web-site, there are much CMS's where the customer is familiar with, but let's say PHP also has a lot of CMS's, and most of the ASP.NET ones are as spaghetti as wordpress is. Also, as I'm aware, the common webserver is a windows webserver, back in the days I started with computers, everyone was saying the administration in windows is worse than in unix-based platforms.

I really don't see the point. For me is just like waste of resources, I think you will need twice better machine running on Windows for the same achievements. C# for desktop - thumbs up, but for web - why?

Same for JSP. Its common server is cross platform, so no need of Windows, but still isn't it also waste of resources? And the question is the same as the paragraph - how a company would decide to use JSP.

The question was raised, because of lots of the sites rising in ASP.NET nowadays. To be honest, I have seen too few sites in JSP.

P.S.: Sorry, I didn't find the relevant tag for this, so I tagged the languages and the involved stuff

答:
For the employment opportunities.

ASP.NET/Java is much more common in business environments, and people who know or even simply have the right buzzword on their CV, will get a pick of many jobs. PHP jobs are out there but are rare in comparison.

The technical aspects of both can be debated forever, and effectively doesn't matter - you can code up a website in any of them. Many people with that luxury will choose the technology they're most comfortable with, or want to learn - hence the website written in Ruby when it was the coolest, or node.js when everyone was raving about it.


问:
From an execution perspective is an interpreter the same as the JVM / or the .net Framework
I've recently started two introductory level courses - one using Python, the other Java.

I've read the answers to this Question but still have difficulty understanding how each ends up with machine code and what the main differences between the two models are:

Is an interpreter doing the same job as something like the JVM, just without the
byte-code?

For python is the interpreter taking the high-level code
and translating it into machine code?

The Java virtual machine needs to be installed on a machine for a java program to run on it - is it similar for python - if the interpreter is installed on the target machine then the python program will run?

Is the JVM (& .net framework) effectively byte-code interpreters?

答:
There is a technical point of view:

a compiler is a processus which transforms a view of a program into another view, lowering the level of abstraction

a interpreter is a processus which execute a program, possibly first transforming the source in another view, but that one will not have a significantly lower level of abstraction.

There is a user point of view:

a compiler just transfor the program, it won't be executed there until another step

an interpreter will execute the program.

There is some confusion lying in the difference between the two.

A interpreter as a user see it sometimes use compilation techniques.  Upfront, compiling the source program in a intermediate representation which is of a significantly lower level of abstraction than the source before interpreting it, maybe even going down to machine level (load and go compiler).  Sometimes detecting heavily used code and compiling just that part or applying special optimization (just in time compilation).

Compilers don't have to go to machine language.  C is a popular target for experimental languages.  Another popular choice is a more or less machine like intermediate code which has to be interpreted after by a virtual machine, sometimes exposing the byte code as such, sometimes bundling the virtual machine with the byte code in one executable (it was the way one of the most popular and widespread Pascal implementation worked).

The virtual machine is itself an interpreter, but may apply compilation techniques as written above.

Compilers sometimes generate a more or less machine like description and delegates the true machine code generations to the linker.  That generation may also be done at installation time (AS/400, and successors whose name I can't remember in the ?Series soup, is the longest during system I know which is using that method).

Now your questions:

Is an interpreter doing the same job as something like the JVM, just without the byte-code?

Sometimes yes, sometimes it is the bundling of the java compiler and the JVM.

For python is the interpreter taking the high-level code and translating it into machine code?

There are several Python interpreters and systems.  I don't think the most popular one goes down to machine code.

The Java virtual machine needs to be installed on a machine for a java program to run on it - is it similar for python - if the interpreter is installed on the target machine then the python program will run?

The most popular Python implementation is an interpreter which need to be installed.

Is the JVM (& .net framework) effectively byte-code interpreters?

Yes, what I called "user level interpreters", they may apply true compilation techniques to offer better performance.


问:
Is QA or testing a lot of overhead or not utilized properly?
From my experiences in software development (Eg. Waterfall ) I see it that most of the times it is the development team that sweats it out with the BA folk to get requirement clarity. The development folks then slog it out to meet deliverable deadlines.

Where is the QA - they might be free - but will only hitch onto the bandwagon after the code is delivered.

Then starts a slew of communication regarding what is a defect and what is a requirement change / clarity needed. From QA perspective - log a defect / bug / issue - and then its the development team responsibility to go figure it out.

Clearly this is problematic and affects my opinion of the role and value that QA brings to the table in the Waterfall model.

The question is if Agile is actually geared towards reducing this 'waste' by getting testing involved early in the development so that issues get eliminated at the start?  If so then what aspects of Agile help solve some of the above problems I have experienced?

答:
Yes, agile is in part "geared towards reducing this 'waste' - getting testing involved early in the development so that issues get eliminated at the start?"

The role of QA should be one where they are equal collaborators with developers and the business side of software development. They are the advocate for the customer, the one who looks at the software from the user's perspective to make sure it matches their definition of quality.

When you tack on QA activities to the end of a development cycle, it's too late for them to have a significant impact on the product. At the end of the cycle, the best they can do is identify existing bugs. When you move them earlier in the cycle, they can be instrumental in preventing bugs. That is the true value that QA can bring to the table, because a bug found in design or early in development is considerably cheaper to fix than one found at the end of the development cycle.

The difference between QA's role when they are included only at the end of a waterfall cycle vs agile or any other methodology that involves QA early in the cycle is one of defect detection versus detect prevention.


问:
Branching Strategy for Test Environment
We will be starting a new project this month. The project will be 1 year and production deployment will only occur towards the end of the project.

We will be doing iterative development (1 month per iteration), so this means we will drop features to Test environment at the end of each iteration for QA testing.

Our branching strategy is:

Trunk - All development will happen on trunk.

Feature Branch -  Branches off trunk will be created on a per need basis for development of large features which could potentially be breaking if done on trunk

QA Release Branches - At the end of each iteration, a branch of trunk will be created. This branch (which includes a version number) will be released to Test environment. All critical and blocking bugs found in this version will be fixed on this branch and fixes will have to be merged to trunk. Non-critical/trivial bugs will not be addressed on the QA release branch and will only be fixed in trunk since the QA release branch will be thrown away after the end of the next iteration where a new release branch will be created off trunk.

Production Branch - this will be the latest QA release branch at the end of the project. This will be tagged and all production bug fixes will be on this branch and merged to trunk.

Is this a correct branching strategy? Is there anything else that we've missed to consider?

We're using SVN.

答:
It sounds fine, I'd worry that the QA branch is relatively short-lived, and I would do all fixes related to that release on that branch so they get merged to trunk on 1 go rather than fixing them on trunk as they are found.

If you fix the trivial bugs on the QA branch then the testers can see and mark them off quickly. I assume they get daily/weekly builds off the QA branch, so trivial bugs shouldn't be time consuming at all if done on QA. (I speak from experience where the tiniest of tiny bugs can have a knock-on effect that causes major grief elsewhere)

One potential improvement I could mention is to do feature development on a branch - ie move the work you usually do on trunk to a dedicated branch instead. Then trunk will only have merges committed to it, which can help in tracking changes that are complete.

Title: Branching Strategy for Test Environment


答:
Your branching strategy strikes me as quite reasonable.  We have pursued a similar strategy at my company and it has worked well with us.

One slight difference is that we do pre-release QA fixes on the trunk because it prevents us from having to merge back and we haven't really had a problem with developing new features while fixing defects. This does give QA a bit more of a moving target in terms of what they are testing, so how workable this is depends on how tightly integrated QA is with the dev team. It works well for us because we have a pretty integrated team and because we are on a fast iteration schedule.  We do have a separate branch for each release so that we can patch the production environment while still building new features on the trunk, but that doesn't seem like it will be necessary for you until later when you start releasing beyond QA.

There are a couple of additional recommendations that I would make:

Encourage frequent check-ins.  This is especially useful if you have many people developing on the trunk.  It will prevent developers from getting out of synch with what others are doing and reduce the potential for conflicts.  Make sure that there is explicit guidance about when it is okay to commit and how often developers should be getting from the trunk.  Frequent commits shouldn't be a problem given that you are trying to isolate breaking changes to feature branches.

Institute a continuous integration process.  This further ensures that you don't end up with huge integration headaches at the end of an iteration, provides notification if something has broken, and let's you automate more of your QA both through automated unit/acceptance tests and potentially through static analysis/code inspection tools. I have found CI provides great "bang for the buck" as an investment in the configuration management process.  Note, there is a tension between CI and using feature branches heavily because the branches essentially let you keep the trunk clean, pass your tests in CI, but still create conflicts/issues in the branches. Frequent merges back into the trunk can help with this as can running CI in the branch and pulling from the trunk frequently, but a proliferation of branches will start to defeat the CI process either by complicating its administration, or simply ignoring it in the branches.

Title: Branching Strategy for Test Environment

Body:
We will be starting a new project this month. The project will be 1 year and production deployment will only occur towards the end of the project.

We will be doing iterative development (1 month per iteration), so this means we will drop features to Test environment at the end of each iteration for QA testing.

Our branching strategy is:

Trunk - All development will happen on trunk.

Feature Branch -  Branches off trunk will be created on a per need basis for development of large features which could potentially be breaking if done on trunk

QA Release Branches - At the end of each iteration, a branch of trunk will be created. This branch (which includes a version number) will be released to Test environment. All critical and blocking bugs found in this version will be fixed on this branch and fixes will have to be merged to trunk. Non-critical/trivial bugs will not be addressed on the QA release branch and will only be fixed in trunk since the QA release branch will be thrown away after the end of the next iteration where a new release branch will be created off trunk.

Production Branch - this will be the latest QA release branch at the end of the project. This will be tagged and all production bug fixes will be on this branch and merged to trunk.

Is this a correct branching strategy? Is there anything else that we've missed to consider?

We're using SVN.


问:
How is multi-threading different in a Java based Web Application vs Stand-alone Java Application
I am fairly new to Java and my experience is limited to Web Based Applications running on a Web Container (Jboss in my case).

Am I correct in saying that for Web Applications the web container takes care of multi-threading? If so, can I introduce new treads in a Web Based applications? Is there any advantage in doing so and in what scenario one would need to do that?

答:
In response to your question:

How is multi-threading different in a Java based Web Application vs Stand-alone Java Application

It is not different. Usually the software web applications are built upon will provide some multi-threading already by making each new request a thread. By you can use/create threads just as you would any other application.

Indeed multi-threading can give you drastic performance increases if you use it right. For I/O intensive tasks such as network access and disk drive access the performance increase is nearly always guaranteed. For computationally intensive tasks you should stick to the rule of one thread per core in the server. For example if your core has an i7 processor you should stick to 7 threads to do computational tasks.

In response to your question:

Is there any advantage in doing so and in what scenario one would need to do that?

Michael Borgwart says you should not do this to improve computational speed. I disagree, as this article suggests multi-threading can help provide responsiveness when users need a computationally heavy task done. In plain English, users wont have to wait as long to complete computationally heavy tasks with multi-threading.

If you intend to use threads a lot, I suggest use of a thread pool. This will reduce the overhead of creating threads.


问:
Managing Production Issues during a Scrum Sprint
The question of managing bugs in production has been a large feature in my mind of late. Sprint's are not meant to have any items added into them, but for critical bugs, this is simply unavoidable.

How does one go about managing this break in the sprint? Do you simply give a sprint a percentage "allowance" of time, thus only filling say 80% of the schedule with sprint items "just in case"?

答:
If this is critical, you must handle it.

To measure its impact on the sprint, you must log it.

Look at this information radiator:

There is a part called "Unplanned items". Put your critical bug there. As you see there is the inverse with "Next" part where you put more user stories than planned in case you complete the sprint faster.

You will talk about it in the sprint review and/or the retrospective. The objective is to find how to limit them, and also adjust your velocity accordingly.

ContentLicense: CC BY-SA 2.5


问:
OO way to gather together data from multiple objects without getters
I'm writing a system that has a number of objects with data in them. For example one object has a user name attribute, another has a date, another shopping cart item etc.

I'm making an object that generates a MD5 hash based on a concatenated string of these values. So for example md5(username + date + special_number + cart_id).

The way I was going to do this was pass the md5_generator object to each other the other objects in turn allowing them to call an add_x method (eg add_username) on the generator to add their specific piece of data. This avoids pulling the data out of each object, which I want to avoid.

I'm wondering if this is the best idea or if there is some simpler OO pattern I'm missing?

答:
You could just have an add_data(key, data) on the hash generator object to generically allow any data to be added:

```<code>class HashGenerator(...):
    def __init__(self):
        self.data = []

    def add_data(self, key, data):
        self.data.append((key, data))

    def calc_hash(self):
        self.data.sort()
        return hashlib.md5("|".join(data for _key, data in self.data))
</code>```

which in turn the data objects are passed and use:

```<code>class UserNameObject(...):
    def inject_data(self, hash_generator):
        hash_generator.add_data('username', self.username)
</code>```

Or, if you'd prefer the data objects to be unaware of the hash generator you could do (which would technically be better):

```<code>class UserNameObject(...):
    def get_hash_tuple(self):
        return ('username', self.username)
</code>```

Though, I would recommend using SHA1 as opposed to MD5 because it's more secure but depending on the purpose of the hash, the best algorithm could vary.

OwnerDisplayName: Cormac Mulhall

Body:
You could just have an add_data(key, data) on the hash generator object to generically allow any data to be added:

class HashGenerator(...):
    def __init__(self):
        self.data = []

    def add_data(self, key, data):
        self.data.append((key, data))

    def calc_hash(self):
        self.data.sort()
        return hashlib.md5("|".join(data for _key, data in self.data))

which in turn the data objects are passed and use:

class UserNameObject(...):
    def inject_data(self, hash_generator):
        hash_generator.add_data('username', self.username)

Or, if you'd prefer the data objects to be unaware of the hash generator you could do (which would technically be better):

class UserNameObject(...):
    def get_hash_tuple(self):
        return ('username', self.username)

Though, I would recommend using SHA1 as opposed to MD5 because it's more secure but depending on the purpose of the hash, the best algorithm could vary.

OwnerDisplayName: cpburnz


答:
You could use a reflection to find out which properties each object has and dynamically add those to the generator.

In pseudo code:

```<code>class HashGenerator {
   String generate(Object o) {
      String combined = "";
      for each( property in o ) {
          combined += o[property];
      }

      return md5(combined);
   }
}
</code>```

Depending on the programming language there will be diffent ways of getting the property in o to work.

Title: OO way to gather together data from multiple objects without getters

Body:
I'm writing a system that has a number of objects with data in them. For example one object has a user name attribute, another has a date, another shopping cart item etc.

I'm making an object that generates a MD5 hash based on a concatenated string of these values. So for example md5(username + date + special_number + cart_id).

The way I was going to do this was pass the md5_generator object to each other the other objects in turn allowing them to call an add_x method (eg add_username) on the generator to add their specific piece of data. This avoids pulling the data out of each object, which I want to avoid.

I'm wondering if this is the best idea or if there is some simpler OO pattern I'm missing?

Body:
You could use a reflection to find out which properties each object has and dynamically add those to the generator.

In pseudo code:

class HashGenerator {
   String generate(Object o) {
      String combined = "";
      for each( property in o ) {
          combined += o[property];
      }

      return md5(combined);
   }
}

Depending on the programming language there will be diffent ways of getting the property in o to work.

OwnerDisplayName: Tobias


问:
How to ask management to increase the number of programmers in the team without sounding incompetent
I am currently working for a small-medium sized company (~50 employees) as the sole IT staff.

Recently, we are on track to replace one expensive yet critical legacy system in favor of an application I am currently working on during my free time at work. However, its been very busy lately with issues spawning left and right so the development of the application has been lagging a lot.

How do I ask a very thrifty management to hire more programmers to help me build the new application without sounding incompetent.

FYI. I do support of all our applications, setup and administration of the network and servers and in-house application development.

EDIT 1: Nature of the Critical Legacy System for added information

The Legacy System is the center of our operations. Basically, all our reports, notifications and data are being handled or are passing through this system. We want to replace it for a few reasons:

We are bleeding money paying for support that is rarely helpful (really terrible support) plus licensing cost.

Ridiculous cost for adding new features (500$ to adjust the width of a column in a report)

System Design/Architecture problems that cause the system to be slow and unscalable (Other branches find the system unusable because of how slow it is when used outside of the Office LAN)

Its a program made with access '97. Need I say more? It still works but its like trying to cut something with a dull blade in terms of performance

答:
This is what we did in a similar situation. It's kinda scrum in a nutshell.

Gather the stakeholders (consumers of IT services, director level). Tell them, "I am spending X hours a week supporting the legacy system and doing my other tasks. At the rate of 40-X hours a week, I cannot deliver the replacement system before mm/dd/yy (you know, plus or minus). Beyond my salary, you will also spend $Y for maintenance of the legacy system during this time, and have to put up with its limitations. Is this what you want, or shall we re-prioritize or add staff?"

If they reprioritize, you win. If they add staff, you win. If they stay the course, they cannot blame you because they made the decision, and you at least don't lose. They have had to balance their thrift against the cost, instead of pretending they can have everything, and being angry that you didn't perform the miracle. They may choose thrift. You'll have to accept their decision, but you can feel better about making slow progress, because it's what the company has decided. Often there are stakeholders who are more excited about the new tool, who will do your arguing for you, especially if other stakeholders are arguing against.


问:
How might one teach OO without referencing physical real-world objects?
I remember reading somewhere that the original concepts behind OO were to find a better architecture for handling the messaging of data between multiple systems in a way that protected the state of that data. Now that is probably a poor paraphrase, but it made me wonder if there is a way of teaching OO without the (Bike, Car, Person, etc.) object analogies, and that instead focuses on the messaging aspects. If you have articles, links, books, etc., that would be helpful.</p>

答:
If you are in a programming group get a few people together and start discussing how you would tell each other to do what you need the system to do. Literally take roles in the system (you can do this on your own by just playing each role, but it is easier with a group of people. Toys help if you are on your own). Focus on what each person is doing/will do, rather than on what data they have. Doing this with people helps this focus on messages and roles because people tend to remember what they are doing but not the data they have.

Take note of what you have to ask each other to do, and what information you need to do it. Be protective of your own data, if another programmer asks for your data for something say no and ask him why he needs it (helps data encapsulation).


问:
Preferred location for installing user guides, sample documents on Windows?
By default, the installer for my product copies files to the Users\Username\AppData\local\MyProduct directory (though the user can change this during installation, of course).

I want to bundle some other files with product - documentation, sample spreadsheets (it includes an Excel add-in) etc.  It doesn't seem appropriate to copy these additional files to AppData because it's a hidden folder that users shouldn't really muck about with.

I could, of course, create a new sub-folder in the user's Documents directory and stick the files in there but as I haven't asked their permission to do this it seems impolite.

So - any suggestions as to an easily accessible location to put these files in?

答:
I see 3 choices:

Plonk it on the Desktop & let the user move it wherever.
 It's simple, obvious, and only mildly annoying.

Create a "Docs" folder inside the folder that has your executable.
  It's also simple and there's the reassurance that everything will be deleted when you uninstall.

Put it in the Documents folder anyway.
 That's what everyone else does and in your case it actually makes sense to put them there.

I agree that Users\Username\AppData\local\MyProduct is not a very friendly location for files you want the user to access.

Whatever you do, you may wish to pop up a message telling the user what you've done.


答:
Help and associated documents can be installed into the same path/path structure that you use for your executable files.  If for no other reason, it makes it easier for your program to find them if you want to launch the help files from within your program.

To make it easier for end users to find your documents, make shortcuts in the program's start menu folder.  But you'll want the docs to be reachable from within your program, because many Win8 users (and frankly, many users all together) either dont have a start menu (Win8), or dont know how to use anything other than a desktop icon to launch a program.

Sample files are more of a 'it depends' topic.  It depends on what you are expecting people to do with the files.  I usually put them into the same directory structure as the executables.  But if sample files are meant to be edited and saved, you might want to put them in their own directory under My Documents.

Title: Preferred location for installing user guides, sample documents on Windows?

Body:
By default, the installer for my product copies files to the Users\Username\AppData\local\MyProduct directory (though the user can change this during installation, of course).

I want to bundle some other files with product - documentation, sample spreadsheets (it includes an Excel add-in) etc.  It doesn't seem appropriate to copy these additional files to AppData because it's a hidden folder that users shouldn't really muck about with.

I could, of course, create a new sub-folder in the user's Documents directory and stick the files in there but as I haven't asked their permission to do this it seems impolite.

So - any suggestions as to an easily accessible location to put these files in?


答:
Whatever you do DO NOT put them in AppData. Adobe does\did this for a long time (haven't looked in awhile but I'd assume they haven't wised up yet) and a huge AppData folder is a mess for system administrators to deal with. For example, if these documents add up to any size they will slow down roaming profiles to an excruciating pace. That is just one company and by now most shops have worked out a way to handle those particular files, if that became standard it would be impossible to manage.

I would say that the best way to handle this depends somewhat on whether or not these documents grow. If these are static files then place them in your Program Files folder. Then at some point during installation ask the user whether they would like the documentation placed in there documents, public documents or left alone. If they select an option then place a shortcut to the folder which has these in the appropriate location.


问:
Can the overuse of custom taglibs disrupt the outsourcing of html designers?
Yesterday me and a friend were talking about the overuse of custom taglibs.

We create taglibs for everything. We create taglibs in order to wrap jQuery UI elements (tabs, button, etc), and other plugins elements as well. We often wrap them together in a single component. We use taglibs in a point that we almost have no pure html within the body tag.

Our question is: is this a healthy habit? Imagine two situations:

1) We hire an html designer and have the cost of a month for him to learn all this stuff.

2) We want to outsource the html development but no company would get our taglib library to learn, OR it become more expensive.

We love taglibs as its been a lovely shortcut for javascipt development as we write it only once. What would be the best practices in this sense, and what would you suggest? We are looking for a future-proof solution (or an argument that agrees with ours).

答:
"We are looking for a future-proof solution"

I would suggest you look into Web Components. That, with little doubt, would be the direction client side development is headed and it would enable easy creation of resuable client side functionalities. Although the Web Components standardization process is still far from finished, you have a couple of libraries out there, that serves as poly-fills that allows the usage of the principle of Web Components across browsers.

Polymer.js (by Google) is an example of this. You also have Brick from Mozilla and React by Facebook.

Also some of the currently leading Javascript framework provide the same idea, although implemented via different mechanism. In AngularJs, you have Directives. In EmberJs you have Components. But the good news is that, at least these two, plan to move their implementation to the official specification once it becomes a formal standard. As stated in the documentation for Embers component and for AngularJs, as announced in the Polymer.js group.

All in all, I would advice you play with Polymer.js. If you want client side functionality to be so decoupled that it is possible to outsource it easily, why not just completely cut the reliance on JSP's, and have that tier implemented using the technology much fitted for it. Am sure a company focused on HTML/Client Side development won't have any problem getting up to speed with it. It is a familiar terrain :)

You might want to check this cool tutorial: Getting Started With Web Components and polymer.js


问:
OAuth alternative for a 2 party system
I'm writing a RESTful service (Java EE, Jersey) and a client application that communicates with it, and I wish to secure it and store any usernames & passwords dedicated in my own database.

I do not want the client to store the username and password locally, not in any form such as base-64 or other encoding at all, I rather have something like the OAuth2 authorization system, where the client app only stores a refresh & access tokens after the resource owner signed-in, but I do not need to provide access to 3rd party services.

Securing my service using Basic auth means the client app has to store the password and send it for each future request, so that's not what I need.

I'm aware that OAuth is intended for different situations, where there are more than just 2 parties involved (see other question).

as mentioned here https://blog.apigee.com/detail/when_to_use_oauth:
OAuth is the only realistic choice for a web application that itself uses another web application's API on behalf of the user. For instance, consider a web application that integrates with Twitter. (Perhaps it's a geolocation app like Foursquare that offers the ability to tweet where you are and what you're doing.)

So what is the correct standardized method to secure my RESTful service if I do not wish to re-invent the wheel and create my own auth method, and if "Basic" is not what I need because it forces me to store the credentials locally on the client, and OAuth is probably an overkill with it's 3rd party access nature.

P.S-
I do wish to provide users with an option to sign-in to my service using facebook or open-id, but that's another story I guess.

答:
I had a similar problem a couple years back, and I found this article to be incredibly helpful.

http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

The basic idea is to have the client and the server to have a shared secret. That shared secret is never communicated over the wire, but is used to create a token (HMAC) that verifies the request. The client does need to know the algorithm for creating the HMAC (can be provided via a client library) and a secret (similar to a password, but not a password).

In your question you mentioned that you don't want your client to have to store the password. This solution does require the client to look up the secret, so it may not meet your requirements; however, it does not require the client to authenticate or sign in to your service.

(On a side note, you mentioned storing passwords as base64. Never store passwords as base 64. Encoding is not the same thing as encryption.)

Title: OAuth alternative for a 2 party system


问:
Is it bad practice to check object types with an identifying member variable?
Preamble:
I am making a simple board game in C++, in which AI characters move around squares on the board. There are different types of squares, each inherited from an abstract class, each with different effects on the AI character. For example, some are shops where the character can buy stuff, others are workplaces where characters get money, etc.

Likewise, there are different AI characters (also inherited from an abstract class), which make different kind of decisions. Some work more than others, some eat more than others, etc.

The problem is that the AI character needs to know the square type in order to make a decision about what to do. At the moment checking the type using a type-name string as a member variable is the easiest solution, but it feels horribly inelegant and not very helpful when it comes to adding new types of squares and AI characters.

Question: Is it bad practice to check the type of an object by asking it for an identifier which is placed into its class for this purpose? Is it bad practice to use other methods of run time type identification such as dynamic_cast and typeinfo for purposes of controlling the flow of execution?

Example: Below the Square class (accessed through currentSquare() has a member function getType() which returns a string with the name of the type:

```<code>//Normal AI character
void decide() {
    if(currentSquare()->getType()=="HOME") {
        watchTV();
        sleep();
    }
    if(currentSquare()->getType()=="WORKPLACE") {
        work();
    }
}

//Party animal AI
void decide() {
    if(currentSquare()->getType()=="HOME") {
        moveTo(getGameBoard()->closestBar());
    }
    if(currentSquare()->getType()=="WORKPLACE") {
        sleep();
    }
}
</code>```

答:
I prefer to use enums rather than strings for situations like this, and the "check type" code should be written to exclude the unspecified cases.</p>

```<code>switch (currentSquare()->getType())
{ default: BUG("case not expected");
  case workplace: ...
    break;
  case home: ..
    break;
}
</code>```

Body:
I prefer to use enums rather than strings for situations like this, and the "check type" code should be written to exclude the unspecified cases.

switch (currentSquare()->getType())
{ default: BUG("case not expected");
  case workplace: ...
    break;
  case home: ..
    break;
}


问:
Can I bundle my JavaScript code with an MIT licensed code and keep my code unaffected from the MIT license?
Can I bundle my proprietary JavaScript code with MIT licensed libraries (e.g. JQuery, AngularJS) into the same file, distribute it via HTTP but disallow my users to use my own code as an MIT licensed code?

This way I could minimize the number of browser requests, and reduce errors due to network errors. I don't want to let my users copy, modify and reuse my own code outside of my website.

答:
Yes.  Just specify the terms of your license with the accompanying code.

The MIT license doesn't have any provisions in it that forces your code to be MIT licensed, nor does it prevent you from relicensing the MIT-licensed code in any way you see fit.


问:
What's wrong with this approach to CSS?
I have a static Jekyll website.

The website is constructed once, on my computer, and then sent to the server in the form of plain HTML, image, and CSS files, to be served by a regular HTTP server.

This construction process involves a template engine that has to glue various components together.

For example, this is the template for my posts and pages (the only other template I have is for the main page, which shares quite a lot with this one):

```<code><!DOCTYPE html>
<html>
    <head>
        {% include head.html %}
        <link rel="stylesheet" href="/css/main.css">
        {% if page.title == "Tautological Cascade" %}
            <title>Tautological Cascade</title>
        {% else %}
            <title>Tautological Cascade: {{ page.title }}</title>
        {% endif %}
    </head>

    <body>
        <div class="site" >
            {% include header.html %}
            {{ content }}
            {% include footer.html %}
        </div>
    </body>
</html>
</code>```

The most important part to notice here is the body section. It basically sandwiches a processed markdown file between two HTML files.

Currently, I only have one, main CSS file, which is used by ALL pages.

I find this approach a bit unpractical. Everything is defined in there, and it's getting messy. Couple that with my general ignorance of anything but the basic CSS, and you get something close to a nightmare.

My idea is this: inline CSS for all of these parts that I glue together.

So header.html would have its CSS in its file, footer.html would have its CSS, and the file that describes the content int its own.

Is this the correct solution to my problem? Is there something wrong with this approach?

答:
You have the right problem identified, but there's a better solution.

You're allowed to include as many CSS files as you need in your  tag.  So all you need to do is add an extra bit of logic up there to grab the appropriate CSS for a given page.

```<code><head>
    {% include head.html %}
    <link rel="stylesheet" href="/css/main.css">
    {% if page.css != "" %}
        <link rel="stylesheet" href="/css/{%page.css%}">
    {% endif %}
    {% if page.title == "Tautological Cascade" %}
        <title>Tautological Cascade</title>
    {% else %}
        <title>Tautological Cascade: {{ page.title }}</title>
    {% endif %}
</head>
</code>```

Then each page can define any special CSS it needs, separately from everything else. Just don't go too far in this direction, to the point that you're duplicating your styles between pages' specific .css files.

Title: What's wrong with this approach to CSS?

Body:
You have the right problem identified, but there's a better solution.

You're allowed to include as many CSS files as you need in your <head> tag.  So all you need to do is add an extra bit of logic up there to grab the appropriate CSS for a given page.

<head>
    {% include head.html %}
    <link rel="stylesheet" href="/css/main.css">
    {% if page.css != "" %}
        <link rel="stylesheet" href="/css/{%page.css%}">
    {% endif %}
    {% if page.title == "Tautological Cascade" %}
        <title>Tautological Cascade</title>
    {% else %}
        <title>Tautological Cascade: {{ page.title }}</title>
    {% endif %}
</head>

Then each page can define any special CSS it needs, separately from everything else. Just don't go too far in this direction, to the point that you're duplicating your styles between pages' specific .css files.


答:
As Amon pointed out, this is a good application for the visitor pattern.  Using it, your AI classes will end up looking something like this:

```<code>void decide(HomeSquare square);
void decide(WorkSquare square);
void decide(ShopSquare square);
</code>```

And your squares have an accept function that looks like:

```<code>void accept(AI ai)
{
    ai.decide(this);
}
</code>```

That lets you use inheritance to create appropriate defaults, or force every AI to implement certain decisions.  You can create an AI that behaves exactly like another one except at home, for example, without copying a bunch of code.  The compiler will point out where you forget something, and you don't have to cast all over the place.

Title: Is it bad practice to check object types with an identifying member variable?

Body:
Preamble:
I am making a simple board game in C++, in which AI characters move around squares on the board. There are different types of squares, each inherited from an abstract class, each with different effects on the AI character. For example, some are shops where the character can buy stuff, others are workplaces where characters get money, etc.

Likewise, there are different AI characters (also inherited from an abstract class), which make different kind of decisions. Some work more than others, some eat more than others, etc.

The problem is that the AI character needs to know the square type in order to make a decision about what to do. At the moment checking the type using a type-name string as a member variable is the easiest solution, but it feels horribly inelegant and not very helpful when it comes to adding new types of squares and AI characters.

Question: Is it bad practice to check the type of an object by asking it for an identifier which is placed into its class for this purpose? Is it bad practice to use other methods of run time type identification such as dynamic_cast and typeinfo for purposes of controlling the flow of execution?

Example: Below the Square class (accessed through currentSquare() has a member function getType() which returns a string with the name of the type:

```<code>//Normal AI character
void decide() {
    if(currentSquare()->getType()=="HOME") {
        watchTV();
        sleep();
    }
    if(currentSquare()->getType()=="WORKPLACE") {
        work();
    }
}

//Party animal AI
void decide() {
    if(currentSquare()->getType()=="HOME") {
        moveTo(getGameBoard()->closestBar());
    }
    if(currentSquare()->getType()=="WORKPLACE") {
        sleep();
    }
}
</code>```

Body:
As Amon pointed out, this is a good application for the visitor pattern.  Using it, your AI classes will end up looking something like this:

void decide(HomeSquare square);
void decide(WorkSquare square);
void decide(ShopSquare square);

And your squares have an accept function that looks like:

void accept(AI ai)
{
    ai.decide(this);
}

That lets you use inheritance to create appropriate defaults, or force every AI to implement certain decisions.  You can create an AI that behaves exactly like another one except at home, for example, without copying a bunch of code.  The compiler will point out where you forget something, and you don't have to cast all over the place.


问:
How to refactor an OO program into a functional one?
I'm having difficulty finding resources on how to write programs in a functional style. The most advanced topic I could find discussed online was using structural typing to cut down on class hierarchies; most just deal with how to use map/fold/reduce/etc to replace imperative loops.

What I would really like to find is an in-depth discussion of an OOP implementation of a non-trivial program, its limitations, and how to refactor it in a functional style. Not just an algorithm or a data structure, but something with several different roles and aspects - a video game perhaps. By the way I did read Real-World Functional Programming by Tomas Petricek, but I'm left wanting more.

答:
I have personal experience "accomplishing" this.  In the end, I didn't come up with something that's purely functional, but I came up with something that I'm happy with.  Here's how I did it:

Convert all external state to a parameter of the function. EG: if an object's method modifies x, make it so the method gets passed an x instead of calling this.x.

Remove behavior from objects.

Make the data of the object publicly accessible

Convert all methods into functions that the object calls.

Have client code that calls the object call the new function by passing in the object data.  EG: Convert
x.methodThatModifiesTheFooVar() into fooFn(x.foo)

Remove the original method from the object

Replace as many iterative loops as you can with higher order functions like map, reduce, filter, etc.

I couldn't get rid of mutable state.  It was just too non-idiomatic in my language (JavaScript).  But, by making all state passed in and/or returned, every function is possible to test.  This is different from OOP where setting up the state would take too long or separating dependencies often requires modifying production code first.

Also, I could be wrong about the definition, but I think my functions are referentially transparent: My functions will have the same effect given the same input.

Edit

As you can see here, it's not possible to create a truly immutable object in JavaScript.  If you're diligent and in control of who calls your code, you can do it by always creating a new object instead of mutating the current one.  It wasn't worth the effort to me.

But if you're using Java you can use these techniques to make your classes immutable.


答:
Definition of Functional Programming

The introduction to The Joy of Clojure says the following:

Functional programming is one of those computing terms that has a
  amorphous definition. If you ask 100 programmers for their definition,
  you’ll likely receive 100 different answers...

Functional programming
  concerns and facilitates the application and composition of
  functions...  For a language to be considered functional, its notion
  of function must be first-class.  First-class functions can be stored,
  passed, and returned just like any other piece of data.  Beyond this
  core concept, [definitions of FP might include] purity, immutability,
  recursion, laziness, and referential transparency.

Programming in Scala 2nd Edition p. 10 has the following definition:

Functional programming is guided by two main ideas.  The first idea is
  that functions are first-class values...  You can pass functions as
  arguments to other functions, return them as results from functions,
  or store them in variables...

The second main idea of functional programming is that the operations
  of a program should map input values to output values rather than
  change data in place.

If we accept the first definition, then the only thing you need to do to make your code "functional" is to turn your loops inside out.  The second definition includes immutability.

First Class Functions

Imagine you currently get a List of Passengers from your Bus object and you iterate over it decreasing each passenger's bank account by the amount of the bus fare.  The functional way to perform this same action would be to have a method on Bus, maybe called forEachPassenger that takes a function of one argument.  Then Bus would iterate over its passengers however that is best accomplished and your client code that charges the fare for the ride would be put in a function and passed to forEachPassenger.  Voila!  You're using functional programming.

Imperative:

```<code>for (Passenger p : Bus.getPassengers()) {
    p.debit(fare);
}
</code>```

Functional (using an anonymous function or "lambda" in Scala):

```<code>myBus = myBus.forEachPassenger(p:Passenger -> { p.debit(fare) })
</code>```

More sugary Scala version:

```<code>myBus = myBus.forEachPassenger(_.debit(fare))
</code>```

Non-first-class Functions

If your language does not support first-class functions, this can get very ugly.  In Java 7 or earlier, You have to provide a "Functional Object" interface like this:

```<code>// Java 8 has java.util.function.Consumer, but in earlier
// versions you have to roll your own:
public interface Consumer<T> {
    public void accept(T t);
}
</code>```

Then the Bus class provides an internal iterator:

```<code>public void forEachPassenger(Consumer<Passenger> c) {
    for (Passenger p : passengers) {
        c.accept(p);
    }
}
</code>```

Finally, you pass an anonymous function object to the Bus:

```<code>// Java 8 has syntactic sugar to make this look more like
// the Scala solution, but earlier versions require manually
// instantiating a "Function Object," in this case, a
// Consumer:
Bus.forEachPassenger(new Consumer<Passenger>() {
    @Override
    public void accept(final Passenger p) {
        p.debit(fare);
    }
}
</code>```

Java 8 allows local variables to be captured the scope of an anonymous function, but in earlier versions, any such varibales must be declared final.  To get around this you may need to make a MutableReference wrapper class.  Here's an integer-specific class that lets you add a loop counter to the above code:

```<code>public static class MutableIntWrapper {
    private int i;
    private MutableIntWrapper(int in) { i = in; }
    public static MutableIntWrapper ofZero() {
        return new MutableIntWrapper(0);
    }
    public int value() { return i; }
    public void increment() { i++; }
}

final MutableIntWrapper count = MutableIntWrapper.ofZero();
Bus.forEachPassenger(new Consumer<Passenger>() {
    @Override
    public void accept(final Passenger p) {
        p.debit(fare);
        count.increment();
    }
}

System.out.println(count.value());
</code>```

Even with this ugliness, it is sometimes beneficial to eliminate complicated and repeated logic from loops spread throughout your program by providing an internal iterator.

This ugliness has been fixed in Java 8, but handling checked exceptions inside a first class function is still really ugly and Java still carries the assumption of mutability in all its collections.  Which brings us to the other goals often associated with FP:

Immutability

Josh Bloch's Item 13 is "Prefer Immutability."  Despite common trash talk to the contrary, OOP can be done with immutable objects, and doing so makes it much better.  For instance, String in Java is immutable.  StringBuffer, OTOH needs to be mutable in order to build an immutable String.  Some tasks, like working with buffers inherently require mutability.

Purity

Each function should at least be memoizable - if you give it the same input parameters (and it should have no input besides its actual arguments), it should produce the same output every time without causing "side effects" like changing global state, performing I/O, or throwing exceptions.

It has been said that in Functional Programming, "some evil is usually required in order to get work done."  100% purity is generally not the goal.  Minimizing side effects is.

Conclusion

Really, of all the ideas above, immutability has been the biggest single win in terms of practical applications for simplifying my code - whether OOP, or FP.  Passing functions to iterators is the second biggest win.  The Java 8 Lambdas documentation has the best explanation of why.  Recursion is great for processing trees.  Laziness allows you to work with infinite collections.

If you like the JVM, I recommend you take a look at Scala and Clojure.  Both are insightful interpretations of Functional Programming.  Scala is type-safe with somewhat C-like syntax, though it really has as much syntax in common with Haskell as with C.  Clojure is not type-safe and it is a Lisp.  I recently posted a comparison of Java, Scala and Clojure with regard to one specific refactoring problem.  Logan Campbell's comparison using the Game of Life includes Haskell and typed Clojure as well.

PS

Jimmy Hoffa pointed out that my Bus class is mutable.  Rather than fix the original, I think this will demonstrate exactly the kind of refactoring this question is about.  This can be fixed by making each method on Bus a factory to produce a new Bus, each method on Passenger a factory to produce a new Passenger.  Thus I've added a return type to everything which means I'll copy Java 8's java.util.function.Function instead of Consumer interface:

```<code>public interface Function<T,R> {
    public R apply(T t);
    // Note: I'm leaving out Java 8's compose() method here for simplicity
}
</code>```

Then on Bus:

```<code>public Bus mapPassengers(Function<Passenger,Passenger> c) {
    // I have to use a mutable collection internally because Java
    // does not have immutable collections that return modified copies
    // of themselves the way the Clojure and Scala collections do.
    List<Passenger> newPassengers = new ArrayList(passengers.size());
    for (Passenger p : passengers) {
        newPassengers.add(c.apply(p));
    }
    return Bus.of(driver, Collections.unmodifiableList(passengers));
}
</code>```

Finally, the anonymous function object returns the modified state of things (a new bus with new passengers).  This assumes that p.debit() now returns a new immutable Passenger with less money than the original:

```<code>Bus b = b.mapPassengers(new Function<Passenger,Passenger>() {
    @Override
    public Passenger apply(final Passenger p) {
        return p.debit(fare);
    }
}
</code>```

Hopefully you can now make your own decision about how functional you want to make your imperative language, and decide whether it would be better to redesign  your project using a functional language.  In Scala or Clojure, the collections and other APIs are designed to make functional programming easy.  Both have very good Java interop, so you can mix and match languages.  In fact, for Java interoperability, Scala compiles its first class functions to anonymous classes that are almost compatible with the Java 8 functional interfaces.  You can read about the details in Scala in Depth sect. 1.3.2.

Title: How to refactor an OO program into a functional one?

Body:
I'm having difficulty finding resources on how to write programs in a functional style. The most advanced topic I could find discussed online was using structural typing to cut down on class hierarchies; most just deal with how to use map/fold/reduce/etc to replace imperative loops.

What I would really like to find is an in-depth discussion of an OOP implementation of a non-trivial program, its limitations, and how to refactor it in a functional style. Not just an algorithm or a data structure, but something with several different roles and aspects - a video game perhaps. By the way I did read Real-World Functional Programming by Tomas Petricek, but I'm left wanting more.

Body:
Definition of Functional Programming

The introduction to The Joy of Clojure says the following:

Functional programming is one of those computing terms that has a
  amorphous definition. If you ask 100 programmers for their definition,
  you’ll likely receive 100 different answers...

Functional programming
  concerns and facilitates the application and composition of
  functions...  For a language to be considered functional, its notion
  of function must be first-class.  First-class functions can be stored,
  passed, and returned just like any other piece of data.  Beyond this
  core concept, [definitions of FP might include] purity, immutability,
  recursion, laziness, and referential transparency.

Programming in Scala 2nd Edition p. 10 has the following definition:

Functional programming is guided by two main ideas.  The first idea is
  that functions are first-class values...  You can pass functions as
  arguments to other functions, return them as results from functions,
  or store them in variables...

The second main idea of functional programming is that the operations
  of a program should map input values to output values rather than
  change data in place.

If we accept the first definition, then the only thing you need to do to make your code "functional" is to turn your loops inside out.  The second definition includes immutability.

First Class Functions

Imagine you currently get a List of Passengers from your Bus object and you iterate over it decreasing each passenger's bank account by the amount of the bus fare.  The functional way to perform this same action would be to have a method on Bus, maybe called forEachPassenger that takes a function of one argument.  Then Bus would iterate over its passengers however that is best accomplished and your client code that charges the fare for the ride would be put in a function and passed to forEachPassenger.  Voila!  You're using functional programming.

Imperative:

for (Passenger p : Bus.getPassengers()) {
    p.debit(fare);
}

Functional (using an anonymous function or "lambda" in Scala):

myBus = myBus.forEachPassenger(p:Passenger -> { p.debit(fare) })

More sugary Scala version:

myBus = myBus.forEachPassenger(_.debit(fare))

Non-first-class Functions

If your language does not support first-class functions, this can get very ugly.  In Java 7 or earlier, You have to provide a "Functional Object" interface like this:

// Java 8 has java.util.function.Consumer, but in earlier
// versions you have to roll your own:
public interface Consumer<T> {
    public void accept(T t);
}

Then the Bus class provides an internal iterator:

public void forEachPassenger(Consumer<Passenger> c) {
    for (Passenger p : passengers) {
        c.accept(p);
    }
}

Finally, you pass an anonymous function object to the Bus:

// Java 8 has syntactic sugar to make this look more like
// the Scala solution, but earlier versions require manually
// instantiating a "Function Object," in this case, a
// Consumer:
Bus.forEachPassenger(new Consumer<Passenger>() {
    @Override
    public void accept(final Passenger p) {
        p.debit(fare);
    }
}

Java 8 allows local variables to be captured the scope of an anonymous function, but in earlier versions, any such varibales must be declared final.  To get around this you may need to make a MutableReference wrapper class.  Here's an integer-specific class that lets you add a loop counter to the above code:

public static class MutableIntWrapper {
    private int i;
    private MutableIntWrapper(int in) { i = in; }
    public static MutableIntWrapper ofZero() {
        return new MutableIntWrapper(0);
    }
    public int value() { return i; }
    public void increment() { i++; }
}

final MutableIntWrapper count = MutableIntWrapper.ofZero();
Bus.forEachPassenger(new Consumer<Passenger>() {
    @Override
    public void accept(final Passenger p) {
        p.debit(fare);
        count.increment();
    }
}

System.out.println(count.value());

Even with this ugliness, it is sometimes beneficial to eliminate complicated and repeated logic from loops spread throughout your program by providing an internal iterator.

This ugliness has been fixed in Java 8, but handling checked exceptions inside a first class function is still really ugly and Java still carries the assumption of mutability in all its collections.  Which brings us to the other goals often associated with FP:

Immutability

Josh Bloch's Item 13 is "Prefer Immutability."  Despite common trash talk to the contrary, OOP can be done with immutable objects, and doing so makes it much better.  For instance, String in Java is immutable.  StringBuffer, OTOH needs to be mutable in order to build an immutable String.  Some tasks, like working with buffers inherently require mutability.

Purity

Each function should at least be memoizable - if you give it the same input parameters (and it should have no input besides its actual arguments), it should produce the same output every time without causing "side effects" like changing global state, performing I/O, or throwing exceptions.

It has been said that in Functional Programming, "some evil is usually required in order to get work done."  100% purity is generally not the goal.  Minimizing side effects is.

Conclusion

Really, of all the ideas above, immutability has been the biggest single win in terms of practical applications for simplifying my code - whether OOP, or FP.  Passing functions to iterators is the second biggest win.  The Java 8 Lambdas documentation has the best explanation of why.  Recursion is great for processing trees.  Laziness allows you to work with infinite collections.

If you like the JVM, I recommend you take a look at Scala and Clojure.  Both are insightful interpretations of Functional Programming.  Scala is type-safe with somewhat C-like syntax, though it really has as much syntax in common with Haskell as with C.  Clojure is not type-safe and it is a Lisp.  I recently posted a comparison of Java, Scala and Clojure with regard to one specific refactoring problem.  Logan Campbell's comparison using the Game of Life includes Haskell and typed Clojure as well.

PS

Jimmy Hoffa pointed out that my Bus class is mutable.  Rather than fix the original, I think this will demonstrate exactly the kind of refactoring this question is about.  This can be fixed by making each method on Bus a factory to produce a new Bus, each method on Passenger a factory to produce a new Passenger.  Thus I've added a return type to everything which means I'll copy Java 8's java.util.function.Function instead of Consumer interface:

public interface Function<T,R> {
    public R apply(T t);
    // Note: I'm leaving out Java 8's compose() method here for simplicity
}

Then on Bus:

public Bus mapPassengers(Function<Passenger,Passenger> c) {
    // I have to use a mutable collection internally because Java
    // does not have immutable collections that return modified copies
    // of themselves the way the Clojure and Scala collections do.
    List<Passenger> newPassengers = new ArrayList(passengers.size());
    for (Passenger p : passengers) {
        newPassengers.add(c.apply(p));
    }
    return Bus.of(driver, Collections.unmodifiableList(passengers));
}

Finally, the anonymous function object returns the modified state of things (a new bus with new passengers).  This assumes that p.debit() now returns a new immutable Passenger with less money than the original:

Bus b = b.mapPassengers(new Function<Passenger,Passenger>() {
    @Override
    public Passenger apply(final Passenger p) {
        return p.debit(fare);
    }
}

Hopefully you can now make your own decision about how functional you want to make your imperative language, and decide whether it would be better to redesign  your project using a functional language.  In Scala or Clojure, the collections and other APIs are designed to make functional programming easy.  Both have very good Java interop, so you can mix and match languages.  In fact, for Java interoperability, Scala compiles its first class functions to anonymous classes that are almost compatible with the Java 8 functional interfaces.  You can read about the details in Scala in Depth sect. 1.3.2.


问:
Algorithm to Find the Aggregate Mass of "Granola Bar"-Like Structures?
I'm a planetary science researcher and one project I'm working on is N-body simulations of Saturn's rings.  The goal of this particular study is to watch as particles clump together under their own self-gravity and measure the aggregate mass of the clumps versus the mean velocity of all particles in the cell.  We're trying to figure out if this can explain some observations made by the Cassini spacecraft during the Saturnian summer solstice when large structures were seen casting shadows on the nearly edge-on rings.  Below is a screenshot of what any given timestep looks like.  (Each particle is 2 m in diameter and the simulation cell itself is around 700 m across.)

The code I'm using already spits out the mean velocity at every timestep.  What I need to do is figure out a way to determine the mass of particles in the clumps and NOT the stray particles between them.  I know every particle's position, mass, size, etc., but I don't know easily that, say, particles 30,000-40,000 along with 102,000-105,000 make up one strand that to the human eye is obvious.

So, the algorithm I need to write would need to be a code with as few user-entered parameters as possible (for replicability and objectivity) that would go through all the particle positions, figure out what particles belong to clumps, and then calculate the mass.  It would be great if it could do it for "each" clump/strand as opposed to everything over the cell, but I don't think I actually need it to separate them out.

The only thing I was thinking of was doing some sort of N2 distance calculation where I'd calculate the distance between every particle and if, say, the closest 100 particles were within a certain distance, then that particle would be considered part of a cluster.  But that seems pretty sloppy and I was hoping that you CS folks and programmers might know of a more elegant solution?

Edited with My Solution:  What I did was to take a sort of nearest-neighbor / cluster approach and do the quick-n-dirty N2 implementation first.  So, take every particle, calculate distance to all other particles, and the threshold for in a cluster or not was whether there were N particles within d distance (two parameters that have to be set a priori, unfortunately, but as was said by some responses/comments, I wasn't going to get away with not having some of those).

I then sped it up by not sorting distances but simply doing an order N search and increment a counter for the particles within d, and that sped stuff up by a factor of 6.  Then I added a "stupid programmer's tree" (because I know next to nothing about tree codes).  I divide up the simulation cell into a set number of grids (best results when grid size ≈7 d) where the main grid lines up with the cell, one grid is offset by half in x and y, and the other two are offset by 1/4 in ±x and ±y.  The code then divides particles into the grids, then each particle N only has to have distances calculated to the other particles in that cell.

Theoretically, if this were a real tree, I should get order N*log(N) as opposed to N2 speeds.  I got somewhere between the two, where for a 50,000-particle sub-set I got a 17x increase in speed, and for a 150,000-particle cell, I got a 38x increase in speed.  12 seconds for the first, 53 seconds for the second, 460 seconds for a 500,000-particle cell.  Those are comparable speeds to how long the code takes to run the simulation 1 timestep forward, so that's reasonable at this point.  Oh -- and it's fully threaded, so it'll take as many processors as I can throw at it.

答: You could, at the end of each timestep, convert the data into a graph, compute the minimum spanning tree, and then begin to remove edges that exceed a certain threshold. That should give you clumps and an easy way to enumerate through the particles in each clump.</p>


答:
I would like to point out the fragility of using strings for identifying classes of objects. You are somewhat working around type safety and if something goes wrong you may receive weird errors at run time. If you have quite some classes, you want to check, it can become a pain to update all parts of the code if you introduce a new class or delete another. Moreover it complicates or even prevents static analysis thus reducing the likelihood of automatically finding bugs (like dead code).

Compare this to using the visitor pattern that others already pointed out. You will get type safety and (if something goes wrong) compile time errors. On top of this the visitor pattern gives you more flexibility and you won't get long cascaded if-else blocks or switch blocks, thus improving readability and maintainability. Static analysis tools will work as intended.

So I would argue that using member variables for identification is at the very best suboptimal.

Full disclosure: I'm mainly a java developer but I think in this case the differences between java and c++ are not a concern. If I am wrong someone please correct me. ;)


答:
Your branching strategy looks really good to me. I have done the same strategy in the past and it works fine. Draw it up on a whiteboard and get all your devs to understand it so that people do the right work in the right branch. Teach and explain to everyone the switch command and get everyone to doublecheck the branch that they are working on. (Or alternatively just check out the entire repo... depending on your code size :) Remember... svn revert is your best friend!

Personally I prefer one person to be the "merge/branch" person (with a few backup people as reserves) to ensure that everything is kept under control and consistent. Let that person become your SVN guru and you'll be away.

A few other helpful hints:

Encourage frequent SVN updates and SVN commits. Every day is preferable.

Cross branch merges should also be done every day, or alternatively whenever a bug is fixed. Do them early and do them often! (you'll get good at it real quick).

Get a good diff tool - beyondcompare is ace. The standard tortoiseSVN one... not too good.

Don't check in stuff that changes upon compilation (like your output directory)

Try to clean up your repo before you start branching (get rid of files that don't need to be under version control - things like external libraries etc). The smaller your repo, the better

Changes to your Production branch and QA branches should be as small and short as possible - don't start refactoring code there, just fix the bug.

Make sure you branch from the top level of your solution - and if you have a DB I hope you've scripted all of your DB stuff (like stored procs or triggers)

Also tell people not to move folders around unless it's strictly necessary. This will make your merging much easier :) (Don't do what I did, launch upon a massive directory restructure halfway through a huge change to trunk which screwed up all of our merges... I was pretty popular after that).

Title: Branching Strategy for Test Environment


答:
It sounds like an idea that might not work.

Maybe take a look at this link for some inspiration: GitHub Flow This is the way github is using it's version system. Even though they use git instead of svn I would argue that the ideas behind their decisions will hold nevertheless.

The (imho) most important parts of this blog post regarding versioning:

master / trunk is deployable or - even better - deployed

development happens only on branches

merging happens only after review (maybe you can place QA here)

This way you get stability. Let me explain why. You need some base to branch off. Now if this base is not the very best you could do and the ultimate instance of everything then it doesn't really make sense to do so. If you branch from trunk while others work on it you will see bugs they introduce that happen to not be found or fixed yet. So likely integration tests (and anything above) may fail on you even though you're not the cause, drastically increasing the amount of debugging and frustration.

Moreover you will have lots of work keeping your 3 branches (trunk, QA, production) in sync. This will likely lead to confusion. I can almost guarantee you to loosing track at some point in time if you do not enforce this with automation.

I would suggest going the way GitHub is going. You can then tag which version you send to QA to have a reference when communicating. Even better could be having QA tighter integrated in the feedback loop as stated above. I strongly suggest using a CI system like Jenkins if you haven't considered using it yet. That way you minimize the round trip time between check-in and feedback and you can enforce coding rules, run static analyzers for error checking and so on.

Disclaimer: The git flow happens to work only if you don't want to fix bugs without introducing new features. If you want to do this your approach might be better suited.

Title: Branching Strategy for Test Environment


问:
business logic: client-side vs. server side
Let's say 3-5 years ago (more or less) n-tier application on the server side - and some javascript/html/CSS for the UI was a basic approach for web development.

Nowadays we can see that traditional web development paradigm changes a lot. Each day I saw more and more application who do not have server side in traditional way. They just consume some services (data-service, auth-service, etc.) but the business logic placed on client side. Also already a lot of javascript frameworks creates for simplify development according such model (Angular, Backbone, etc.)

What are the main benefits and disadvantages of new model versus traditional approach?

答:
There are several advantages to this approach:-

Responsiveness, because the business logic is in the fat client you do not need to wait for a round trip over the network for every interaction.

Sophistication - having all the control and higher level logic in the client enables rich user interfaces (e.g. this site, or gmail) which would simply not be possible if every interaction required a round trip to the server.

Scalability, all this processing is taking place on your device, using your electricity. if you have a large number of users the saving in server side processing is significant.

There are a few downsides though.

Lack of control over the client environment. You do not know which browser on which OS or what screen size and processing power your client will have. You application may not work on every client.

Uneven response. Large client libraries need to be downloaded and upgraded every now and then which will be relatively slow, once downloaded the response is lightning fast, users, generally prefer a consistent response time even if it is a little slower.

Javascript -- love it or hate it you are stuck with it as your main development language. Your code becomes public which some companies hate (perhaps they are embarrassed by their code quality?).

Security -- your server side code is now largely just database services whose APIs are open to anyone studying your Javascript therefore you need to take extra care in securing these services.


问:
How can I integrate local web development environments with a central SSO solution?
We have a single-page web application, and we have a new SSO site (also our own) using OAuth2, and are looking to hook them up.

On our production/staging/CI deployments, it's easy to hook everything up. For instance:

on production we'll have https://app.company.com access our prod backend point to https://sso.company.com for auth and vice versa

on CI we'll have https://app.ci.company.com access our dev backend and point to https://sso.ci.company.com for auth.

When we're doing development on the app, we access it locally at something like http://localhost:8000/, and it points to the shared dev backend. In the past, we've had it just do its own auth against the dev backend (getting the end user's credentials and submitting it), but we'd like to get it wired to use SSO to auth.

The question comes up of how we can do this without every developer who wants to develop locally needing to set up and custom configure their own SSO service. Specifically, can we use the shared dev/CI SSO and have it point to our local deployments?

What we've considered:

Use a proxy file/hosts file and have http(s)://sso.ci.company.com point to http(s)://localhost:8000. This burdens us with setting up HTTPS locally or have the SSO direct to a non-HTTPS URL. Also, the setup is a bit of a pain.

Have our local app redirect to the SSO with an argument identifying itself, and have the SSO use that to know where to redirect. For instance, redirect to https://sso.ci.company.com/?appUrl=localhost:8000. This forces us to punch an open-ended redirect in the SSO that we'd have to turn off for production and it is a bit "weird" but it works and can be black-boxed into the app.

Just run the SSO locally on every dev box. This is basically the non-solution since it would require a lot of setup to get to a "one box that can run everything" script, and it negates one of our valuable advantages at the moment in that basically all you need to do is check out the code on any system and have it running. I've seen this done before commonly though (often on top of dev VMs); I would just like to explore options that we are potentially closer to.

Is there a solution to this sort of problem or aspects of our ideas we haven't considered yet?

答:
I've previously worked in an environment where we've had SSO and local developer environments.

The key problem that needs to be worked on with SSO and developer environments is that the domain cookie needs to be able to be retrieved when hitting the local dev environment.

Admittingly, part of this has to do with how we set up the environment (and it was many years ago that I was involved with this).  It was a polyglot environment with a mixture of static html, old perl cgis, a weblogic server for Java EE, an iis server for some apps that needed to run with asp, and something that engineering ran.  The way that SSO communicated this information was that a reverse proxy stuck into the http headers the authenticated user name and all associated access they had.  This way, no matter who got it, they could look at the headers and continue from there.

First off, DNS was set up so that each developer had a host name in the 'dev.company.com' domain - thus 'sxu.dev.company.com' (for you) and 'jsmith.dev.comapny.com' for John Smith.  All of these names (CNAMES) pointed to a single common dev reverse proxy (the reverse proxy had very little on it) that then looked at the virtual host name that was coming through and then forwarded out the request to the appropriate developer's machine. Note that the interactions with the SSO code was completely contained within the reverse proxy so that no additional libraries needed to be installed anywhere else.

The interaction with infrastructure was simply to add another cname to common.dev.company.com whenever we had a new hire, and then we would add their name to a file that was run through some m4 macros to generate the proper apache http.conf file for the reverse proxy (that did take some work the first time we did it).

With this idea in place, you may wish to consider setting up a reverse proxy that acts to just forward everything to the appropriate developer's machine over http (no matter what type of connection it received).  https://sxu.ci.company.com/xyz goes to the reverse proxy, which handles the https, and forwards it to your dev box at http://10.1.2.3/xyz.  The gotcha with this approach that you have to watch for is that if you have any absolute paths in the code, or the dev's server tries to be aware of where its installed and the protocol being used to generate a link that is the same format, things might go a bit wonky (thats a technical term).

This avoids the problem of setting up https locally (only one server has is running https) or modifying the sso server to go to a non-https url.  You've got different setup in a different place.

I am unsure if your local dev boxes respond to access other than localhost (its a valid configuration), if so, those will need to be modified because the request is coming from the proxy in this case rather than the local browser.

I do want to point out the side benefit that it will mean that other devs can hit your environment (you want someone to reproduce a bug while you're watching the log files that you don't know how to repo - have them hit your server).

The second option is a not-non-standard approach (I do recall several production SSO systems being configured to allow a limited set of appUrl type parameters - in part so that the external person could use SSO and go to a specific page once logged in.  Adding a mapping of 'dev->localhost:8000' would allow for this, however you will need to reconsider how to address the problem of localhost doesn't get company.com cookies.  You will likely need to modify your local boxes to identify as localhost.company.com for that to work.


问:
Why does Clojure neglect the uniform access principle?
My background is Ruby, C#, JavaScript and Java. And now I'm learning Clojure. What makes me feel uncomfortable about the later is that idiomatic Clojure seems to neglect the Uniform access principle (wiki, c2) and thus to a certain degree encapsulation as well by suggesting to use maps instead of some sort of "structures" or "classes". It feels like step back. So a couple of questions, if anyone informed:

Which other design decisions/concerns it conflicted with and why it was considered less important?

Did you have the same concern as well and how it end up when you switched from a language supporting UAP by default (Ruby, Eiffel, Python, C#) to Clojure?

答:
First, a disclaimer: I'm not deeply familiar with the uniform access principle so you may want to take this with a grain of salt. That said, I would argue that Clojure does observe a uniform access principle: function calls.

The key quote on Wikipedia seems to be that "all services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation", and that's exactly the case with function calls in Clojure. In fact, everything in Clojure (and other Lisps) is a function call except for special forms and macros - and macros actually are functions, with the distinction that they operate on source code. You can even specify function call behavior for your own types by implementing clojure.lang.IFn:

```<code>(deftype Invokable []
  clojure.lang.IFn
  (invoke [this]
    :was-invoked))

(def invokable (Invokable.))
(invokable)                  ;=> :was-invoked
</code>```

You may have in mind the use of keywords as functions, which are most specifically associated with hash-maps, but you can actually implement that behavior for different types as well. Here's a silly example where keyword access reads a file (with the same name as the keyword) from your home directory, or returns a default value if such a file doesn't exist:

```<code>(ns weird.example
  (:require [clojure.java.io :as io]))

(deftype WeirdKlass []
  clojure.lang.ILookup
  (valAt [this k not-found]
    (let [home (System/getProperty "user.home")
          file (io/file home (name k))]
     (if (.isFile file)
       (slurp file)
       not-found)))
  (valAt [this k]
    (.valAt this k nil)))

(def klass (WeirdKlass.))

;; assuming you have a file at $HOME/testfile
(:testfile klass)        ;=> "test content!"
(:blah klass)            ;=> nil
(:blah klass :not-found) ;=> :not-found
</code>```

Update based on Alexey's comment

I think I have a better idea what you mean now but in practice I haven't found it to be an inconvenience. When you want or need a level of indirection/abstraction between your code's functionality and its underlying data representation the way to achieve it is: functions!

The simplest way would be to define full-name as a function which happens to use keyword lookup but could later be changed to instead compute the name (without clients knowing or caring):

```<code>;; For now
(defn full-name [person]
  (:full-name person))

;; Maybe later
(defn full-name [person]
  (str (:first-name person)
       " "
       (:last-name person)))
</code>```

Of course, you could also use records and protocols:

```<code>(defprotocol IPerson
  (full-name [p])
  (first-name [p])
  (last-name [p]))

(defrecord Person1 [name]
  IPerson
  (full-name [_]
    name)
  (first-name [_]
    (first (.split name " ")))
  (last-name [_]
    (last (.split name " "))))

(def person1 (->Person1 "Joe Schmoe"))
(full-name person1)  ;=> "Joe Schmoe"
(first-name person1) ;=> "Joe"
(last-name person1)  ;=> "Schmoe"

(defrecord Person2 [f-name l-name]
  IPerson
  (full-name [_]
    (str f-name " " l-name))
  (first-name [_]
    f-name)
  (last-name [_]
    l-name))

(def person2 (->Person2 "Joe" "Schmoe"))
(full-name person2)  ;=> "Joe Schmoe"
(first-name person2) ;=> "Joe"
(last-name person2)  ;=> "Schmoe"
</code>```

The big (very big, in my view) upside of using "plain" data structures when possible is that it means you and your users have Clojure's full range of map and sequence operations at your disposal. Alan Perlis expressed this idea well when he said that "it is better to have 100 functions operate on one data structure than 10 functions on 10 data structures."

Body:
First, a disclaimer: I'm not deeply familiar with the uniform access principle so you may want to take this with a grain of salt. That said, I would argue that Clojure does observe a uniform access principle: function calls.

The key quote on Wikipedia seems to be that "all services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation", and that's exactly the case with function calls in Clojure. In fact, everything in Clojure (and other Lisps) is a function call except for special forms and macros - and macros actually are functions, with the distinction that they operate on source code. You can even specify function call behavior for your own types by implementing clojure.lang.IFn:

(deftype Invokable []
  clojure.lang.IFn
  (invoke [this]
    :was-invoked))

(def invokable (Invokable.))
(invokable)                  ;=> :was-invoked

You may have in mind the use of keywords as functions, which are most specifically associated with hash-maps, but you can actually implement that behavior for different types as well. Here's a silly example where keyword access reads a file (with the same name as the keyword) from your home directory, or returns a default value if such a file doesn't exist:

(ns weird.example
  (:require [clojure.java.io :as io]))

(deftype WeirdKlass []
  clojure.lang.ILookup
  (valAt [this k not-found]
    (let [home (System/getProperty "user.home")
          file (io/file home (name k))]
     (if (.isFile file)
       (slurp file)
       not-found)))
  (valAt [this k]
    (.valAt this k nil)))

(def klass (WeirdKlass.))

;; assuming you have a file at $HOME/testfile
(:testfile klass)        ;=> "test content!"
(:blah klass)            ;=> nil
(:blah klass :not-found) ;=> :not-found

Update based on Alexey's comment

I think I have a better idea what you mean now but in practice I haven't found it to be an inconvenience. When you want or need a level of indirection/abstraction between your code's functionality and its underlying data representation the way to achieve it is: functions!

The simplest way would be to define full-name as a function which happens to use keyword lookup but could later be changed to instead compute the name (without clients knowing or caring):

;; For now
(defn full-name [person]
  (:full-name person))

;; Maybe later
(defn full-name [person]
  (str (:first-name person)
       " "
       (:last-name person)))

Of course, you could also use records and protocols:

(defprotocol IPerson
  (full-name [p])
  (first-name [p])
  (last-name [p]))

(defrecord Person1 [name]
  IPerson
  (full-name [_]
    name)
  (first-name [_]
    (first (.split name " ")))
  (last-name [_]
    (last (.split name " "))))

(def person1 (->Person1 "Joe Schmoe"))
(full-name person1)  ;=> "Joe Schmoe"
(first-name person1) ;=> "Joe"
(last-name person1)  ;=> "Schmoe"

(defrecord Person2 [f-name l-name]
  IPerson
  (full-name [_]
    (str f-name " " l-name))
  (first-name [_]
    f-name)
  (last-name [_]
    l-name))

(def person2 (->Person2 "Joe" "Schmoe"))
(full-name person2)  ;=> "Joe Schmoe"
(first-name person2) ;=> "Joe"
(last-name person2)  ;=> "Schmoe"

The big (very big, in my view) upside of using "plain" data structures when possible is that it means you and your users have Clojure's full range of map and sequence operations at your disposal. Alan Perlis expressed this idea well when he said that "it is better to have 100 functions operate on one data structure than 10 functions on 10 data structures."