পাস আইডি বা অবজেক্ট?


38

কোনও ডোমেন সত্তা পাওয়ার জন্য কোনও ব্যবসায় যুক্তিযুক্ত পদ্ধতি সরবরাহ করার সময়, প্যারামিটারটি কোনও বস্তু বা একটি আইডি গ্রহণ করতে পারে? উদাহরণস্বরূপ, আমাদের কি এটি করা উচিত:

public Foo GetItem(int id) {}

অথবা এটা:

public Foo GetItem(Foo foo) {}

আমি চারপাশে, পুরোপুরি অবজেক্টগুলিকে পাশ কাটাতে বিশ্বাস করি, তবে এই ক্ষেত্রে কী হবে যেখানে আমরা কোনও অবজেক্ট পাচ্ছি এবং আমরা কেবল আইডি জানি? কলকারীকে একটি খালি ফু তৈরি করতে হবে এবং আইডি সেট করা উচিত, বা এটি কেবল আইডিটি পদ্ধতিতে পাস করা উচিত? যেহেতু আগত ফু ফাঁকা থাকবে, আইডি ব্যতীত, আমি ফোনকারীকে কোনও ফোও তৈরি করতে হবে এবং তার আইডি সেট করতে হবে যখন এটি কেবল আইটেমটি getItem () পদ্ধতিতে প্রেরণ করতে পারে তা আমি দেখতে পাচ্ছি না।

উত্তর:


42

কেবলমাত্র একক ক্ষেত্রটি দেখার জন্য ব্যবহৃত হচ্ছে।

কলারের কাছে একটি নেই Foo, এটি পাওয়ার চেষ্টা করছে। অবশ্যই, আপনি Fooঅন্যান্য সমস্ত ক্ষেত্র ফাঁকা রেখে অস্থায়ী করতে পারেন , তবে এটি কেবল তুচ্ছ তথ্য কাঠামোর জন্য কাজ করে। বেশিরভাগ অবজেক্টে এমন আক্রমণকারী থাকে যা বেশিরভাগ খালি-অবজেক্ট পদ্ধতির দ্বারা লঙ্ঘন করা হয়, সুতরাং এটি এড়িয়ে চলুন।


ধন্যবাদ. আমি আমার উত্তরটি আমার উত্তর উত্তর 2 পয়েন্ট এর সাথে পছন্দ করি।
বব হর্ন

3
এটি যৌক্তিক বলে মনে হচ্ছে। তবে পারফরম্যান্স অনুসারে, আমি এমন অঞ্চলে চলে এসেছি যেখানে কলারের কাছে বস্তু থাকতে পারে এবং তা নাও থাকতে পারে। কেবলমাত্র আইডি পাস করার ফলে ডাটাবেস থেকে দু'বার পড়ার কথা বলা হতে পারে। এটি কি কেবল একটি গ্রহণযোগ্য পারফরম্যান্স হিট? অথবা আপনি আইডি বা অবজেক্ট উভয় পাশ করার সম্ভাবনাটি সরবরাহ করেন?
গণমাধ্যমে

আমি আজকাল লবণের দানা দিয়ে এই 'কখনই বস্তুটি পাস করি না' নিয়মগুলি গ্রহণ করি। এটি কেবল আপনার প্রসঙ্গ / দৃশ্যের উপর নির্ভর করে।
ব্রুনো

12

এটি কি এখন বা ভবিষ্যতে কোনও সময় তারের (সিরিয়ালযুক্ত / deserialized) অতিক্রম করবে? কে-জানে-কত বড় পূর্ণ বস্তুটির উপরে একক আইডি প্রকারটি পছন্দ করুন।

আপনি যদি তার সত্তায় আইডিটির ধরণ-সুরক্ষা খুঁজছেন, তবে সেই সাথে কোড সমাধানও রয়েছে। আপনার উদাহরণ প্রয়োজন হলে আমাকে জানান।

সম্পাদনা: আইডির ধরণ-সুরক্ষার প্রসারণ:

সুতরাং, আসুন আপনার পদ্ধতি গ্রহণ করা যাক:

public Foo GetItem(int id) {}

