答:
Will this be going over the wire (serialized/deserialized) any time now or in the future? Favor the single ID type over the who-knows-how-large full object.

If you're looking for type-safety of the ID to its entity, then there are code solutions as well. Let me know if you need an example.

Edit: expanding on type-safety of ID:

So, let's take your method:

```<code>public Foo GetItem(int id) {}
</code>```

We only hope that the integer id that's passed in is for a Foo object. Someone could misuse it and pass in some Bar object's integer ID or even just by hand type in 812341. It's not type safe to Foo. Secondly, even if you used the pass an object Foo version, I'm sure Foo has an ID field which is int which someone can possibly modify. And lastly, you cannot use method overloading if these exist in a class together as only the return type varies. Let's rewrite this method a bit to look type-safe in C#:

```<code>public Foo GetItem(IntId<Foo> id) {}
</code>```

So I've introduced a class named IntId which has a generic piece to it. In this particular case, I want an int that's associated with Foo only. I can't just pass in a naked int nor can I assign an IntId<Bar> to it accidentally. So below is how I've written these type-safe identifiers. Do take note that the manipulation of the actual underlying int is only at your data access layer. Anything above that only sees the strong type and has no (direct) access to its internal int ID. It should have no reason to.

IModelId.cs interface:

```<code>namespace GenericIdentifiers
{
    using System.Runtime.Serialization;
    using System.ServiceModel;

    /// <summary>
    /// Defines an interface for an object's unique key in order to abstract out the underlying key
    /// generation/maintenance mechanism.
    /// </summary>
    /// <typeparam name="T">The type the key is representing.</typeparam>
    [ServiceContract]
    public interface IModelId<T> where T : class
    {
        /// <summary>
        /// Gets a string representation of the domain the model originated from.
        /// </summary>
        /// <value>The origin.</value>
        [DataMember]
        string Origin
        {
            [OperationContract]get;
        }

        /// <summary>
        /// The model instance identifier for the model object that this <see cref="IModelId{T}"/> refers to.
        /// Typically, this is a database key, file name, or some other unique identifier.
        /// <typeparam name="TKeyDataType">The expected data type of the identifier.</typeparam>
        /// </summary>
        /// <typeparam name="TKeyDataType">The expected data type of the identifier.</typeparam>
        /// <returns>The unique key as the data type specified.</returns>
        [OperationContract]
        TKeyDataType GetKey<TKeyDataType>();

        /// <summary>
        /// Performs an equality check on the two model identifiers and returns <c>true</c> if they are equal; otherwise
        /// <c>false</c> is returned.  All implementations must also override the equal operator.
        /// </summary>
        /// <param name="obj">The identifier to compare against.</param>
        /// <returns><c>true</c> if the identifiers are equal; otherwise <c>false</c> is returned.</returns>
        [OperationContract]
        bool Equals(IModelId<T> obj);
    }
}
</code>```

ModelIdBase.cs base class:

```<code>namespace GenericIdentifiers
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.Serialization;

    /// <summary>
    /// Represents an object's unique key in order to abstract out the underlying key generation/maintenance mechanism.
    /// </summary>
    /// <typeparam name="T">The type the key is representing.</typeparam>
    [DataContract(IsReference = true)]
    [KnownType("GetKnownTypes")]
    public abstract class ModelIdBase<T> : IModelId<T> where T : class
    {
        /// <summary>
        /// Gets a string representation of the domain the model originated from.
        /// </summary>
        [DataMember]
        public string Origin
        {
            get;

            internal set;
        }

        /// <summary>
        /// The model instance identifier for the model object that this <see cref="ModelIdBase{T}"/> refers to.
        /// Typically, this is a database key, file name, or some other unique identifier.
        /// </summary>
        /// <typeparam name="TKeyDataType">The expected data type of the identifier.</typeparam>
        /// <returns>The unique key as the data type specified.</returns>
        public abstract TKeyDataType GetKey<TKeyDataType>();

        /// <summary>
        /// Performs an equality check on the two model identifiers and returns <c>true</c> if they are equal;
        /// otherwise <c>false</c> is returned. All implementations must also override the equal operator.
        /// </summary>
        /// <param name="obj">The identifier to compare against.</param>
        /// <returns>
        ///   <c>true</c> if the identifiers are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public abstract bool Equals(IModelId<T> obj);

        protected static IEnumerable<Type> GetKnownTypes()
        {
            return new[] { typeof(IntId<T>), typeof(GuidId<T>) };
        }
    }
}
</code>```

IntId.cs:

```<code>namespace GenericIdentifiers
{
    // System namespaces
    using System;
    using System.Diagnostics;
    using System.Globalization;
    using System.Runtime.Serialization;

    /// <summary>
    /// Represents an abstraction of the database key for a Model Identifier.
    /// </summary>
    /// <typeparam name="T">The expected owner data type for this identifier.</typeparam>
    [DebuggerDisplay("Origin={Origin}, Integer Identifier={Id}")]
    [DataContract(IsReference = true)]
    public sealed class IntId<T> : ModelIdBase<T> where T : class
    {
        /// <summary>
        /// Gets or sets the unique ID.
        /// </summary>
        /// <value>The unique ID.</value>
        [DataMember]
        internal int Id
        {
            get;

            set;
        }

        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="intIdentifier1">The first Model Identifier to compare.</param>
        /// <param name="intIdentifier2">The second Model Identifier to compare.</param>
        /// <returns>
        ///   <c>true</c> if the instances are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public static bool operator ==(IntId<T> intIdentifier1, IntId<T> intIdentifier2)
        {
            return object.Equals(intIdentifier1, intIdentifier2);
        }

        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="intIdentifier1">The first Model Identifier to compare.</param>
        /// <param name="intIdentifier2">The second Model Identifier to compare.</param>
        /// <returns>
        ///   <c>true</c> if the instances are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public static bool operator !=(IntId<T> intIdentifier1, IntId<T> intIdentifier2)
        {
            return !object.Equals(intIdentifier1, intIdentifier2);
        }

        /// <summary>
        /// Performs an implicit conversion from <see cref="IntId{T}"/> to <see cref="System.Int32"/>.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator int(IntId<T> id)
        {
            return id == null ? int.MinValue : id.GetKey<int>();
        }

        /// <summary>
        /// Performs an implicit conversion from <see cref="System.Int32"/> to <see cref="IntId{T}"/>.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator IntId<T>(int id)
        {
            return new IntId<T> { Id = id };
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current
        /// <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current
        /// <see cref="T:System.Object"/>.</param>
        /// <returns>true if the specified <see cref="T:System.Object"/> is equal to the current
        /// <see cref="T:System.Object"/>; otherwise, false.</returns>
        /// <exception cref="T:System.NullReferenceException">The <paramref name="obj"/> parameter is null.</exception>
        public override bool Equals(object obj)
        {
            return this.Equals(obj as IModelId<T>);
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        public override int GetHashCode()
        {
            unchecked
            {
                var hash = 17;

                hash = (23 * hash) + (this.Origin == null ? 0 : this.Origin.GetHashCode());
                return (31 * hash) + this.GetKey<int>().GetHashCode();
            }
        }

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return this.Origin + ":" + this.GetKey<int>().ToString(CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Performs an equality check on the two model identifiers and returns <c>true</c> if they are equal;
        /// otherwise <c>false</c> is returned.  All implementations must also override the equal operator.
        /// </summary>
        /// <param name="obj">The identifier to compare against.</param>
        /// <returns>
        ///   <c>true</c> if the identifiers are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public override bool Equals(IModelId<T> obj)
        {
            if (obj == null)
            {
                return false;
            }

            return (obj.Origin == this.Origin) && (obj.GetKey<int>() == this.GetKey<int>());
        }

        /// <summary>
        /// The model instance identifier for the model object that this <see cref="ModelIdBase{T}"/> refers to.
        /// Typically, this is a database key, file name, or some other unique identifier.
        /// </summary>
        /// <typeparam name="TKeyDataType">The expected data type of the identifier.</typeparam>
        /// <returns>The unique key as the data type specified.</returns>
        public override TKeyDataType GetKey<TKeyDataType>()
        {
            return (TKeyDataType)Convert.ChangeType(this.Id, typeof(TKeyDataType), CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Generates an object from its string representation.
        /// </summary>
        /// <param name="value">The value of the model's type.</param>
        /// <returns>A new instance of this class as it's interface containing the value from the string.</returns>
        internal static ModelIdBase<T> FromString(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            int id;
            var originAndId = value.Split(new[] { ":" }, StringSplitOptions.None);

            if (originAndId.Length != 2)
            {
                throw new ArgumentOutOfRangeException("value", "value must be in the format of Origin:Identifier");
            }

            return int.TryParse(originAndId[1], NumberStyles.None, CultureInfo.InvariantCulture, out id)
                ? new IntId<T> { Id = id, Origin = originAndId[0] }
                : null;
        }
    }
}
</code>```

and, for completeness' sake of my codebase, I also wrote one for GUID entities, GuidId.cs:

