Meeting 6: Unterschied zwischen den Versionen

Aus Java Student User Group Austria - Java + JVM in Wien Österreich / Vienna Austria
Wechseln zu: Navigation, Suche
(ZtCMMhSlDFtyzm)
Zeile 1: Zeile 1:
'''When''': Monday, November 3rd, 2008 - 19:00
+
Lene My Baastrup Sommergaard siger:Hej Marianne.Beklager vores sene svar  Siden har ikke ve6ret fuldt opdateret det sistde halve e5r, men det he5ber vi pe5 at kunne e6ndre pe5. Der var lagersalg i starten af april  Jeg he5ber du fik information fra anden side. /Lene
 
 
'''Where''': [http://www.wegweiser.ac.at/tuwien/hoersaal/F4.html Freihaus HS4]
 
 
 
 
 
==Bazaar==
 
 
 
Download the [[Media:JSUG-Bazaar-Florian Motlik.pdf |slides]] (pdf, 68KB).<br />
 
You can also view the [http://www.slideshare.net/javastudentusergroup/jsug-bazaar-by-florian-motlik slides online].
 
 
 
===Contents===
 
 
 
Bazaar was introduced by [[Benutzer:Matlock|Florian Motlik]], which is an opensource, distributed verion control system completely written in python.
 
 
 
====Core Concepts====
 
First of all, you have to be aware of some necessary terms and their meaning:
 
 
 
* '''Revision''': A snapshot of the files you are working with.
 
* '''Working tree''': The directory containing your version controlled files and subdirectories.
 
* '''Branch''': An ordered set of revisions that describe the history of a set of files.
 
* '''Repository''': A store of revisions.
 
 
 
See: [http://doc.bazaar-vcs.org/bzr.dev/en/user-guide/index.html#core-concepts http://doc.bazaar-vcs.org/bzr.dev/en/user-guide/index.html#core-concepts]
 
 
 
 
 
====Distributed vs Centralized====
 
 
 
[[Bild:Bazaar distributed.png|thumb|Distributed vs Centralized Versioning System]]
 
The big difference (as compared to traditionally VCS like CVS and SVN) is that bazaar manages sources in a distributed way. Instead of a central server with a single repository where each developer commits his changes, in the bazaar world every developer has its own repository and instead of commits there are only merges.
 
 
 
====Workflows====
 
With bazaar, you can work in many different workflows, depending on your environment: solo, partner, central (with local commits) or decentral (shared mainline, human or automated gatekeeper). Depending on that workflows, you have to execute different commands.
 
 
 
=====Solo & Partner=====
 
 
 
Initialize the repository:
 
<code>
 
$ bzr init-repo # create meta repository (for performance reasons)
 
$ bzr init # transform directory into repository
 
</code>
 
 
 
In solo mode:
 
<code>
 
$ cd my-stuff
 
$ bzr init
 
$ bzr add
 
$ bzr commit -m "Initial import"
 
</code>
 
 
 
In partner mode:
 
<code>
 
UserA$ bzr init
 
... some code changes on UserA's machine ...
 
UserA$ bzr commit
 
UserB$ bzr branch <nowiki>http://server.com/UserA</nowiki>
 
... some code changes on UserB's machine ...
 
UserB$ bzr commit
 
UserA$ merge <nowiki>http://server.com/UserB</nowiki>
 
... some code changes on UserA's machine ...
 
UserA$ bzr commit
 
UserB$ bzr merge <nowiki>http://server.com/UserA</nowiki>
 
</code>
 
 
 
=====Central=====
 
 
 
Necessary steps are similar to CVS/SVN, where the branch is bound to the server and a network connection is required.
 
<code>
 
$ bzr checkout <nowiki>http://server.com/repo</nowiki>
 
... some code changes on local machine ...
 
$ bzr commit
 
$ bzr update
 
</code>
 
 
 
====Decentral====
 
 
 
In this case you mirror the main branch which is not supposed to be used for development.
 
<code>
 
$ bzr branch <nowiki>http://server.com/trunk</nowiki>
 
$ bzr branch trunk feature1
 
... some code changes related to feature1 ...
 
$ bzr branch trunk fix1
 
... some code changes related to fix1 ...
 
$ cd trunk
 
$ bzr merge ../fix1
 
$ bzr commit # locally
 
$ bzr update # to update the mirrored branch
 
</code>
 
 
 
 
 
===Links===
 
 
 
* [http://bazaar-vcs.org/ http://bazaar-vcs.org/] ... Official website
 
* [http://doc.bazaar-vcs.org/bzr.dev/ http://doc.bazaar-vcs.org/bzr.dev/] ... User documentation
 
* [https://launchpad.net/ https://launchpad.net/] ... Hosting service like sourceforge using bazaar
 
 
 
==Maven==
 
 
 
By [[Benutzer:Mikegr|Michael Greifeneder]].
 
 
 
==Fluent Interfaces==
 
 
 
Unfortunately there are no slides available for the presentation from Axel Gross but you can have a look at [http://www.martinfowler.com/bliki/FluentInterface.html Martin Fowler's article] about fluent interfaces who coined the term.
 
 
 
To be short, it's kind of an internal DSL with the aim to provide a readable API.
 
 
 
 
 
The following example shows the use of [http://www.jmock.org/ JMock]:
 
<source lang="java">
 
mock.expects(once()).method("m").with(or(stringContains("hello"),
 
                                        stringContains("howdy")));
 
</source>
 
 
 
 
 
In a preceding presentation about [[Meeting_1#db4o|db4o]] we had similar code for querying a OO database:
 
<source lang="java">
 
query.descend("matrNr").constrain(500000).greater().equal();
 
</source>
 
 
 
 
 
===Simple Example===
 
 
 
Personally, I ([[Benutzer:Christoph.pickl|Christoph Pickl]]) like to use that technique to construct complex objects which should be on the one side immutable but on the other easy to create (values for creation are sometimes scattered throughout many different classes). Imagine you have a <code>Person</code> type with its only attributes <code>name:String</code> and <code>age:int</code> which are both marked final.
 
 
 
<source lang="java">
 
public class Person {
 
 
 
  // final attributes
 
  private final String name;
 
  private final int age;
 
 
 
  // constructor is package-private, so only PersonBuilder can access it
 
  Person(final String name, final int age) {
 
    this.name = name;
 
    this.age = age;
 
  }
 
 
 
  // simple getter methods
 
  public String getName() {
 
    return this.name;
 
  }
 
  public int getAge() {
 
    return this.age;
 
  }
 
}
 
</source>
 
 
 
 
 
A <code>PersonBuilder</code> now provides the single possibility to create <code>Person</code>s. The interesting thing here is, that it forces the caller to invoke methods for each attribute of <code>Person</code>, and returns itself but with another "''face''" (builder interface). Only if the last attribute was set the <code>create()</code> method is accessible which finally returns a new instance.
 
Guard clauses (actually used to avoid nested conditions) help to ensure that the instance will only store valid values. This gives the advantage of defining a valid state outside of the entity itself so it can be reused in a complete different environment with complete different limitations (name can be null, etc).
 
<source lang="java">
 
public class PersonBuilder implements IPersonBuilder1, IPersonBuilder2, IPersonBuilderFinisher {
 
 
 
  // (non-final) attributes
 
  private String name;
 
  private int age;
 
 
 
  // constructor
 
  private PersonBuilder() {
 
    // constructor not visible; use static factory method build()
 
  }
 
  public static IPersonBuilder1 build() {
 
    return new PersonBuilder();
 
  }
 
 
 
  // fluent interface implementations
 
  public IPersonBuilder2 name(final String name) {
 
    if(name == null) { // guard clause
 
      throw new IllegalArgumentException("name == null");
 
    }
 
    this.name = name;
 
    return this;
 
  }
 
 
 
  public IPersonBuilderFinisher age(final int age) {
 
    if(age < 0 || age > 200) { // guard clause
 
      throw new IllegalArgumentException("age not within range 0-200: " + age);
 
    }
 
    this.age = age;
 
    return this;
 
  }
 
 
 
  public Person newInstance() {
 
    return new Person(this.name, this.age);
 
  }
 
}
 
 
 
</source>
 
 
 
 
 
Two obvious disadvantages come to my mind: The overhead of creating an interface for each method plus one for the creation and you have to invoke the methods in exactly the way they are defined via the fluent interfaces. You can't change the order, and you can't skip any attribute.
 
<source lang="java">
 
public interface IPersonBuilder1 {
 
  IPersonBuilder2 name(String name);
 
}
 
public interface IPersonBuilder2 {
 
  IPersonBuilderFinisher age(int age );
 
}
 
public interface IPersonBuilderFinisher {
 
  Person newInstance();
 
}
 
</source>
 
 
 
 
 
Finally you can use the builder to create <code>Person</code> instances via a very readable API. The second <code>Person</code> instance is created in a distributed manner, which would not be that easy if you would have to create the instance in the old-fashioned way because of final attributes you have to pass to the constructor.
 
<source lang="java">
 
public class App {
 
 
 
  public static void main(final String[] args) {
 
    // short version:
 
    final Person p1 = PersonBuilder.build().name("Christoph Pickl").age(23).newInstance();
 
 
 
    // or use different builders and pass them around
 
    final IPersonBuilder2 builder2 = PersonBuilder.build().name("Christopherus Pickl");
 
    final Person p2 = App.computeAge(builder2).newInstance();
 
  }
 
 
 
  private static IPersonBuilderFinisher computeAge(final IPersonBuilder2 builder2) {
 
    final int age = 42; // some complicated computation
 
    return builder2.age(age);
 
  }
 
}
 
</source>
 
 
 
[[Category:Meeting]]
 

Version vom 9. November 2012, 10:14 Uhr

Lene My Baastrup Sommergaard siger:Hej Marianne.Beklager vores sene svar Siden har ikke ve6ret fuldt opdateret det sistde halve e5r, men det he5ber vi pe5 at kunne e6ndre pe5. Der var lagersalg i starten af april Jeg he5ber du fik information fra anden side. /Lene