আমরা কেবলমাত্র আশা করি যে পূর্ণসংখ্যাটি idউত্তীর্ণ হয়েছে এটি কোনও Fooঅবজেক্টের জন্য। কেউ এটির অপব্যবহার করতে পারে এবং কোনও Barঅবজেক্টের পূর্ণসংখ্যার আইডি বা এমনকি হাতে টাইপ করে পাস করতে পারে 812341। এটি টাইপ নিরাপদ নয় Foo। দ্বিতীয়ত, আপনি পাসটি কোনও অবজেক্ট Fooসংস্করণ ব্যবহার করলেও , আমি নিশ্চিতভাবেই Fooএকটি আইডি ক্ষেত্র রয়েছে যা intসম্ভবত কেউ পরিবর্তন করতে পারে। এবং সবশেষে, আপনি যদি রিটার্নের টাইপের পরিবর্তিত হয় তবে ক্লাসে যদি এগুলি একসাথে থাকে তবে আপনি পদ্ধতি ওভারলোডিং ব্যবহার করতে পারবেন না। সি # তে টাইপ-নিরাপদ দেখতে এই পদ্ধতিটি কিছুটা আবার লিখি:

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

সুতরাং আমি একটি ক্লাস চালু করেছি IntIdযার একটি জেনেরিক অংশ রয়েছে। এই বিশেষ ক্ষেত্রে, আমি intএটির সাথে যুক্ত হতে চাই Foo। আমি কেবল উলঙ্গ হয়ে intযেতে পারি না বা IntId<Bar>ঘটনাক্রমে এটির জন্য কোনও বরাদ্দও করতে পারি না । সুতরাং নীচে আমি কীভাবে এই টাইপ-সেফ আইডেন্টিফায়ারগুলি লিখেছি। নোট গ্রহণ করবেন না যে প্রকৃত অন্তর্নিহিত ম্যানিপুলেশন intহয় শুধুমাত্র আপনার ডেটা অ্যাক্সেস স্তর করেন। উপরের যে কোনও কিছুই কেবল শক্তিশালী প্রকারটি দেখে এবং এর অভ্যন্তরীণ intআইডিতে কোনও (সরাসরি) অ্যাক্সেস নেই । এটির কোনও কারণ থাকতে হবে না।

IModelId.cs ইন্টারফেস:

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 বেস শ্রেণি:

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;
        }
    }
}

এবং, আমার কোডবেসের সম্পূর্ণতার জন্য, আমি জিইউইডি সত্তা, গাইড আইডি কোডের জন্য একটিও লিখেছি:

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;
        }
    }
}

হ্যাঁ, এটি তারের উপর দিয়ে যাচ্ছে। আমি জানি না যে আইডিটির সত্তায় আমার টাইপ-সুরক্ষা দরকার, তবে আপনি এটির অর্থ কী বোঝাতে আগ্রহী। হ্যাঁ, আপনি যদি এটির উপর প্রসারিত করতে পারেন তবে তা দুর্দান্ত।
বব হর্ন

আমি তাই করেছি। একটু কোড-ভারী হয়ে উঠেছে :)
জেসি সি স্লিকার

1
যাইহোক, আমি Originসম্পত্তিটি ব্যাখ্যা করিনি : এটি অনেকটা এসকিউএল সার্ভার পার্লেন্সে স্কিমার মতো। Fooআপনার অ্যাকাউন্টিং সফ্টওয়্যারটিতে এটি ব্যবহার করা হতে পারে এবং Fooহিউম্যান রিসোর্সগুলির জন্য অন্যটি রয়েছে যা আপনার ডেটা অ্যাক্সেস লেয়ারে এগুলি আলাদা করার জন্য সেই সামান্য ক্ষেত্র উপস্থিত রয়েছে। বা, যদি আপনার কোনও বিরোধ না হয় তবে এটিকে আমার মতো করে উপেক্ষা করুন।
জেসি সি স্লিকার 14 ই

1
@ জেসিসি.স্লাইকার: প্রথম নজরে এটি দেখতে ওভার ইঞ্জিনিয়ারিং কোনও কিছুর জন্য নিখুঁত উদাহরণ বলে মনে হচ্ছে।
ডক ব্রাউন