```<code>namespace GenericIdentifiers
{
    // System namespaces
    using System;
    using System.Diagnostics;
    using System.Globalization;
    using System.Runtime.Serialization;

    /// <summary>
    /// Represents an abstraction of the database key for a Model Identifier.
    /// </summary>
    /// <typeparam name="T">The expected owner data type for this identifier.</typeparam>
    [DebuggerDisplay("Origin={Origin}, GUID={Id}")]
    [DataContract(IsReference = true)]
    public sealed class GuidId<T> : ModelIdBase<T> where T : class
    {
        /// <summary>
        /// Gets or sets the unique ID.
        /// </summary>
        /// <value>The unique ID.</value>
        [DataMember]
        internal Guid Id
        {
            get;

            set;
        }

        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="guidIdentifier1">The first Model Identifier to compare.</param>
        /// <param name="guidIdentifier2">The second Model Identifier to compare.</param>
        /// <returns>
        ///   <c>true</c> if the instances are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public static bool operator ==(GuidId<T> guidIdentifier1, GuidId<T> guidIdentifier2)
        {
            return object.Equals(guidIdentifier1, guidIdentifier2);
        }

        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="guidIdentifier1">The first Model Identifier to compare.</param>
        /// <param name="guidIdentifier2">The second Model Identifier to compare.</param>
        /// <returns>
        ///   <c>true</c> if the instances are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public static bool operator !=(GuidId<T> guidIdentifier1, GuidId<T> guidIdentifier2)
        {
            return !object.Equals(guidIdentifier1, guidIdentifier2);
        }

        /// <summary>
        /// Performs an implicit conversion from <see cref="GuidId{T}"/> to <see cref="System.Guid"/>.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator Guid(GuidId<T> id)
        {
            return id == null ? Guid.Empty : id.GetKey<Guid>();
        }

        /// <summary>
        /// Performs an implicit conversion from <see cref="System.Guid"/> to <see cref="GuidId{T}"/>.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator GuidId<T>(Guid id)
        {
            return new GuidId<T> { Id = id };
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current
        /// <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current
        /// <see cref="T:System.Object"/>.</param>
        /// <returns>true if the specified <see cref="T:System.Object"/> is equal to the current
        /// <see cref="T:System.Object"/>; otherwise, false.</returns>
        /// <exception cref="T:System.NullReferenceException">The <paramref name="obj"/> parameter is null.</exception>
        public override bool Equals(object obj)
        {
            return this.Equals(obj as IModelId<T>);
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        public override int GetHashCode()
        {
            unchecked
            {
                var hash = 17;

                hash = (23 * hash) + (this.Origin == null ? 0 : this.Origin.GetHashCode());
                return (31 * hash) + this.GetKey<Guid>().GetHashCode();
            }
        }

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return this.Origin + ":" + this.GetKey<Guid>();
        }

        /// <summary>
        /// Performs an equality check on the two model identifiers and returns <c>true</c> if they are equal;
        /// otherwise <c>false</c> is returned.  All implementations must also override the equal operator.
        /// </summary>
        /// <param name="obj">The identifier to compare against.</param>
        /// <returns>
        ///   <c>true</c> if the identifiers are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public override bool Equals(IModelId<T> obj)
        {
            if (obj == null)
            {
                return false;
            }

            return (obj.Origin == this.Origin) && (obj.GetKey<Guid>() == this.GetKey<Guid>());
        }

        /// <summary>
        /// The model instance identifier for the model object that this <see cref="ModelIdBase{T}"/> refers to.
        /// Typically, this is a database key, file name, or some other unique identifier.
        /// </summary>
        /// <typeparam name="TKeyDataType">The expected data type of the identifier.</typeparam>
        /// <returns>The unique key as the data type specified.</returns>
        public override TKeyDataType GetKey<TKeyDataType>()
        {
            return (TKeyDataType)Convert.ChangeType(this.Id, typeof(TKeyDataType), CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Generates an object from its string representation.
        /// </summary>
        /// <param name="value">The value of the model's type.</param>
        /// <returns>A new instance of this class as it's interface containing the value from the string.</returns>
        internal static ModelIdBase<T> FromString(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            Guid id;
            var originAndId = value.Split(new[] { ":" }, StringSplitOptions.None);

            if (originAndId.Length != 2)
            {
                throw new ArgumentOutOfRangeException("value", "value must be in the format of Origin:Identifier");
            }

            return Guid.TryParse(originAndId[1], out id) ? new GuidId<T> { Id = id, Origin = originAndId[0] } : null;
        }
    }
}
</code>```

Title: Pass ID or Object?

Body:
Will this be going over the wire (serialized/deserialized) any time now or in the future? Favor the single ID type over the who-knows-how-large full object.

If you're looking for type-safety of the ID to its entity, then there are code solutions as well. Let me know if you need an example.

Edit: expanding on type-safety of ID:

So, let's take your method:

public Foo GetItem(int id) {}

We only hope that the integer id that's passed in is for a Foo object. Someone could misuse it and pass in some Bar object's integer ID or even just by hand type in 812341. It's not type safe to Foo. Secondly, even if you used the pass an object Foo version, I'm sure Foo has an ID field which is int which someone can possibly modify. And lastly, you cannot use method overloading if these exist in a class together as only the return type varies. Let's rewrite this method a bit to look type-safe in C#:

public Foo GetItem(IntId<Foo> id) {}

So I've introduced a class named IntId which has a generic piece to it. In this particular case, I want an int that's associated with Foo only. I can't just pass in a naked int nor can I assign an IntId<Bar> to it accidentally. So below is how I've written these type-safe identifiers. Do take note that the manipulation of the actual underlying int is only at your data access layer. Anything above that only sees the strong type and has no (direct) access to its internal int ID. It should have no reason to.

IModelId.cs interface:

namespace GenericIdentifiers
{
    using System.Runtime.Serialization;
    using System.ServiceModel;

    /// <summary>
    /// Defines an interface for an object's unique key in order to abstract out the underlying key
    /// generation/maintenance mechanism.
    /// </summary>
    /// <typeparam name="T">The type the key is representing.</typeparam>
    [ServiceContract]
    public interface IModelId<T> where T : class
    {
        /// <summary>
        /// Gets a string representation of the domain the model originated from.
        /// </summary>
        /// <value>The origin.</value>
        [DataMember]
        string Origin
        {
            [OperationContract]get;
        }

        /// <summary>
        /// The model instance identifier for the model object that this <see cref="IModelId{T}"/> refers to.
        /// Typically, this is a database key, file name, or some other unique identifier.
        /// <typeparam name="TKeyDataType">The expected data type of the identifier.</typeparam>
        /// </summary>
        /// <typeparam name="TKeyDataType">The expected data type of the identifier.</typeparam>
        /// <returns>The unique key as the data type specified.</returns>
        [OperationContract]
        TKeyDataType GetKey<TKeyDataType>();

        /// <summary>
        /// Performs an equality check on the two model identifiers and returns <c>true</c> if they are equal; otherwise
        /// <c>false</c> is returned.  All implementations must also override the equal operator.
        /// </summary>
        /// <param name="obj">The identifier to compare against.</param>
        /// <returns><c>true</c> if the identifiers are equal; otherwise <c>false</c> is returned.</returns>
        [OperationContract]
        bool Equals(IModelId<T> obj);
    }
}

ModelIdBase.cs base class:

namespace GenericIdentifiers
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.Serialization;

    /// <summary>
    /// Represents an object's unique key in order to abstract out the underlying key generation/maintenance mechanism.
    /// </summary>
    /// <typeparam name="T">The type the key is representing.</typeparam>
    [DataContract(IsReference = true)]
    [KnownType("GetKnownTypes")]
    public abstract class ModelIdBase<T> : IModelId<T> where T : class
    {
        /// <summary>
        /// Gets a string representation of the domain the model originated from.
        /// </summary>
        [DataMember]
        public string Origin
        {
            get;

            internal set;
        }

        /// <summary>
        /// The model instance identifier for the model object that this <see cref="ModelIdBase{T}"/> refers to.
        /// Typically, this is a database key, file name, or some other unique identifier.
        /// </summary>
        /// <typeparam name="TKeyDataType">The expected data type of the identifier.</typeparam>
        /// <returns>The unique key as the data type specified.</returns>
        public abstract TKeyDataType GetKey<TKeyDataType>();

        /// <summary>
        /// Performs an equality check on the two model identifiers and returns <c>true</c> if they are equal;
        /// otherwise <c>false</c> is returned. All implementations must also override the equal operator.
        /// </summary>
        /// <param name="obj">The identifier to compare against.</param>
        /// <returns>
        ///   <c>true</c> if the identifiers are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public abstract bool Equals(IModelId<T> obj);

        protected static IEnumerable<Type> GetKnownTypes()
        {
            return new[] { typeof(IntId<T>), typeof(GuidId<T>) };
        }
    }
}

IntId.cs:

namespace GenericIdentifiers
{
    // System namespaces
    using System;
    using System.Diagnostics;
    using System.Globalization;
    using System.Runtime.Serialization;

