tag:blogger.com,1999:blog-64252229330307042992024年10月11日T16:32:47.033-07:00Build Without BoundariesUnknownnoreply@blogger.comBlogger11125tag:blogger.com,1999:blog-6425222933030704299.post-15109056701095699882009年05月08日T11:17:00.000-07:002009年05月08日T12:20:06.234-07:00Venus Flytraps from Seed<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyMZy_FZLlyiQwyKTCo9HhroYsjpu6o2yGiRIJoQN_66hIHi4jArZC15uBxJqWy6ooTF3jSRwEe1LFn8KsoYxvd6_AN79I0FF4tKGXGus9jdi28WUZwT3TcDK-FhGtop26gYDGEWc9gtM/s1600-h/DSCF0027.JPG"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 200px; height: 150px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyMZy_FZLlyiQwyKTCo9HhroYsjpu6o2yGiRIJoQN_66hIHi4jArZC15uBxJqWy6ooTF3jSRwEe1LFn8KsoYxvd6_AN79I0FF4tKGXGus9jdi28WUZwT3TcDK-FhGtop26gYDGEWc9gtM/s200/DSCF0027.JPG" alt="" id="BLOGGER_PHOTO_ID_5333520208438396610" border="0" /></a>Venus Flytraps are generally considered a challenging plant to keep. My experience is that they are not that difficult as long as someone understands the conditions that they need. Growing flytraps from seed is thought to be considerably more challenging. I suppose that I am going to find out.<br /><br />This is an experiment in progress, so it might still turn out to be a disaster.<br /><br />Plan:<br />85 degrees (F) max until germination changing to 80 degrees afterward. Removal of cover after germination. A photo-period of 16 hours per day. One cell of the tray has been left empty so that the standing water level can be monitored. Water should be standing but not above the soil. After a few weeks I should have tiny little traps. After a couple of years I should have traps big enough to transplant into other containers and start a dormancy cycle.<br /><br />Materials:<br /><ul><li>1 x Standard 11" x 22" Seedling tray with cover<br /></li><li>3 x T5 (Sun Blaze) Grow Lights (mounted to and hung by two 5" square dowels)</li><li>1 x Heat mat</li><li>1 x Thermostat</li><li>1 x Timer</li><li>Some aluminum foil</li><li>Soil mix of 1 part Sphagnum peat and 1 part sand</li><li>2 gallons distilled water (to clean sand and start out)<br /></li><li>375 Venus Flytrap Seeds (Dionaea muscipula)</li></ul>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-6425222933030704299.post-83642600983778774022008年02月06日T18:53:00.000-08:002008年02月06日T20:15:53.494-08:00Fluent Problem Solving by EliminationMany problems lend themselves to a solution through a process of elimination. These include the selection of scientific hypothesis, technical troubleshooting, medical diagnosis, etc. I have written a small framework to help solve this class of problems. Additionally, I made a fluent interface to create constraint rules. You can download it from the code samples section.<br /><br />I am planning on creating a few examples in the near future to show it off, but for this post I just want to give a sneak peek at a couple of lines of Java code that uses it. This comes from a test that categorizes an animal based on observable qualities. This is the definition of one constraint rule that allows the system to know that no mammals have scales or feathers.<br /><pre><br />constraint = when(skin).is(scaley).or(skin).is(feathery).then(animalType).isNot(mammal);<br /></pre><br />Here is another that tells the system that only bats have both fur and wings:<br /><pre><br />constraint = when(skin).is(furry).and(phalanx).is(wings).then(animal).is(bat);<br /></pre>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-6425222933030704299.post-51316162575377689672008年01月20日T22:08:00.000-08:002008年01月20日T22:16:17.305-08:00Language Use CasesImagine that you are the customer for a new programming language. What three use cases would be most important to you and why?Unknownnoreply@blogger.com12tag:blogger.com,1999:blog-6425222933030704299.post-42177270430284601392008年01月12日T09:03:00.000-08:002008年01月12日T09:21:47.411-08:00Searching for more Fluent API patterns for JavaPrevious posts cover three patterns commonly seen in Fluent APIs in Java.<br /><ol><li>Method Chaining</li><li>Nested Interfaces</li><li>Fluent Builder</li></ol>So far these are the only Fluent patterns that I have seen used successfully in Java. Does anyone have any examples of Fluent APIs in Java that don't use one of these techniques?Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-6425222933030704299.post-2913459637386147732008年01月12日T08:37:00.000-08:002008年01月12日T09:22:10.215-08:00Fluent API pattern: Method ChainingMethod Chaining is the simplest and most common pattern for creating Fluent APIs. A great example is in the Binder class in Guice. It allows you to chain methods one after another in a way that describes the desired results. Here is an example from the <a href="http://docs.google.com/View?docid=dd2fhx4z_5df5hw8">Guice User's Guide</a>:<br /><pre><br />binder.bind(Service.class).to(ServiceImpl.class).in(Scopes.SINGLETON);<br /></pre><br />The simplest implementation of method chaining can be seen in the Java StringBuffer where the 'append' method returns a reference to itself. This is not exactly Fluent since it does not resemble a natural language sentence, but it works the same way.<br /><br />This can also be seen in an example from a previous post that uses the CustomerCreator:<br /><pre><br />Customer customer = createCustomer.named("Bob").that(bought.item(CompactDisc).on("02/17/2006"));<br /></pre><br />The method 'named' returns another instance of a CustomerCreator such that you can chain the 'that' method off of it. Per usual, I strongly encourage you to download the full example source and play with it to see how these Fluent API pattern can be used in conjunction.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6425222933030704299.post-40473643511371387392007年12月28日T17:37:00.000-08:002007年12月31日T21:04:59.557-08:00Fluent Query Language Through Strategy CompositionIn the last post we created a Fluent API that builds a domain object hierarchy. In this post we are going to create a Fluent API that acts as a domain specific querying language for this same domain. Let's take a look at a slightly modified example from a previous post:<br /><pre>CustomerQuery query = questionThatAsks.whichCustomers(bought(anything(), between("01/01/2006", "01/01/2007")));<br />List&lt;Customer&gt; customers = query.ask(listOfAllCustomers);</pre><br />This example creates a CustomerQuery object that is capable of answering the question that has been asked, 'Which customers bought anything between 01/01/2006 and 01/01/2007?'. We could have picked any date or date range. We could have specified that are looking for Customers that bought compact discs. Pretty cool, huh? Can you imagine how it works?<br /><br />We are doing a combination of two things to get this affect. First we are gathering information about the desired return type base on which builder method we call (ie. whichCustomers, howManyCustomers, haveAnyCustomers, etc.). When we ask 'whichCustomers' we know that we are going to return a query object of type &lt;List&lt;Customer&gt;&gt;. If we ask 'howManyCustomers' we know we should return an int. <br /> <br />Secondly we are using a composing the behavior of our query using a Strategy Pattern. In this case our strategy takes the form of a Predicate. You could expand on your interface with different types of Strategy objects. For instance, you could add a Strategy to do proper formatting base on which builder method you call. Or a Strategy to add select a particular property off of the Customer objects.<br /><br />You don't even have to even create the intermediate CustomerQuery object. You would just as easily get your answer directly. Take some time to look over the full example source. Then think about your business domain and how a similar pattern could be used to allow you to code in your business logic in this incredibly expressive way.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6425222933030704299.post-31913427445031805022007年12月27日T20:06:00.000-08:002007年12月31日T21:04:32.290-08:00Fluent API pattern: Nested InterfacesMultiple Fluent APIs can be used in a nested fashion in order to separate and organize responsibilities while keeping individual classes simple. Fluent APIs can become complex as more features are added if a designer is not careful. This pattern gives a clear and sustainable path for growth. Let's take a closer look at one of the examples from my last post:<br /><pre><br />Customer customer = createCustomer.named("Bob").that(bought.item(CompactDisc).on("02/17/2006"));<br /></pre><br />Reading the words reveals in English exactly what is going on with the code. It creates a customer named Bob that bought a compact disc on 02/17/2006. What is going on behind the scenes? That is not quite as clear, nor is it important to anyone other than the Fluent API designer!<br /><br />Before diving in, let's talk briefly about the domain. We are creating a Customer. Customer's have Transactions. Transactions have Items and Dates.<br /><br />The first thing to notice is that almost half of this code is fully enclosed in parenthesis. The result of '<i>bought.item(CompactDisc).on("02/17/2006")</i>' is being passed to a method named 'that'. It is not obvious here, but the 'that' method is on a CustomerCreator object. <br /><br />Now notice that 'bought' is an object. However, in this snippet this object is not instantiated. Don't be too bothered by this. The declaration and instantiation of this object is just fluff that distracts from the true intent of the code. With some creative use of static imports you can instantiate this object in just one place in your entire codebase and never have to look at it again. Know, though, that the 'bought' object is a TransactionCreator.<br /><br />TransactionCreator has methods that set Items and Date. In order to chain methods, all methods on TransactionCreator return a TransactionCreator with all appropriate data set. <span style="color:red;">Warning</span>: Do not just return 'this' from such methods. You will need to do a deep clone or you will likely have very interesting things happen unexpectedly when you change data on one Transaction and it changes on all the others as well.<br /><br />The object 'createCustomer' is very similar of type CustomerCreator. It creates a Customer instead of a Transaction. However, it follows the exact same pattern as TransactionCreator. Methods 'named' and 'that' are both on the CustomerCreator class and both return cloned CustomerCreators that have had some piece of data added to it.<br /><br />The final piece of the puzzle is that CustomerCreator and TransactionCreator extend Customer and Transaction respectively. This allows for method chaining that can end at any time and still give you an object of the target class.<br /><br />I strongly encourage you to download the full example source and look through it. Fluent APIs do not need to be overly complex, but they are a drastic shift from traditional interface design. Don't give up even if it takes a while to really understand. The benefits are worth the learning curve.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6425222933030704299.post-85811982300280691522007年12月16日T16:14:00.000-08:002009年11月07日T16:21:58.617-08:00Intro to Fluent APIsA Fluent API is a interface or set of interfaces that allow one to express one's code in a way that is similar to English (or your natural language of choice). Such APIs are often incorrectly referred to as Domain Specific Languages (DSL). The difference, of course, is that a Fluent API is implemented within an existing general purpose language.<br /><br />Example of creating a model object that represents a customer:<br /><pre>Customer customer = createCustomer.named("Bob").that(bought.item(CompactDisc).on("02/17/2006"));</pre><br /><br />Example of querying a list of customers:<br /><pre><br />List&lt;Customer&gt; question = questionThatAsks.whichCustomers(bought(anything(), between("12/31/2006", "01/01/2007"))).ask(customers);<br /></pre><br />Full code examples are available files section of the <a href="http://buildwithoutboundaries.blogspot.com/">home page</a>.<br /><br />My team has created two comparable Fluent APIs to help us build and query model objects, and our productivity has increased substantially from it. It has allowed us to program at a very high level and in the terms of our business domain. There are trade-offs involved. For instance, it is difficult to look at a individual methods and understand how they fit into the system. You will likely have methods named 'with' and 'and' that do very little if any work. These methods exist entirely for the sake of readability. Fortunately, it is very easy to learn to use Fluent APIs from examples.<br /><br />Creating Fluent APIs is another story all together. It is not difficult or complex, but it is a radical departure from tradition programming paradigm. For this reason it often takes some mental acrobatics to design a new Fluent API, but it gets easier with time. I believe, though, that this learning curve is partly because common patterns pertaining to creating Fluent APIs have not adequately been formalized and documented. These techniques have been used by visionaries for many years particularly in the Ruby community (often called DSLs). However Fluent APIs are just starting to gain popularity in the mainstream Java and C# communities. One reason that this movement was started in the dynamic language communities is that the flexibility of such languages makes creating elegant Fluent APIs much easier. Part of the reason that Fluent APIs are starting to catch on in the Java community is that Java 5 introduced some features that, when used together, make such expressive APIs both possible and practical. Static imports, generics and enums play crucial roles in achieving English-like readability.<br /><br />The success and productivity that I have experienced using Fluent APIs in Java has given me a new appreciation for Java. This appreciation is not for Java as a solution for real world problem, but as a means of creating the tools necessary for solving real world problems.<br /><br /><span style="font-weight: bold;">Popular tools using Fluent APIs:</span><br /><ul><li><a href="http://www.jmock.org/">JMock</a> (For scripting expectations)<br /></li><li><a href="http://code.google.com/p/google-guice/">Guice</a> (Binders)<br /></li><li>JAX-B (<a href="https://jaxb2-commons.dev.java.net/fluent-api/">Fluent API Plugin</a>)</li></ul>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6425222933030704299.post-13000960651725946852007年12月15日T20:14:00.001-08:002007年12月27日T20:01:20.358-08:00Synergy Between Guice, Easymock and JUnitI have recently written separate posts about Guice and Easymock. Those posts were really just preparation for this one. Guice and Easymock are impressive tools each on their own. However they really shine when used together and in conjunction with JUnit (or your testing framework of choice). If you are unfamiliar with either of these tools please read the previous posts to get up to speed before continuing reading.<br /><b>Synergistic Effects:</b><b><br /></b><div style="margin-left: 40px;">Arrows indicate that one tool is increasing the value of the tool to which the arrow points.<br /><br /></div><div style="margin-left: 40px;"><b>Easymock --&gt; JUnit</b>:<br /><ul><li>Higher signal to noise ratio in tests since manual mocks are unnecessary. This increases the expressiveness of the tests and increases the value of the tests as executable documentation.</li></ul><b>JUnit --&gt; Guice:<br /></b><ul><li>Unit testing code leads most people eventually into some form of dependency injection. Thus Guice often just makes easier the best-practices that a developer is already following.<br /></li></ul><b>Guice --&gt; JUnit:<br /></b></div><div style="margin-left: 40px;"><ul><li>Classes can use injected dependencies rather than relying on concrete implementations, allowing tests to be targeted on solely on the class under test.<br /></li></ul></div><div style="margin-left: 40px;"><ul><li>Individual test classes do not need to construct collaborator objects as a prerequisite for instantiating the class under test. They can simply have Guice build an instance of the class under test.<br /></li><li>Collaborators that are necessary for the intent of the test can be injected directly into test classes (see below).</li><li>Collaborators that are not important in achieving the goal of the test can be ignored.</li></ul><b>Guice &lt;--&gt; Easymock:<br /></b><ul><li>Mock collaborators can be configured in a Guice configuation Module intended specifically for testing.</li><li>The testing Module is reusable to the same work to generate mocks won't have to be done in multiple test classes.<br /></li></ul><br /></div>Object can be injected directly into tests. You still want to instantiate your own class under test, but this is very useful for collaborator objects that are not the focus of the test. The following example does not show the use of the injected object, only that the injection is possible:<br /><br /><div style="overflow: auto;"><pre><br />@RunWith(InjectingTestClassMethodsRunner.class)<br />public class InjectionTest {<br /> @Inject IClock clock;<br /><br /> @Test<br /> public void myTest() {<br /> assertNotNull(clock);<br /> }<br />}<br /></pre></div><br /><br />Here is a snippet to show you how to use Guice to instantiate your test classes in JUnit:<br /><div style="overflow: auto;"><pre><br />public class InjectingTestClassMethodsRunner extends TestClassMethodsRunner {<br /> public InjectingTestClassMethodsRunner(Class klass) {<br /> super(klass);<br /> }<br /><br /> @Override<br /> protected Object createTest() throws Exception {<br /> Injector injector = Guice.createInjector(new TestModule());<br /> return injector.getInstance(this.getTestClass());<br /> }<br />}<br /></div></pre>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-6425222933030704299.post-33294849493352006742007年12月15日T20:14:00.000-08:002007年12月27日T19:48:27.394-08:00Simple Dependency Injection with GuiceGoogle's <a href="http://code.google.com/p/google-guice/">Guice</a> is a very slick, annotations-based <a href="http://en.wikipedia.org/wiki/Dependency_injection">Dependency Injection</a> framework. It allows you to easily create class instances even if they have complex dependencies on other classes. The knowledge of what concrete implementation to use for a dependency is contained in simple configuration classes called Modules. Injection sites for these implementations may be constructors, methods, or fields. Anywhere you want a dependency to be injected you just add the @Inject annotation to. The is pretty much all there is too it. Guice is very simple and has a relatively small learning curve.<br><br>Here is a code snippet showing injection of a dependancy into a constructor:<br /><div style="overflow: auto;"><pre><br />@Inject <br>public TimeChecker(IClock clock) { ... }<br /></pre></div><br /><br />And here is the Module to tell Guice which concrete implementation to use:<br /><div style="overflow: auto;"><pre><br />@Inject<br />public TimeChecker(IClock clock) { ... }<br /></pre></div><br /><br />Now to get an instance of TimeChecker you no longer need to build it's dependancies:<br /><div style="overflow: auto;"><pre><br />TimeChecker timeChecker = Guice.createInjector(new ProductionSettingsModule()).getInstance(TimeChecker.class);<br /></pre></div><br /><br />For one dependency this looks like a lot of work, but if your class has four or five dependencies the above line does not get any bigger.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-6425222933030704299.post-29434574587289511482007年12月15日T20:11:00.000-08:002007年12月27日T19:48:40.330-08:00Less Tedious Tests with Easymock<a title="mocks" href="http://en.wikipedia.org/wiki/Mock_object" id="d6oj"></a>If you have small, simple classes with clearly defined responsibilities you will inevitably have dependencies between them. You could use these collaborator classes directly with the 'new' operator, but if you do you will not be able to test your classes in isolation of each other and you will wind up with much duplication between your tests. It will also be difficult to test all of the scenarios that you might want to because of the behaviors of these collaborator classes. So instead you inject these collaborators into you class under test. This is better, but it does force you to create mock classes. These mock classes will often require behaviors in order to perform your test or gather information about the behavior of your class under test. One problem with this is that this behavior in your mock classes becomes difficult to maintain as the complexity of the behavior of your class under test increases. Another problem is that if you follow this strategy repeatedly you will develop a lot of test code that is redundant.<br><br><a title="Easymock" href="http://www.easymock.org/" id="kjt5">Easymock</a> helps to avoid these problems. It will create mock objects for you and allow you to easily specify how your class under test is expected to use them. The following is a bit incomplete for the sake of explanation, so I encourage you to read <a title="the documentation" href="http://www.easymock.org/Documentation.html" id="m3_6">the documentation</a>.<br><br>Getting a new clock object:<br /><pre style="overflow: auto;"><br />IClock clock = Easymock.createMock(IClock.class);<br /></pre><br /><br />Telling Easymock how the clock is expected to be used:<br /><pre style="overflow: auto;"><br />Easymock.expect(clock.getTime()).andReturn(new Date());<br /></pre><br /><br />Then you give the clock object to your class under test to use and Easymock is able to notify JUnit of when and how your class under test used the collaborator in an unexpected way.Unknownnoreply@blogger.com0

AltStyle によって変換されたページ (->オリジナル) /