2
@DocBrown অসহায়তা প্রতিটি তাদের নিজস্ব। এটি এমন একটি সমাধান যা কিছু লোকের প্রয়োজন। কিছু মানুষ না। যদি YAGNI হয়, তবে এটি ব্যবহার করবেন না। আপনার যদি এটির প্রয়োজন হয় তবে তা রয়েছে।
জেসি সি স্লিকার 16 ই

5

আমি অবশ্যই আপনার উপসংহার সাথে একমত। কিছু কারণে আইডি পাস করা পছন্দ করা হয়:

  1. এটা সহজ. উপাদান মধ্যে ইন্টারফেস সহজ হতে হবে।
  2. Fooশুধু আইডির জন্য একটি বস্তু তৈরির অর্থ মিথ্যা মান তৈরি করা। কেউ ভুল করতে পারে এবং এই মানগুলি ব্যবহার করতে পারে।
  3. intআরও প্ল্যাটফর্ম-বিস্তৃত এবং সমস্ত আধুনিক ভাষায় স্থানীয়ভাবে ঘোষণা করা যেতে পারে। Fooপদ্ধতি কলারের দ্বারা কোনও অবজেক্ট তৈরি করতে আপনার সম্ভবত একটি জটিল ডেটা স্ট্রাকচার তৈরি করতে হবে (জেএসন অবজেক্টের মতো)।

4

আমি মনে করি আপনি বেন ভয়েগট যেমন পরামর্শ দিয়েছেন তেমনটি অবজেক্টের শনাক্তকারীর উপরে অনুসন্ধান স্থাপন করা বুদ্ধিমানের কাজ হবে।

তবে মনে রাখবেন যে আপনার অবজেক্টের শনাক্তকরণকারীর ধরণ পরিবর্তন হতে পারে। এর মতো, আমি আমার প্রতিটি আইটেমের জন্য একটি শনাক্তকারী শ্রেণি তৈরি করব এবং কেবলমাত্র এই শনাক্তকারীদের এই দৃষ্টান্তগুলির মাধ্যমে আইটেমগুলি সন্ধান করার অনুমতি দেব। নিম্নলিখিত উদাহরণটি দেখুন:

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

  public ItemId Id; { get; set; }
}

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

আমি এনক্যাপসুলেশন ব্যবহার করেছি, তবে আপনি এর Itemথেকে উত্তরাধিকারীও করতে পারেন ItemId

এইভাবে, যদি রাস্তার পাশে আপনার আইডির ধরণ পরিবর্তন হয় তবে আপনাকে Itemক্লাসে বা গেটআইটেম পদ্ধতির স্বাক্ষরে কোনও পরিবর্তন করতে হবে না । কেবলমাত্র পরিষেবাটি বাস্তবায়নের ক্ষেত্রে আপনাকে নিজের কোড পরিবর্তন করতে হবে (যা কেবলমাত্র সমস্ত ক্ষেত্রেই পরিবর্তন হয়)


2

এটি আপনার পদ্ধতি কী করে তার উপর নির্ভর করে।

সাধারণত এর জন্য Get methods, id parameterঅবজেক্টটি পাস করা এবং ফিরে পাওয়া সাধারণ জ্ঞান । আপডেটের জন্য বা SET methodsআপনি পুরো অবজেক্টটি সেট / আপডেট করতে পাঠিয়েছেন।

কিছু অন্যান্য ক্ষেত্রে যেখানে আপনার method is passing search parameters(পৃথক আদিম ধরণের সংগ্রহ হিসাবে) ফলাফলের একটি সেট পুনরুদ্ধার করার জন্য এটি use a container to holdআপনার অনুসন্ধান পরামিতিগুলির বুদ্ধিমান হতে পারে । দীর্ঘমেয়াদে প্যারামিটারের সংখ্যা পরিবর্তিত হলে এটি দরকারী। সুতরাং, আপনি would not needপরিবর্তন করতে signature of your method, add or remove parameter in all over the places

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.