    /// <summary>
    /// Represents an abstraction of the database key for a Model Identifier.
    /// </summary>
    /// <typeparam name="T">The expected owner data type for this identifier.</typeparam>
    [DebuggerDisplay("Origin={Origin}, Integer Identifier={Id}")]
    [DataContract(IsReference = true)]
    public sealed class IntId<T> : ModelIdBase<T> where T : class
    {
        /// <summary>
        /// Gets or sets the unique ID.
        /// </summary>
        /// <value>The unique ID.</value>
        [DataMember]
        internal int Id
        {
            get;

            set;
        }

        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="intIdentifier1">The first Model Identifier to compare.</param>
        /// <param name="intIdentifier2">The second Model Identifier to compare.</param>
        /// <returns>
        ///   <c>true</c> if the instances are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public static bool operator ==(IntId<T> intIdentifier1, IntId<T> intIdentifier2)
        {
            return object.Equals(intIdentifier1, intIdentifier2);
        }

        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="intIdentifier1">The first Model Identifier to compare.</param>
        /// <param name="intIdentifier2">The second Model Identifier to compare.</param>
        /// <returns>
        ///   <c>true</c> if the instances are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public static bool operator !=(IntId<T> intIdentifier1, IntId<T> intIdentifier2)
        {
            return !object.Equals(intIdentifier1, intIdentifier2);
        }

        /// <summary>
        /// Performs an implicit conversion from <see cref="IntId{T}"/> to <see cref="System.Int32"/>.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator int(IntId<T> id)
        {
            return id == null ? int.MinValue : id.GetKey<int>();
        }

        /// <summary>
        /// Performs an implicit conversion from <see cref="System.Int32"/> to <see cref="IntId{T}"/>.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator IntId<T>(int id)
        {
            return new IntId<T> { Id = id };
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current
        /// <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current
        /// <see cref="T:System.Object"/>.</param>
        /// <returns>true if the specified <see cref="T:System.Object"/> is equal to the current
        /// <see cref="T:System.Object"/>; otherwise, false.</returns>
        /// <exception cref="T:System.NullReferenceException">The <paramref name="obj"/> parameter is null.</exception>
        public override bool Equals(object obj)
        {
            return this.Equals(obj as IModelId<T>);
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        public override int GetHashCode()
        {
            unchecked
            {
                var hash = 17;

                hash = (23 * hash) + (this.Origin == null ? 0 : this.Origin.GetHashCode());
                return (31 * hash) + this.GetKey<int>().GetHashCode();
            }
        }

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return this.Origin + ":" + this.GetKey<int>().ToString(CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Performs an equality check on the two model identifiers and returns <c>true</c> if they are equal;
        /// otherwise <c>false</c> is returned.  All implementations must also override the equal operator.
        /// </summary>
        /// <param name="obj">The identifier to compare against.</param>
        /// <returns>
        ///   <c>true</c> if the identifiers are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public override bool Equals(IModelId<T> obj)
        {
            if (obj == null)
            {
                return false;
            }

            return (obj.Origin == this.Origin) && (obj.GetKey<int>() == this.GetKey<int>());
        }

        /// <summary>
        /// The model instance identifier for the model object that this <see cref="ModelIdBase{T}"/> refers to.
        /// Typically, this is a database key, file name, or some other unique identifier.
        /// </summary>
        /// <typeparam name="TKeyDataType">The expected data type of the identifier.</typeparam>
        /// <returns>The unique key as the data type specified.</returns>
        public override TKeyDataType GetKey<TKeyDataType>()
        {
            return (TKeyDataType)Convert.ChangeType(this.Id, typeof(TKeyDataType), CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Generates an object from its string representation.
        /// </summary>
        /// <param name="value">The value of the model's type.</param>
        /// <returns>A new instance of this class as it's interface containing the value from the string.</returns>
        internal static ModelIdBase<T> FromString(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            int id;
            var originAndId = value.Split(new[] { ":" }, StringSplitOptions.None);

            if (originAndId.Length != 2)
            {
                throw new ArgumentOutOfRangeException("value", "value must be in the format of Origin:Identifier");
            }

            return int.TryParse(originAndId[1], NumberStyles.None, CultureInfo.InvariantCulture, out id)
                ? new IntId<T> { Id = id, Origin = originAndId[0] }
                : null;
        }
    }
}

and, for completeness' sake of my codebase, I also wrote one for GUID entities, GuidId.cs:

namespace GenericIdentifiers
{
    // System namespaces
    using System;
    using System.Diagnostics;
    using System.Globalization;
    using System.Runtime.Serialization;

    /// <summary>
    /// Represents an abstraction of the database key for a Model Identifier.
    /// </summary>
    /// <typeparam name="T">The expected owner data type for this identifier.</typeparam>
    [DebuggerDisplay("Origin={Origin}, GUID={Id}")]
    [DataContract(IsReference = true)]
    public sealed class GuidId<T> : ModelIdBase<T> where T : class
    {
        /// <summary>
        /// Gets or sets the unique ID.
        /// </summary>
        /// <value>The unique ID.</value>
        [DataMember]
        internal Guid Id
        {
            get;

            set;
        }

        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="guidIdentifier1">The first Model Identifier to compare.</param>
        /// <param name="guidIdentifier2">The second Model Identifier to compare.</param>
        /// <returns>
        ///   <c>true</c> if the instances are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public static bool operator ==(GuidId<T> guidIdentifier1, GuidId<T> guidIdentifier2)
        {
            return object.Equals(guidIdentifier1, guidIdentifier2);
        }

        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="guidIdentifier1">The first Model Identifier to compare.</param>
        /// <param name="guidIdentifier2">The second Model Identifier to compare.</param>
        /// <returns>
        ///   <c>true</c> if the instances are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public static bool operator !=(GuidId<T> guidIdentifier1, GuidId<T> guidIdentifier2)
        {
            return !object.Equals(guidIdentifier1, guidIdentifier2);
        }

        /// <summary>
        /// Performs an implicit conversion from <see cref="GuidId{T}"/> to <see cref="System.Guid"/>.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator Guid(GuidId<T> id)
        {
            return id == null ? Guid.Empty : id.GetKey<Guid>();
        }

        /// <summary>
        /// Performs an implicit conversion from <see cref="System.Guid"/> to <see cref="GuidId{T}"/>.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns>The result of the conversion.</returns>
        public static implicit operator GuidId<T>(Guid id)
        {
            return new GuidId<T> { Id = id };
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current
        /// <see cref="T:System.Object"/>.
        /// </summary>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current
        /// <see cref="T:System.Object"/>.</param>
        /// <returns>true if the specified <see cref="T:System.Object"/> is equal to the current
        /// <see cref="T:System.Object"/>; otherwise, false.</returns>
        /// <exception cref="T:System.NullReferenceException">The <paramref name="obj"/> parameter is null.</exception>
        public override bool Equals(object obj)
        {
            return this.Equals(obj as IModelId<T>);
        }

        /// <summary>
        /// Serves as a hash function for a particular type.
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        public override int GetHashCode()
        {
            unchecked
            {
                var hash = 17;

                hash = (23 * hash) + (this.Origin == null ? 0 : this.Origin.GetHashCode());
                return (31 * hash) + this.GetKey<Guid>().GetHashCode();
            }
        }

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return this.Origin + ":" + this.GetKey<Guid>();
        }

        /// <summary>
        /// Performs an equality check on the two model identifiers and returns <c>true</c> if they are equal;
        /// otherwise <c>false</c> is returned.  All implementations must also override the equal operator.
        /// </summary>
        /// <param name="obj">The identifier to compare against.</param>
        /// <returns>
        ///   <c>true</c> if the identifiers are equal; otherwise <c>false</c> is returned.
        /// </returns>
        public override bool Equals(IModelId<T> obj)
        {
            if (obj == null)
            {
                return false;
            }

            return (obj.Origin == this.Origin) && (obj.GetKey<Guid>() == this.GetKey<Guid>());
        }

        /// <summary>
        /// The model instance identifier for the model object that this <see cref="ModelIdBase{T}"/> refers to.
        /// Typically, this is a database key, file name, or some other unique identifier.
        /// </summary>
        /// <typeparam name="TKeyDataType">The expected data type of the identifier.</typeparam>
        /// <returns>The unique key as the data type specified.</returns>
        public override TKeyDataType GetKey<TKeyDataType>()
        {
            return (TKeyDataType)Convert.ChangeType(this.Id, typeof(TKeyDataType), CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Generates an object from its string representation.
        /// </summary>
        /// <param name="value">The value of the model's type.</param>
        /// <returns>A new instance of this class as it's interface containing the value from the string.</returns>
        internal static ModelIdBase<T> FromString(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            Guid id;
            var originAndId = value.Split(new[] { ":" }, StringSplitOptions.None);

            if (originAndId.Length != 2)
            {
                throw new ArgumentOutOfRangeException("value", "value must be in the format of Origin:Identifier");
            }

            return Guid.TryParse(originAndId[1], out id) ? new GuidId<T> { Id = id, Origin = originAndId[0] } : null;
        }
    }
}


问:
When do we need to apply a software development methodology?
There are many software development methodologies - SCRUM, agile, XP, etc. - and they all have there advantages and disadvantages I suppose.

But when do we really need to apply them? Surely they are not necessary for small 1-man projects, but for large 50+ teams you can most certainly not go about ad-hoc:ing the whole thing.

So what's the line for when to use and when to not use such a methodology, if there indeed is one?

答:
Even in a strictly 1-man project (you coding software for yourself with no schedule) you have to:

Figure out what you actually want/need.

Figure out how it can be done (various approaches).

Implement it.

See what you got and go back to 1), refining the requirements.

You could do it informally (cowboy), but given that the 1-man project is a special edge case (usually there's at least you and someone else you're working for), doing it with some well founded light formalism is virtually always preferable. Keep in mind that the core of the Agile Manifesto is really just a few principles. The formal methodologies (e.g. Scrum) aimed to reach those principles can and should be tailored according to the team size etc.

ContentLicense: CC BY-SA 2.5


问:
Is it wise to be going back and forth between two programming languages?
I have been writing quite a lot of PHP for nearly two years. Now I am doing .NET (mainly c#) development. However, sometimes I go back and do some php.

My main question is, is it wise for me to continue doing this or should I continue development in C#? Would this harm me in the long run (mind you my main goal is not to be a jack o all trades) or is it a good practice to be doing?

答:
People retiring this year started their careers before C was created.  It's safe to say you might switch programming languages once or twice in your career.  You don't want to work for employers who don't understand that.

When you're new, context switching between two languages is a lot more difficult, so you'll be more productive if you work at least 4-8 hours in one language before switching.  Later you'll be able to switch instantly without a loss in productivity.  In other words, using two languages will eventually become a strength instead of slowing you down.

ContentLicense: CC BY-SA 3.0


答:
Would this harm me in the long run (mind you my main goal is not to be a jack o all trades) or is it a good practice to be doing?

Knowing two or more languages would never harm you. Knowing your languages very shallow (without understanding inner-workings) may harm you.

My personally preference was always mastering one object-oriented programming language first. This would provide you in depth learning of all programming concepts, and ease to learn next one once there is a need.

is it a good practice to be doing?

Absolutely yes!

I would suggest definitely to learn more than one and practice them by building some applications. Meanwhile, you may also plan to learn some scripting languages (jQuery, KnockoutJs, etc.) and libraries if you are doing or planning to do web-development.

Title: Is it wise to be going back and forth between two programming languages?

Body:
I have been writing quite a lot of PHP for nearly two years. Now I am doing .NET (mainly c#) development. However, sometimes I go back and do some php.

My main question is, is it wise for me to continue doing this or should I continue development in C#? Would this harm me in the long run (mind you my main goal is not to be a jack o all trades) or is it a good practice to be doing?


问:
Pass ID or Object?
When providing a business logic method to get a domain entity, should the parameter accept an object or an ID? For example, should we do this:

```<code>public Foo GetItem(int id) {}
</code>```

or this:

```<code>public Foo GetItem(Foo foo) {}
</code>```

I believe in passing objects around, in their entirety, but what about this case where we're getting an object and we only know the ID? Should the caller create an empty Foo and set the ID, or should it just pass the ID to the method? Since the incoming Foo will be empty, except for the ID, I don't see the benefit of the caller having to create a Foo and set its ID when it could just send the ID to the GetItem() method.

答:
It depends on what your method does.

Generally for Get methods, it is common sense to pass id parameter and get the object back. While for update or SET methods you would sent the whole object to be set/updated.

In some other cases where your method is passing search parameters (as a collection of individual primitive types) to retrieve a set of results, it might be wise to use a container to hold your search parameters. This is useful if in long run number of parameters will change. Thus, you would not need to change the signature of your method, add or remove parameter in all over the places.

Title: Pass ID or Object?


问:
How to unit test a jsp file?
I'm developing a Java 6 EE application and I'm testing my jsp code with another one with a testing version of the function calls and code used in the original one but it seems loose and impractical. Is there a good way to accomplish this kind of testing?</p>

答:
I don't think there is a good way to test JSPs, mainly because they were developed before unit testing became a focus of development.

Robert Martin wrote an article several years ago about hacking the JSP compiler so that you can direct, non-container based unit tests. His idea was good, but it was broken with the very next TomCat major release. There's just too much magic going on.

I disagree with the "just don't add code and you won't need to test it" idea. OBVIOUSLY you should not be putting code in the JSP. But nonetheless a complex UI will often have display logic that could be profitably unit tested.

Consider this example:

```<code><c:choose>
  <c:when test="${mydto.showAdminMenu}">
   The admin menu....
  </c:when>
  <c:otherwise>
    Something completely different
  </c:otherwise>
</c:choose>
</code>```

This code is already well factored: the logic to decide whether we show the admin menu is not in the view. Nonetheless, if there were an easy way to unit test JSPs, then we could write a test to show that the behavior we want actually appears, and it would protect us from a change to the page that accidentally made the admin menu visible when it shouldn't be.

Title: How to unit test a jsp file?

Body:
I don't think there is a good way to test JSPs, mainly because they were developed before unit testing became a focus of development.

Robert Martin wrote an article several years ago about hacking the JSP compiler so that you can direct, non-container based unit tests. His idea was good, but it was broken with the very next TomCat major release. There's just too much magic going on.

I disagree with the "just don't add code and you won't need to test it" idea. OBVIOUSLY you should not be putting code in the JSP. But nonetheless a complex UI will often have display logic that could be profitably unit tested.

Consider this example:

<c:choose>
  <c:when test="${mydto.showAdminMenu}">
   The admin menu....
  </c:when>
  <c:otherwise>
    Something completely different
  </c:otherwise>
</c:choose>

This code is already well factored: the logic to decide whether we show the admin menu is not in the view. Nonetheless, if there were an easy way to unit test JSPs, then we could write a test to show that the behavior we want actually appears, and it would protect us from a change to the page that accidentally made the admin menu visible when it shouldn't be.


答:
I think you would be wise to establish the lookup on the identifier of the object as Ben Voigt has suggested.

However, remember that the type of your object's identifier may change. As such, I would create a identifier class for each of my items, and only allow looking up the items via these instances of these identifiers. See the following example:

```<code>public class Item
{
  public class ItemId
  {
    public int Id { get; set;}
  }

  public ItemId Id; { get; set; }
}

public interface Service
{
  Item GetItem(ItemId id);
}
</code>```

I used encapsulation, but you can also make Item inherit from ItemId.

That way, if the type of your id changes along the road, you don't have to change anything in the Item class, or in the signature of the GetItem method. Only in the implementation of the service would you have to change your code (which is the only thing that changes in all cases anyway)

Title: Pass ID or Object?

Body:
When providing a business logic method to get a domain entity, should the parameter accept an object or an ID? For example, should we do this:

```<code>public Foo GetItem(int id) {}
</code>```

or this:

```<code>public Foo GetItem(Foo foo) {}
</code>```

I believe in passing objects around, in their entirety, but what about this case where we're getting an object and we only know the ID? Should the caller create an empty Foo and set the ID, or should it just pass the ID to the method? Since the incoming Foo will be empty, except for the ID, I don't see the benefit of the caller having to create a Foo and set its ID when it could just send the ID to the GetItem() method.

Body:
I think you would be wise to establish the lookup on the identifier of the object as Ben Voigt has suggested.

However, remember that the type of your object's identifier may change. As such, I would create a identifier class for each of my items, and only allow looking up the items via these instances of these identifiers. See the following example:

public class Item
{
  public class ItemId
  {
    public int Id { get; set;}
  }

  public ItemId Id; { get; set; }
}

public interface Service
{
  Item GetItem(ItemId id);
}

I used encapsulation, but you can also make Item inherit from ItemId.

That way, if the type of your id changes along the road, you don't have to change anything in the Item class, or in the signature of the GetItem method. Only in the implementation of the service would you have to change your code (which is the only thing that changes in all cases anyway)


答:
Learning a new programming language will teach you things about programming that you can apply to the languages you already know. You should definitely consider at least playing with some other languages, even if you don't use them professionally, rather than just having so few.

Ideally, one that's very different in approach to those you already know.


答:
The approach to the development you take must maximise the ROI of the project. Depending on the project nature and the resources available the right direction to take may be different.

There are two obvious rules though, common to designing any functioning system

the performance and delivarables must
be quantatively measurable, metrics
must be as simpe and as unambiguous
as possible. (reflecting Graham Lee's comment:) As it is not always possible to set up adequate metrics at the very beginning, metrics should evolve as project goes on to reflect the growing expertise of the manangement in the problem domain

the risks assessement
procedures (partially based on above
metrics) must be set up before the
project starts, and dynamically
updated as project evolves. The
mitigation plan must exist for every
type of identified potential risk and
shoud be triggered accordingly

The need in asource code version control, system backups, QA procedures, and many other essential bits is just another part of the project risk management.

One more consideration -- the bigger the company is and the more the departments like yours are the more desired it is to have some converged practices used globally to ensure minimum overhead on relocating resources from project to project and also minimum overhead on senior management required to understand the details of projects in departments they run.

Title: When do we need to apply a software development methodology?

Body:
There are many software development methodologies - SCRUM, agile, XP, etc. - and they all have there advantages and disadvantages I suppose.

But when do we really need to apply them? Surely they are not necessary for small 1-man projects, but for large 50+ teams you can most certainly not go about ad-hoc:ing the whole thing.

So what's the line for when to use and when to not use such a methodology, if there indeed is one?


问:
How to avoid the pitfalls of static analysis
I'm working at a company that would score 11 on Joel Test - at least on paper.

In practice, however, nothing works quite as well as expected, and the project has been on DEFCON 1 for half a year. Now, most of my peers are happy if they can go back home at 6pm - on Sunday.

One of the apparently good practices that struck me as not working is the use of static analysis tools. The project both tracks gcc -Wall warnings and a proprietary and very expensive "C/C++" tool.

Gcc warnings do more often than not point to real(if most of the time inoffensive) bugs.

The proprietary tools, however, list things such as implicit casts and sizeof'ing a string literal. Implicit casts are also blacklisted on their stylebook.

The standard practice is that people is pressed to make every single warning shut up. Note that this does exclude warnings that are predominantly false positives, this is not the problem.

The result is:

People add type casts to every rvalue and to every argument hiding real problematic type mismatches in the process.

People introduce off by one bugs, or use a different problematic language feature.(strlen instead of sizeof, strncpy instead of strcpy, etc.)

The warnings are silenced.

The bug reports start rolling in.

The main point is the original code was working and written by people who were playing safe within their language abilities whereas the fixes were not.

Now, I don't really think this company can be saved. However, I would like to know if there is a better, preferably working, way to use the "pro" tools or if I should just avoid using them altogether in case I am the one making the decision in the future.

A solution which doesn't assume all programmers are geniuses that can't err. Because well, if they are, then there is no need to use the tools in the first place.

答:
I'm working at a company that would score 11 on Joel Test - at least on paper.

That test is just mildly relevant to software companies. I don't understand the hype about it. You can score 12 and still have 100% crap programmers. People matter far more than tools.

The proprietary tools, however, list things such as implicit casts and sizeof'ing a string literal. Implicit casts are also blacklisted on their stylebook. The standard practice is that people is pressed to make every single warning shut up. Note that this does exclude warnings that are predominantly false positives, this is not the problem.

This is the largest problem with all static analysers: too many false positives. The only way to handle this is to learn in detail why the tool was set to give a warning for a certain issue. Only then can you make qualified assumptions of whether a warning is false or not.

For the specific cast of implicit typecasts, it is there because of some very common, subtle and dangerous bugs in the C language, caused by the two (moronic) implicit type promotion rules in C. They are formally known as the integer promotion rules and the usual arithmetic conversions. I think less than one in ten of all professional C programmers can explain what these two rules do, and what they don't do. And yet these rules are extremely fundamental and applied thousands of times between the lines in any normal C program.

The MISRA-C standard devoted a whole chapter to explain these dangerous implicit conversion rules, and then they added numerous fairly complex rules for how to avoid bugs caused by implicit conversion. This had quite some impact on all static analysers in the market.

I would recommend any C programmer to read that MISRA-C chapter, or at the very least Google the two promotion rules I mentioned and read as much about them as you can. You can only ignore the static analyser when you know everything there is to know about these rules.

Now, I don't really think this company can be saved. However, I would like to know if there is a better, preferably working, way to use the "pro" tools or if I should just avoid using them altogether in case I am the one making the decision in the future.

A solution which doesn't assume all programmers are geniuses that can't err. Because well, if they are, then there is no need to use the tools in the first place.

There is no easy way around it. The real problem is actually not the tool, but the obscure C language. It may seem to be an easy language at a brief glance, but there are plenty of illogical and strange mechanisms going on between the lines. And there are also hundreds of cases of undefined/unspecified/impl.specific behavior in the language. Most of them you must learn and avoid.

So you must either become a veteran C programmer that understands all these obscure warnings, or you must be in a team with at least one such person. Companies that only hire a bunch of junior programmers with no veteran in the team should not use these tools, nor should they work with high-integrity software development.


问:
How to select drawing system when requirements not yet known?
We're developping an application for 2D data processing and display. At the moment data is displayed by converting each point to a color depending on intensity, so in rather low level code. This works well. A new feature is displaying a grid and a bunch of lines that can be moved with the mouse on that image.

As usual when new technologies are going to be picked, I made a little demo to test some things out: using the current data plot, a line is drawn on top that can be moved up/down with the mouse, and at the same time there is text displaying the cursor coordinates. I tried some different ways: using a Canvas, using a somehwat lower level DrawingContext and using the low level WriteableBitmapEx api.

To me, there was no real difference in ease of coding nor display speed. Yes the Canvas option had a couple of lines less code than the others, while I had the impression the lower level options were somewhat faster to display. But no huge differenes making me pick one immediately.

So the problem now is: I have no idea how to select the most suitable system for the job, but it is a very important decision to make since the graphical part of the app will likely continue to grow. Needless to say it would be a small disaster if we pick A now, and in one year we figure out B would have been way better. Normally I'd select the fastest or most convenient option, or look at future requirements and use the system that seems to fit best, but in this case there is simply not enough difference, and future requirements are not exactly known: for now we think it's sufficient if we can draw lines, circles and some text, and update speed is not that important. However the application is in it's early stage, so is the underlying hardware and there are less than 100 customers. That however, might change rapidly. And so can requirements.

Question is simple: what to do? Some options I've been thinkig about:

pick one that 'feels' best (WriteableBitmapEx but probably just because I have an affinity with lowlevel stuff)

pick the one with the least amount of code (Canvas, also seems very easy on the UI level with effects and mouse events and what not)

make a more extensive demo so differences become more clear
pick one, but put everything behind an interface so the implementation can be swapped later (might be quite some work)

答:
With a decent decoupled design, realizing you need something more efficient down the road and implementing a new rendering mechanism shouldn't be as though a task as it would seem.

My advice would be to pick the component that you and your team is most comfortable with (whether it be the easiest or the one closest to what you have worked with in the past).  Then, your biggest concern should be to decouple model/logic as much as possible from rendering to be able to reimplement a new rendering system on top of the same interface should the need arise.

You're not at a point in time where you can make optimization as requirements are not well known and you don't have the full-fledged system to work with so any optimization done right now is likely time wasted.


问:
How can I prevent users from merging origin/X into Y in git?
Is it possible to force git to only merge remote tracking branches into the corresponding local branch? E.g. assume origin/X tracks X on origin and corresponds to local X and the same for origin/Y and Y. I want to prevent users to do git checkout Y; git merge origin/X. Is it possible? How?

Edit:

To make it clear: The workflow is not the problem. People try to merge the wrong branches because they forgot to checkout the correct branch before merging. It is not about "offenders" or pushing to the central repo. It's just people forgetting at which branch they are. The last "incident" was literally:

"I should commit and push real quick before I leave.

git add .

git commit -am 'Feature Y'

git push origin

Whoops, whats that. It tells me to merge branch origin/X first. OK whatevs.

git merge origin/X

Whoops, whats that now. Lots of merge conflicts. What have I done. I better call somebody..."

The user was working in branch Y and did not understand what the git push origin was saying. It told it that origin/X needed merging and that's what he did, because he wanted to "push real quick". In the case above branch X was one commit ahead of the local X, so pushing all branches yielded the "needs merging" error.

I adjusted the "workflow" now to always push a branch explicitly, e.g. git push origin Y instead of just git push origin, but that's not curing the problem. It should (usually) not be allowed without a warning to merge origin/X with Y. For merging feature branches X and Y can be merged.

答:
I think that you may be approaching this from the wrong angle.

Why is merging origin/X into Y a problem? If it is because, for instance, Y is a release branch (which is tracking origin/Y), while origin/X is a development branch, and you don't development code leaking into a production release, then it is more important to control origin/Y than to control Y.

As Christopher suggests in a comment, this should really be taken care of by your workflow.

To prevent mistakes though, as Ikke points out, you may want to make use of permissions to limit who can update different remote references. For example, gitolite allows very fine grained access control. From Scott Chacon's excellent Pro Git:

Gitolite allows you to specify permissions not just by repository, but also by branch or tag names within each repository. That is, you can specify that certain people (or groups of people) can only push certain "refs" (branches or tags) but not others.

One option is to only allow your continuous integration server to push to your release branches, and only then after your integration and unit tests have passed. This sort of automated workflow can really help prevent mistakes propagating.


问:
What are the Top Developer Productivity Tools/Plugins for Java in Eclipse?
I personally use CodeRush in Visual Studio 2010 to do refactoring, write code faster with templates and generally navigate my code 10 times faster than stock VS.  Recently, I've been working on another Android app and got to thinking...What are the top productivity plugins for Eclipse?

Preferably free. I'm looking for plugins that help write in Java, not PHP or Rails or any of the other languages Eclipse supports.

答:
You may find subclipse a very handy plugin; it makes it very intuitive whether there's changes to be committed or not.

Another suggestion is don't look for more plugins, look into eclipse itself because the features it provides, such as refatoring and source generating, is really very enough for everyday java programming.

I have switched from C++ to Java for around 1 year and really enjoyed the magics eclipse done to me. It's awesome!


答:
No, there is nothing wrong with learning multiple languages and using them all fairly often. In my day-to-day I can encounter Ruby, PHP, JavaScript, CoffeeScript, Python and occasionally C. I know all of these languages fairly well and going from one to another just flips a switch in my brain. Sure I miss features of some languages when I go to another but you'll get over that.

I try to always have a language I'm learning in-depth and then another one as an "up and coming". This way you always have a clear educational goal and then something on the horizon. Right now Ruby is my main language and I'm experimenting with Go. I'll probably never get a job as a Go developer but learning a new language has made be a better developer.

When I interview a developer I always like to see a few different languages on their resume. If a developer on has "C/C++" or "PHP and Javascript" on their resume they look a lot less interesting than someone who has a firm grasp of 4 or 5 languages. Make sure you feel comfortable in any language you list, anything on your resume is fair game in the interview!

In short: Using multiple languages regularly is a sign of a good developer who cares about their craft. Keep coding!


问:
How big does my project need to be for me to unit test it?
I assume that my project is decoupled enough to allow for unit testing. But how big, exactly, in terms of clases and functions does my project need to be to make unit testing worthwhile?

We all make mistakes and no one's perfect, but I consider myself a decent programmer to handle small projects' errors with stepping through. Or is unit testing a hard necessity no matter of what size your project is?

答:
Unless you are going to write code without testing it, you are always going to incur the cost of testing.

The difference between having unit tests and not having them is the difference between the cost of writing the test and the cost of running it compared to the cost of testing by hand.

If the cost of writing a unit test is 2 minutes and the cost of running the unit test is practically 0, but the cost of manually testing the code is 1 minute, then you break even when you have run the test twice.

For many years I was under the misapprehension that I didn't have enough time to write unit tests for my code. When I did write tests, they were bloated, heavy things which only encouraged me to think that I should only ever write unit tests when I knew they were needed.

Recently I've been encouraged to use Test Driven Development and I found it to be a complete revelation. I'm now firmly convinced that I don't have the time not to write unit-tests.

In my experience, by developing with testing in mind you end up with cleaner interfaces, more focussed classes & modules and generally more SOLID, testable code.

Every time I work with legacy code which doesn't have unit tests and I have to manually test something, I keep thinking "this would be so much quicker if this code already had unit tests". Every time I have to try and add unit test functionality to code with high coupling, I keep thinking "this would be so much easier if it had been written in a de-coupled way".

TL;DR version:

Write a test when the cost of writing the test, plus the cost of running it as many times as you need to is likely to be less than the cost of manually testing it as many times as you need to.

Remember though that if you use TDD, the cost of writing tests is likely to come down as you get better at it, and unless the code is absolutely trivial, you will probably end up running your tests more often than you expect.


问:
Where do I place my example implementations in my framework?
I've created a pretty simple templating framework and have default implementations for some of my interfaces used for passing around information. I store these in MyFramework.Default namespace

However, I am unsure of where to place example implementations, such as a template that creates a concrete class. This template seems like it would be useful to people who use my framework, but I am not sure if it belongs in a separate assembly, or perhaps a namespace within the framework.

If it's a namespace, is there any convention for its name?

答:
Separate Assembly?

The answer here depends upon how you intend the examples to be used.

If they are templates that can then be directly reused by others within the framework, include them in the assembly.

If the intent is a copy and paste type exercise, put them in a separate assembly.

Namespace

Here, I would suggest that you use a separate namespace regardless of how the examples are to be used.  In general, you would expect the users of your framework to have their own namespaces surrounding their work and integrating with your framework's namespace.  It will make the example more valid by following that model yourself.

Likewise, reverse that advice if you really intend them to extend your framework's namespace.


问:
Question on design of current pagination implementations
I have checked pagination implementations on asp.net mvc specifically and i really feel that there is something less efficient in implementations.

First of all all implementations use pagination values like below.

```<code>public ActionResult MostPopulars(int pageIndex,int pageSize)
{

}
</code>```

The thing that i feel wrong is pageIndex and pageSize totally should be member of Pagination class otherwise this way looks so much functional way. Also it simplify unnecesary paramater pass in tiers of application.

Second thing is that they use below interface.

```<code>public interface IPagedList<T> : IList<T>
{
    int PageCount { get; }
    int TotalItemCount { get; }
    int PageIndex { get; }
    int PageNumber { get; }
    int PageSize { get; }
    bool HasPreviousPage { get; }
    bool HasNextPage { get; }
    bool IsFirstPage { get; }
    bool IsLastPage { get; }
}
</code>```

If i want to routing my pagination to different action so i have to create new view model for encapsulate action name in it or even controller name. Another solution can be that sending this interfaced model to view then specify action and controller hard coded in pager method as parameter but i am losing totally re-usability of my view because it is strictly depends on just one action.

Another thing is that they use below code in view

```<code>Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount)
</code>```

If the model is IPagedList why they don't provide an overload method like @Html.Pager(Model) or even better one is @Html.Pager(). You know that we know model type in this way. Before i was doing mistake because i was using Model.PageIndex instead of Model.PageNumber.

Another big issue is they strongly rely on IQueryable interface. How they know that i use IQueryable in my data layer ? I would expected that they work simply with collections that is keep pagination implementation persistence ignorant.

What is wrong about my improvement ideas over their pagination implementations ?
What is their reason to not implement their paginations in this way ?

答:
As user8685 stated: your interface seems redundant to existing MVC stuff and principles.

Try this: information you require from IPagedList, like page index etc. should be implemented in business logic layer and fed to the view/page through a generic model that can be fed back to the server and safely cast and processed there. Why? Because what you are collecting here clearly is an input to your information system and as such belongs to layers lower than UI.

This way may not be the best way to go and is certainly not the quickest, but should make it easier to see what you really need in terms of abstraction and data architecture and thus help you remove redundancy.

Also, existing helpers often contain too much overhead for simple usage and sometimes obfuscate the big picture.


答: Two languages may help you or not - that depends. It will not harm you, that's for sure. Many devs tend to think that using something else apart from the 'main language' is pure waste of time but I strongly disagree. Learning another language (and using it) is a pure benefit: it gives you a different perspective on how to solve problems. It may happen that you will start using one of the languages for particular tasks at all times (as it happened to me after I had a chance to learn and use Python).</p>


答:
Your example implementations should be in your unit test assembly (you really should have one, it is the easiest way to test any kind of general library you are building). Examples of using a library will often serve well as some kind of test, and vice versa. Since your unit test assembly is linked against your testing framework (which you normally don't want to deploy), it must be a separate assembly.

Concerning namespace I totally agree to GlenH7.

Title: Where do I place my example implementations in my framework?

Body:
I've created a pretty simple templating framework and have default implementations for some of my interfaces used for passing around information. I store these in MyFramework.Default namespace

However, I am unsure of where to place example implementations, such as a template that creates a concrete class. This template seems like it would be useful to people who use my framework, but I am not sure if it belongs in a separate assembly, or perhaps a namespace within the framework.

If it's a namespace, is there any convention for its name?


问:
How to capture different build verisons of the same production release artifact version in Artifactory?
Let's say I have artifacts "mylibrary-5.2.jar" and "mylibrary-5.3.jar" representing the 5.2 and 5.3 versions of a library that our project creates and publishes for one of our other projects.

Does Artifactory support having multiple "versions" of each of these artifacts to represent the different builds that were performed during a release to construct this artifact?

For example, to produce the final version of the 5.2 release of "mylibrary" aka the artifact: mylibrary-5.2.jar, we went through 3 builds to get to a version that passed our integration environment's automated tests and our user acceptance tests.

So there were three separate builds that produced three separate artifacts for release 5.2. We want to be able to retain and potentially recall these different build's artifact at a later date (for testing, etc).

In order to do this, which of the following options would work?

Capture the artifacts as separate Artifacts, i.e.
build-5.2-b1.jar (build 1's artifact), build-5.2-b2.jar (build 2's
artifact), build-5.2-b3.jar (build 3's artifact), and build-5.2.jar
(the final production release; which matches build 3)

Capture a SINGLE artifact named "build-5.2.jar" which has
VERSIONS of the artifact which capture builds 1 through 3 and which
can be recalled later, by version number.

Some other option we have not considered, but should

答:
The usual way to do this is create each build with a separate version number. For example, 5.2.RC1, 5.2.RC2, and so on ("RC" is "release candidate"). Then make a final version that's 5.2.RELEASE.

I believe (no evidence) that version 5.2.RC1 is considered "newer" than 5.2, which is why companies that do this tend to go with 5.2.RELEASE as the final version.

You might be able to tell Artifactory to not remove snapshots when the release version is deployed. Since each snapshot is written to the repository with a unique datestamp, this will give you the history you want.

You definitely do not want to combine different versions into a single JAR. That will just make your life more difficult trying to use that JAR.

And really, I think you'll find the benefit of keeping each release candidate to be pretty low. Unless, of course, you're in some highly regulated or litigated field, where you must keep each version to satisfy the regulators/lawyers.


问:
Exceptions or Error codes
We are building a web service(SOAP, .Net) which would be talking to (mostly) native clients (windows, C++) and we are wondering what is the best way to communicate errors to the client (e.g. SomethingBadHappened like login service not available or something like user not found) and haven't been able to decide between throwing exception to the client or using some kind of error code model to do the above.

What you would prefer on the handling on the client side: receiving a error code or handling a ServerFault exception which contains the reason for the error?

1) Why are we thinking exception: Because it would make server side code a lot more uniform

2) Why are we thinking error codes: Because we think it makes more sense from the client side perspective.

If 2) is really true we would probably want to go for error codes than exceptions? Is that the case here?

Also, would the answer change if we were talking to managed clients instead of native clients?

答:
SOAP has a concept of faults, you can convert an exception to a fault on the server side and on the client proxy the fault can again be converted back to an exception. This works remarkably well in WCF and Java metro stack, cannot comment on native C++ clients.

As regards to SOA best practice define one generic fault and few specific faults only if the client need to handle a certain type of error differently. Never send a exception stack trace to client in production deployment. This is because in theory the server trace has no meaning for the client and for security reasons as well. Log the full error and stacktrace on the server and send a unique reference to the log in the fault. In WCF I use the Microsoft Exception Handling block from Enterprise Library to generate a guid and also convert a exception to SOAP fault.

Check the guidance at Microsoft Patterns and Practices.

Title: Exceptions or Error codes


答:
Over the course of your career, you will have to learn new languages and new technologies; the industry simply requires it.  On my first professional assignment, I had to deliver code written in Ada, C, and Fortran, along with some SQL and shell scripts.  I've had to switch from C++ to Java and back again in the last couple of years.  I've written shell scripts in csh, bash, and perl.

Taking time to learn different languages, especially if they're in different domains (OO, functional, logical, etc.) will help you in several ways.  It will keep your brain sharp.  It will help you separate concepts from implementation (e.g., hashes and maps aren't just data types in a particular language).  It will give you a better idea of what tools are appropriate for a given problem (for example, I wouldn't build a Web site in C, nor would I write a device driver in Haskell).  It may make it easier for you to find a job ("Hey, he already knows Intercal1, we don't have to train him!").  It will give you an idea of what challenges face language designers.  It may inspire you to create your own programming language.

At the very least, it will keep you from being bored.

1.  Joke.  Don't try to learn Intercal.


问:
Best method to implement a filtered search
I would like to ask you, your opinion when it comes to implement a filtered search form. Let's imagine the following case:

1 Big table with lots of columns

It might be important to say that this SQL Server

You need to implement a form to search data in this table, and in this form you'll have several check boxes that allow you to costumize this search.

Now my question here is which one of the following should be the best way to implement the search?

Create a stored procedure with a query inside. This stored procedure will check if the parameters are given by the application and in the case they are not given a wildcard will be putted in the query.

Create a dynamic query, that is built accordingly to what is given by the application.

I am asking this because I know that SQL Server creates an execution plan when the stored procedure is created, in order to optimize its performance, however by creating a dynamic query inside of the stored procedure will we sacrifice the optimization gained by the execution plan?

Please tell me what would be the best approach in your oppinion.

答:
Start with whatever you think is easier to implement (I guess option 2). Then measure the performance for real world data. Only start optimizing when needed, not beforehand.

By the way, depending on how complex your search filters are, your task may not be easily solved without dynamic SQL. So even when you use a stored procedure, that most probably won't increase performance, as you already suspecting. On the other hand, if it helps, there are several types of hints (see http://www.simple-talk.com/sql/performance/controlling-execution-plans-with-hints/) you can add to an SQL query, dynamic or not, to help SQL server to optimize its execution plan.


答:
There aren't any hard rules that I know of, but the common practice in C# would be to put your standard implementations into the same package as the interface. For example, IList and List both live in the system.collections.generic namespace.

If the implementation is sufficiently specialised you might want to put it into a sub-package. The main thing though, especially if your framework has a significant number of packages, is to be consistent.

Try to think about it from the point of view of someone who's going to use your framework: ideally you want them to be able to discover your classes without having to refer to the documentation.


答:
You might want to look at the answer to this similar question here:
https://stackoverflow.com/questions/11329823/add-where-clauses-to-sql-dynamically-programmatically

We've found that a SPROC which takes in a bunch of optional parameters and implements the filter like this :

```<code>CREATE PROC MyProc (@optionalParam1 NVARCHAR(50)=NULL, @optionalParam2 INT=NULL)
AS
...
SELECT field1, field2, ... FROM [Table]
WHERE
  (@optionalParam1 IS NULL OR MyColumn1 = @optionalParam1)
  AND (@optionalParam2 IS NULL OR MyColumn2 = @optionalParam2)
</code>```

will cache the first execution plan it is run with (e.g. @optionalParam1 = 'Hello World', @optionalParam2 = NULL) but then perform miserably if we pass it a different set of optional parameters (e.g. @optionalParam1 = NULL, @optionalParam2 = 42). (And obviously we want the performance of the cached plan, so WITH RECOMPILE is out)

The exception here is that if there is ALSO at least one MANDATORY filter on the query which is HIGHLY selective and properly indexed, in addition to the optional parameters, then the above PROC will perform fine.

However, if ALL the filters are optional, the rather awful truth is that parameterized dynamic sql actually performs better (unless you write N! different static PROCS for each permutation of optional parameters).

Dynamic SQL like the below will create and cache a different plan for each permutation of the Query parameters, but at least each plan will be 'tailored' to the specific query (it doesn't matter whether it is a PROC or Adhoc SQL - as long as they are parameterized queries, they will be cached)

So hence my preference for :

```<code>DECLARE @SQL NVARCHAR(MAX)

-- Mandatory / Static part of the Query here
SET @SQL = N'SELECT * FROM [table] WHERE 1 = 1'

IF @OptionalParam1 IS NOT NULL
    BEGIN
        SET @SQL = @SQL + N' AND MyColumn1 = @optionalParam1'
    END

IF @OptionalParam2 IS NOT NULL
    BEGIN
        SET @SQL = @SQL + N' AND MyColumn2 = @optionalParam2'
    END

EXEC sp_executesql @SQL,
    N'@optionalParam1 NVARCHAR(50),
      @optionalParam2 INT'
    ,@optionalParam1 = @optionalParam1
    ,@optionalParam2 = @optionalParam2
</code>```

etc. It doesn't matter if we pass in redundant parameters into sp_executesql - they are ignored.
It is worth noting that ORM's like Linq2SQL and EF use parameterized dynamic sql in a similar way.

The awful 1 == 1 hack can also be avoided if you keep track of whether any predicates have yet been applied or not, and then conditionally apply the first AND only on the second and subsequent predicates. If there are no predicates at all, then WHERE disappears as well.

Note that despite the dynamic query, we are still parameterizing the filters, if present, so we have at least a first line of defence against SQL Injection attacks.

Title: Best method to implement a filtered search

Body:
I would like to ask you, your opinion when it comes to implement a filtered search form. Let's imagine the following case:

1 Big table with lots of columns

It might be important to say that this SQL Server

You need to implement a form to search data in this table, and in this form you'll have several check boxes that allow you to costumize this search.

Now my question here is which one of the following should be the best way to implement the search?

Create a stored procedure with a query inside. This stored procedure will check if the parameters are given by the application and in the case they are not given a wildcard will be putted in the query.

Create a dynamic query, that is built accordingly to what is given by the application.

I am asking this because I know that SQL Server creates an execution plan when the stored procedure is created, in order to optimize its performance, however by creating a dynamic query inside of the stored procedure will we sacrifice the optimization gained by the execution plan?

Please tell me what would be the best approach in your oppinion.

Body:
You might want to look at the answer to this similar question here:
https://stackoverflow.com/questions/11329823/add-where-clauses-to-sql-dynamically-programmatically

We've found that a SPROC which takes in a bunch of optional parameters and implements the filter like this :

CREATE PROC MyProc (@optionalParam1 NVARCHAR(50)=NULL, @optionalParam2 INT=NULL)
AS
...
SELECT field1, field2, ... FROM [Table]
WHERE
  (@optionalParam1 IS NULL OR MyColumn1 = @optionalParam1)
  AND (@optionalParam2 IS NULL OR MyColumn2 = @optionalParam2)

will cache the first execution plan it is run with (e.g. @optionalParam1 = 'Hello World', @optionalParam2 = NULL) but then perform miserably if we pass it a different set of optional parameters (e.g. @optionalParam1 = NULL, @optionalParam2 = 42). (And obviously we want the performance of the cached plan, so WITH RECOMPILE is out)

The exception here is that if there is ALSO at least one MANDATORY filter on the query which is HIGHLY selective and properly indexed, in addition to the optional parameters, then the above PROC will perform fine.

However, if ALL the filters are optional, the rather awful truth is that parameterized dynamic sql actually performs better (unless you write N! different static PROCS for each permutation of optional parameters).

Dynamic SQL like the below will create and cache a different plan for each permutation of the Query parameters, but at least each plan will be 'tailored' to the specific query (it doesn't matter whether it is a PROC or Adhoc SQL - as long as they are parameterized queries, they will be cached)

So hence my preference for :

DECLARE @SQL NVARCHAR(MAX)

-- Mandatory / Static part of the Query here
SET @SQL = N'SELECT * FROM [table] WHERE 1 = 1'

IF @OptionalParam1 IS NOT NULL
    BEGIN
        SET @SQL = @SQL + N' AND MyColumn1 = @optionalParam1'
    END

IF @OptionalParam2 IS NOT NULL
    BEGIN
        SET @SQL = @SQL + N' AND MyColumn2 = @optionalParam2'
    END

EXEC sp_executesql @SQL,
    N'@optionalParam1 NVARCHAR(50),
      @optionalParam2 INT'
    ,@optionalParam1 = @optionalParam1
    ,@optionalParam2 = @optionalParam2

etc. It doesn't matter if we pass in redundant parameters into sp_executesql - they are ignored.
It is worth noting that ORM's like Linq2SQL and EF use parameterized dynamic sql in a similar way.

The awful 1 == 1 hack can also be avoided if you keep track of whether any predicates have yet been applied or not, and then conditionally apply the first AND only on the second and subsequent predicates. If there are no predicates at all, then WHERE disappears as well.

Note that despite the dynamic query, we are still parameterizing the filters, if present, so we have at least a first line of defence against SQL Injection attacks.

ContentLicense: CC BY-SA 4.0


答:
When looking at resumes we usually look for somebody that knows multiple languages. Also, as a person's experience increases the number of languages they have used should increase too.

In our environment we often have to tackle new and interesting problems and we are looking for people that are willing to jump in and solve those problems, whether they need to learn a new language or not. The problem might be in code running on a Windows desktop, a Windows server, a Linux server or in a browser.

Knowing multiple languages is a sign of somebody with a good attitude toward their craft. They want to always learn new things so they do. A lack of knowing a number of languages is a sign to me that a person only does the bare minimum and is not interested in learning.


问:
Public-private key pair handling on a Windows ecosystem
I've been thinking about how to architect an infrastructure for one of our business applications with the following requirement:

Data written by some user can only be read by that user and his superior and a 3rd person yet to be defined

I'm thinking in using some sort of asymmetric algorithm, such as RSA for data encryption.

We can generate a public-private key pair for each user and store the public key of each one openly on a database, but how should we handle the private key ?

If we just let the users manage their private key one day we will have a big headache if one of them loses his key.

If the private key becomes public somehow then the data would become public too, rendering the architecture invalid.

Our infrastructure is heavily Microsoft-oriented: All applications are ASP.Net MVC3, our dabatase is SQL Server 2005 and we use Active Directory for user authentication and basic data, such as e-mail/phone number.

How would you guys architect a solution to solve this problem ?

Bottom-line: This is not a banking or financial application, it's some kind of 360-degree personal feedback system.

EDIT:
Adding more requirements, hoping to make it more clear:

This database will be in production environment, where developers don't have access;

When the database is restored, developers should not be able to recover the data;

The DBA should not be able to view the data by SELECT'ing the rows on the tables;

EDIT 2: Bounty info.
Bounty went to the answer with more upvotes, although my personal feel is that none of the answers provided addressed the question correctly. For this reason, I'm granting the bounty but not marking the answer as correct.

答:
We have what sounds like a similar system.  We had to set up a table with login names matching the Active Directory that specifiy who is whom's superior.  If you are using MVC3 with Windows Authenication you should be able to see who is looking up who.  Here's an example:

https://stackoverflow.com/questions/1267071/how-to-get-windows-user-name-when-identity-impersonate-true-in-asp-net

One thing to look out for is that people will want to give confidential information about there superiors.  Allow feedback to be specified 'for HR only'.


答:
In this situation you're not asking about switching from JAVA to C# and back all the time, instead you're going with C# and PHP which really isn't a big deal.

Suppose you wanted to do some WEB based stuff where you're using a WAMP stack (Windows/Apache/MySQL/PHP) and C#.  You use the C# to write some SOAP based services and then use PHP to consume them.

This seems totally acceptable to me.

Anyway, knowing more than one language is good.  The more you know the better.  PHP/C#/Java/Python/javascript libraries[JQuery for instance].  Be useful to as many people as you can.


问:
How do I add a Help system to my WinForms project?
I have pretty much completed work on a Winforms application, and would like to add a Help feature for users.  I cannot send users to a website, and am thinking along the lines of the kind of help you get when you click on Help in IE (or hit F1).  I believe this is compiled html or something, but am not sure what tools are available to assist in building this kind of thing, or how many options are out there.

Anyway, how about some suggestions?

答: Adobe Robohelp is one tool that can help generate html help files. You can always point the browser to a file on the local machine.</p>


答:
There are a number of questions on Stack Overflow that can assist you:

https://stackoverflow.com/questions/2317738/how-to-add-help-to-winform-c-sharp-application

https://stackoverflow.com/questions/1178922/how-to-add-help-to-windows-forms

https://stackoverflow.com/questions/3158901/integrating-help-into-winforms-application

https://stackoverflow.com/questions/3077361/what-tools-are-available-to-create-a-help-file-in-visual-studio-2010

https://stackoverflow.com/questions/920585/how-to-add-or-handle-help-files-to-a-net-project

Title: How do I add a Help system to my WinForms project?

Body:
I have pretty much completed work on a Winforms application, and would like to add a Help feature for users.  I cannot send users to a website, and am thinking along the lines of the kind of help you get when you click on Help in IE (or hit F1).  I believe this is compiled html or something, but am not sure what tools are available to assist in building this kind of thing, or how many options are out there.

Anyway, how about some suggestions?


问:
JavaScript vs third party libraries
I program in Java and it doesn't make sense to me to think about learning a Java library or a framework without knowing the actual language the thing is built with. Same goes for C. I always avoided JavaScript simply because I wasn't interested in the client side of things but that has changed now.

I'm confused as to how and why do people avoid learning JavaScript and instead jump right ahead with a library like JQuery ?
How can I program without knowing the features of JS, what is a prototype based language, functions as first class citizens, OOP, closures, etc.

Also, are most of the things today in the client-side world built with the help of third party libraries?

答:
Most JavaScript developers use a framework since JavaScript as a language contains quite a lot of cruft and otherwise undesirable functionality. It has some really powerful functionality but there are also plenty of ways to shoot yourself in the foot.

I've used jQuery and YUI and the past. When using a good JavaScript framework programming in it is a significantly more enjoyable experience. I tend to favor jQuery these days because it allows me to write very clean functional-like code. jQuery also relies heavily on CSS selectors for DOM querying so it feels a lot more natural to write $('#some_element') than writing document.getElementById('some_element').

I recommend reading JavaScript: The Good Parts by Douglas Crockford to learn some tips for very effective (and beautiful) Javascript programming. This book won't teach you how to write nifty JavaScript effects or AJAXy magic but it will teach you about the language, what to rely on, and what to run away from screaming. It's a fairly short book but I'd recommend reading it a few times.

Title: JavaScript vs third party libraries


答:
People learn differently.

==Top down approach==

Some jump into the library and learn how to work with the library and inevitably learn some of the javascript, or base language, features.

==Bottom up approach==

Others like to learn about the pieces and then how they are put together to create the library they're using. Sometimes they feel that to be more effective they'd like to know the nooks and crannies of what they're using and the language it's written in.

The approach you take largely depends on you AND how easy the library is to use. If the library is hard to use then either users won't use it OR they'll be forced to do a bottom up approach.

Fortunately, javascript appears deceptively similar enough to java and other languages in terms of syntax that most users feel they can take a top down approach while relying on their reference language for help to determine how things are working. This happens even though, as stated in the comments, Javascript is very different from Java and draws more inspiration from LISP/Scheme than from Java.

The top down approach works with javascript/jquery quite well but what inevitable ends up happening is that the user ends up coming up with a Java like solution to their problems when a simple javascript convention would be easier to implement. This is a drawback but only until they realize that javascript can make some tasks easier. Until then, to the user, javascript becomes Java just on the client side.

Eventually they run into some weird bug or code they can't understand, like the way closures work, and have to dig into javascript basics more than they have to.

I don't know how much of client-side code is built with 3rd party libraries but I do know that they can make life much easier since you don't have to 're-invent the wheel'. Cave men did that a while ago so focus on other things if you can. If you're in a limited environment then you might have to write your own library but basing it on a 3rd party library is NOT a bad idea because they've thought of, faced, and solved more issues than one person could hope to cover in the same amount of time.

Title: JavaScript vs third party libraries

Body:
I program in Java and it doesn't make sense to me to think about learning a Java library or a framework without knowing the actual language the thing is built with. Same goes for C. I always avoided JavaScript simply because I wasn't interested in the client side of things but that has changed now.

I'm confused as to how and why do people avoid learning JavaScript and instead jump right ahead with a library like JQuery ?
How can I program without knowing the features of JS, what is a prototype based language, functions as first class citizens, OOP, closures, etc.

Also, are most of the things today in the client-side world built with the help of third party libraries?


问:
Why use binary files to stack up different versions on DMSs?
I've used both Liferay and Alfresco trying to use them as the Document Management System for an intranet.

I noticed the following:

They use the file system and the database to store files

They use a GUID to name the file on the filesystem and that GUID is
used as an Id in the database.

The GUID-named file is a binary file

The GUID-named binary file stores all versions for a given file

The path for the file in the DMS doesn't match the one in the file
system

The URL makes reference to the GUID when a certain file is requested

What I want to know is why is this, and what would be the best way of doing it. Like how to would you create the binary file (zip?), and what parts would you keep in the binary file and what parts would you store in the database (meta-data, path?).

I'm assuming some of the benefits of doing it like this. As having the same URL for a file, regardless of its current document path. And having only one file even if the file has changed names over time.

答:
Storing large binary blocks as files is typically more efficient then storing large BLOBs in a database. It depends.

GUIDs have the advantage you can create one at random and use it without depending on some identity provider. Using a seed based ID generated in a DBMS would require you to first go to the database before writing a file to disk, with a GUID the order doesn't matter.

Document revisions can perfectly fit an append model. It can keep adding revisions to the file without causing too much rewriting. It also allows for smart storage and just storing deltas going from revision to revision, similar to what a version control repository would do. Otherwise using compression can also make a significant difference compared to storing the revisions in their own file.

It may also do this to avoid creating too many files on disk, which in turn may have a negative impact on performance. Copying around directories or making backups of directories with a huge amount of small files can be problematic slow.

Perhaps you should not look at the files as "files", it's just data. The GUID allows retrieval. Sticking it in the filename allows the file system to help out grabbing it.

You could do without a database, you may import some work though that a DB already does for you. In a hybrid approach I would typically put stuff in the DB that I would query on (e.g "Which documents are at path X?"). This would avoid having to create my own indices and such around the file based repository.