সলিড, রক্তস্বল্প ডোমেনগুলি এড়ানো, নির্ভরতা ইনজেকশন?


33

যদিও এটি একটি প্রোগ্রামিং ল্যাঙ্গুয়েজ অজোনস্টিক প্রশ্ন হতে পারে তবে আমি নেট নেট ইকোসিস্টেমকে লক্ষ্য করে উত্তরগুলি দিতে আগ্রহী।

এই দৃশ্যটি: ধরুন আমাদের জনপ্রশাসনের জন্য একটি সাধারণ কনসোল অ্যাপ্লিকেশন বিকাশ করা উচিত। আবেদনটি যানবাহন শুল্ক সম্পর্কে। তাদের (কেবলমাত্র) নিম্নলিখিত ব্যবসায়িক বিধি রয়েছে:

১. ক) যদি গাড়িটি গাড়ি হয় এবং সর্বশেষ সময়টি তার মালিক 30 দিন আগে কর প্রদান করে থাকে তবে মালিককে আবার পরিশোধ করতে হবে।

১. বি) যানবাহনটি যদি মোটরবাইক হয় এবং owner০ দিন আগে তার মালিক যখন শেষবারের মতো কর প্রদান করেছিলেন তবে মালিককে আবার অর্থ প্রদান করতে হবে।

অন্য কথায়, আপনার যদি গাড়ী থাকে তবে আপনাকে প্রতি 30 দিন সময় দিতে হয় বা আপনার কাছে মোটরবাইক থাকলে আপনাকে প্রতি 60 দিন পরে দিতে হবে।

সিস্টেমের প্রতিটি গাড়ির জন্য, অ্যাপ্লিকেশনটির সেই নিয়মগুলি পরীক্ষা করা উচিত এবং সেই গাড়িগুলি (প্লেট নম্বর এবং মালিকের তথ্য) মুদ্রণ করা উচিত যা সেগুলি সন্তুষ্ট করে না।

আমি যা চাই তা হ'ল:

২. ক) সলিড নীতিগুলি (বিশেষত উন্মুক্ত / বদ্ধ নীতি) মেনে চলুন।

আমি যা চাই না তা হ'ল (আমার মনে হয়):

২. বি) অ্যানিমিক ডোমেন, সুতরাং ব্যবসায়ের যুক্তি ব্যবসায়ের সত্তার মধ্যে থাকা উচিত go

আমি এটি দিয়ে শুরু করেছি:

public class Person
// You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.
{
    public string Name { get; set; }

    public string Surname { get; set; }
}

public abstract class Vehicle
{
    public string PlateNumber { get; set; }

    public Person Owner { get; set; }

    public DateTime LastPaidTime { get; set; }

    public abstract bool HasToPay();
}

public class Car : Vehicle
{
    public override bool HasToPay()
    {
        return (DateTime.Today - this.LastPaidTime).TotalDays >= 30;
    }
}

public class Motorbike : Vehicle
{
    public override bool HasToPay()
    {
        return (DateTime.Today - this.LastPaidTime).TotalDays >= 60;
    }
}

public class PublicAdministration
{
    public IEnumerable<Vehicle> GetVehiclesThatHaveToPay()
    {
        return this.GetAllVehicles().Where(vehicle => vehicle.HasToPay());
    }

    private IEnumerable<Vehicle> GetAllVehicles()
    {
        throw new NotImplementedException();
    }
}

class Program
{
    static void Main(string[] args)
    {
        PublicAdministration administration = new PublicAdministration();
        foreach (var vehicle in administration.GetVehiclesThatHaveToPay())
        {
            Console.WriteLine("Plate number: {0}\tOwner: {1}, {2}", vehicle.PlateNumber, vehicle.Owner.Surname, vehicle.Owner.Name);
        }
    }
}

2.এ: ওপেন / বদ্ধ নীতিটি গ্যারান্টিযুক্ত; যদি তারা সাইকেল ট্যাক্স চান তবে আপনি কেবল যানবাহন থেকে উত্তরাধিকারী হন, তবে আপনি হ্যাসটোপে পদ্ধতিটি ওভাররাইড করবেন এবং আপনার কাজ শেষ। সাধারণ উত্তরাধিকারের মাধ্যমে সন্তুষ্ট / বন্ধ নীতি

"সমস্যাগুলি" হ'ল:

৩.এ) কেন কোনও যানবাহনকে তার মূল্য দিতে হবে তা জানতে হবে? পাবলিক অ্যাডমিনিস্ট্রেশন উদ্বেগ না? যদি জনপ্রশাসন গাড়ি ট্যাক্স পরিবর্তনের জন্য নিয়ম করে, তবে গাড়িটি কেন পরিবর্তন করতে হবে? আমার মনে হয় আপনার জিজ্ঞাসা করা উচিত: "তাহলে আপনি যানবাহনের ভিতরে কেন হ্যাশটোপে পদ্ধতি রেখেছেন?", এবং উত্তরটি হ'ল: কারণ আমি পাবলিক-অ্যাডমিনিস্ট্রেশনের ভিতরে যানবাহনের ধরণের (টাইপফ) পরীক্ষা করতে চাই না। আপনি কি আরও ভাল বিকল্প দেখতে পাচ্ছেন?

৩.বি) হয়তো কর প্রদানের বিষয়টি সর্বোপরি একটি গাড়ির উদ্বেগ, বা হতে পারে আমার প্রাথমিক ব্যক্তি-যানবাহন-গাড়ি-মোটরবাইক-পাবলিক অ্যাডমিনিস্ট্রেশন ডিজাইনটি কেবল সাধারণ ভুল, অথবা আমার একজন দার্শনিক এবং আরও ভাল ব্যবসায় বিশ্লেষক প্রয়োজন। একটি সমাধান হতে পারে: হ্যাসটোপে পদ্ধতিটিকে অন্য শ্রেণিতে স্থানান্তর করুন, আমরা এটিকে ট্যাক্সপমেন্ট বলতে পারি। তারপরে আমরা দুটি ট্যাক্স পেমেন্ট উদ্ভূত ক্লাস তৈরি করি; কারট্যাক্স পেমেন্ট এবং মোটরবাইকট্যাক্স পেমেন্ট। তারপরে আমরা যানবাহনের ক্লাসে একটি বিমূর্ত প্রদানের সম্পত্তি (কর প্রদেয় প্রকারের প্রকারের) যুক্ত করি এবং আমরা গাড়ী এবং মোটরবাইক শ্রেণি থেকে সঠিক কর প্রদানের দৃষ্টান্তটি ফিরিয়ে দিই:

public abstract class TaxPayment
{
    public abstract bool HasToPay();
}

public class CarTaxPayment : TaxPayment
{
    public override bool HasToPay()
    {
        return (DateTime.Today - this.LastPaidTime).TotalDays >= 30;
    }
}

public class MotorbikeTaxPayment : TaxPayment
{
    public override bool HasToPay()
    {
        return (DateTime.Today - this.LastPaidTime).TotalDays >= 60;
    }
}

public abstract class Vehicle
{
    public string PlateNumber { get; set; }

    public Person Owner { get; set; }

    public DateTime LastPaidTime { get; set; }

    public abstract TaxPayment Payment { get; }
}

public class Car : Vehicle
{
    private CarTaxPayment payment = new CarTaxPayment();
    public override TaxPayment Payment
    {
        get { return this.payment; }
    }
}

public class Motorbike : Vehicle
{
    private MotorbikeTaxPayment payment = new MotorbikeTaxPayment();
    public override TaxPayment Payment
    {
        get { return this.payment; }
    }
}

এবং আমরা পুরানো প্রক্রিয়াটি এভাবেই প্রার্থনা করি:

    public IEnumerable<Vehicle> GetVehiclesThatHaveToPay()
    {
        return this.GetAllVehicles().Where(vehicle => vehicle.Payment.HasToPay());
    }

তবে এখন এই কোডটি সংকলন করবে না কার্ট্যাকপেসমেন্ট / মোটরবাইকট্যাক্স পেমেন্ট / ট্যাক্সপেমেন্টের ভিতরে লাস্টপেইডটাইম সদস্য নেই। আমি CarTaxPayment এবং মোটরবাইকট্যাক্স পেমেন্টটি ব্যবসায়ের সংস্থাগুলির চেয়ে "অ্যালগরিদম বাস্তবায়ন" এর মতো দেখতে আরও শুরু করি। কোনওভাবে এখন সেই "অ্যালগরিদমগুলি" লাস্টপেইডটাইমের মান প্রয়োজন। অবশ্যই, আমরা করের অর্থ পরিশোধের নির্মাতার কাছে মানটি পাস করতে পারি, তবে এটি যানবাহন আবরণ, বা দায়িত্বগুলি লঙ্ঘন করবে বা এই ওওপি প্রচারকরা যা বলুক না কেন, তা নয়?

3.c) ধরুন আমাদের ইতিমধ্যে একটি সত্ত্বা ফ্রেমওয়ার্ক অবজেক্ট কনটেক্সট (যা আমাদের ডোমেন অবজেক্ট ব্যবহার করে; ব্যক্তি, যানবাহন, গাড়ি, মোটরবাইক, পাবলিক অ্যাডমিনিস্ট্রেশন)। আপনি পাবলিকএডমিনিস্ট্রেশন.গেটএলভেলিক্স পদ্ধতি থেকে কোনও অবজেক্ট কনটেক্সট রেফারেন্স পেতে কীভাবে করতে পারেন এবং তাই চমত্কারতা বাস্তবায়ন করেন?

৩. ডি) আমাদের যদি কারট্যাক্সপেমেন্টের জন্য একই অবজেক্ট কনটেক্সট রেফারেন্সের প্রয়োজন হয় তবে হসটোপপে মোটরবাইকট্যাক্স পেমেন্টের জন্য আলাদা একটি। "ইনজেকশন" দেওয়ার দায়িত্বে থাকা হাসটপোপে বা কীভাবে আপনি এই রেফারেন্সগুলি পেমেন্ট ক্লাসে পাস করবেন? এই ক্ষেত্রে, একটি রক্তাল্পতা ডোমেন এড়ানো (এবং এইভাবে কোনও পরিষেবা সামগ্রী নেই), আমাদেরকে বিপর্যয়ের দিকে নিয়ে যায় না?

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

উত্তর:


15

আমি বলব যে কোনও ব্যক্তি বা যানবাহন উভয়েরই জানা উচিত নয় যে কোনও অর্থ প্রদানের কারণে।

সমস্যা ডোমেন পুনরায় পরীক্ষা করা

আপনি যদি সমস্যাযুক্ত ডোমেনটির দিকে নজর রাখেন "গাড়ি থাকা লোকেরা": গাড়ি কেনার জন্য আপনার কাছে একরকম চুক্তি রয়েছে যা এক ব্যক্তির থেকে অন্য ব্যক্তির মালিকানা স্থানান্তর করে, গাড়ি বা ব্যক্তি এই প্রক্রিয়াতে কোনও পরিবর্তন করে না। আপনার মডেলটিতে পুরোপুরি অভাব রয়েছে।

চিন্তার পরীক্ষা

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

=> মালিকানা

কারের মালিকানাধীন গাড়ি এখনও একটি গাড়ি তবে কেউ এর জন্য ট্যাক্স দেবে না। আসলে, আপনি গাড়ির জন্য ট্যাক্স দিচ্ছেন না তবে একটি গাড়ি মালিকের অধিকারের জন্য । সুতরাং আমার প্রস্তাবটি হবে:

public class Person
{
    public string Name { get; set; }

    public string Surname { get; set; }

    public List<Ownership> getOwnerships();

    public List<Vehicle> getVehiclesOwned();
}

public abstract class Vehicle
{
    public string PlateNumber { get; set; }

    public Ownership currentOwnership { get; set; }

}

public class Car : Vehicle {}

public class Motorbike : Vehicle {}

public abstract class Ownership
{
    public Ownership(Vehicle vehicle, Owner owner);

    public Vehicle Vehicle { get;}

    public Owner CurrentOwner { get; set; }

    public abstract bool HasToPay();

    public DateTime LastPaidTime { get; set; }

   //Could model things like payment history or owner history here as well
}

public class CarOwnership : Ownership
{
    public override bool HasToPay()
    {
        return (DateTime.Today - this.LastPaidTime).TotalDays >= 30;
    }
}

public class MotorbikeOwnership : Ownership
{
    public override bool HasToPay()
    {
        return (DateTime.Today - this.LastPaidTime).TotalDays >= 60;
    }
}

public class PublicAdministration
{
    public IEnumerable<Ownership> GetVehiclesThatHaveToPay()
    {
        return this.GetAllOwnerships().Where(HasToPay());
    }

}

এটি নিখুঁত থেকে দূরে এবং সম্ভবত সি # কোডটিও দূরবর্তীভাবে সংশোধন করা সম্ভব নয় তবে আমি আশা করি আপনি ধারণাটি পেয়েছেন (এবং কেউ এটি পরিষ্কার করতে পারে)। একমাত্র ক্ষতি হ'ল আপনার এবং সম্ভবত CarOwnershipএকটি Carএবং একটি এর মধ্যে সঠিক তৈরি করার জন্য কোনও কারখানা বা কোনও কিছুর প্রয়োজন হবেPerson


আমি মনে করি বাহনটির নিজেই এর জন্য প্রদেয় করগুলি রেকর্ড করা উচিত, এবং ব্যক্তিদের তাদের সমস্ত যানবাহনের জন্য প্রদত্ত কর রেকর্ড করা উচিত। একটি ট্যাক্স কোড লেখা যেতে পারে যাতে কোনও গাড়ীর উপর কর 1 জুন প্রদান করা হয় এবং এটি 10 ​​জুন বিক্রি করা হয় তবে নতুন মালিক 10 জুন, জুলাই 1 বা 10 জুলাই করের জন্য দায়বদ্ধ হয়ে উঠতে পারে (এমনকি তা থাকলেও) বর্তমানে এটির একটি উপায় পরিবর্তিত হতে পারে)। যদি মালিকানা পরিবর্তনের মাধ্যমেও যদি 30 দিনের নিয়ম গাড়ীর জন্য স্থির থাকে তবে কারও দ্বারা owedণী গাড়িগুলি শুল্ক দিতে পারে না, তবে আমি প্রস্তাব দেব যে 30 বা ততোধিক দিনের জন্য অনাবৃত গাড়ি যখন কেনা হবে, তখন একটি কর প্রদান ...
সুপারক্যাট

... একটি কল্পিত "অবিবাহিত যানবাহন ট্যাক্স creditণ" ব্যক্তির কাছ থেকে রেকর্ড করুন, যাতে বিক্রয়ের সময় হিসাবে শুল্ক বা ত্রিশ দিন হতে পারে, নির্ধারিত যানটি নির্বিশেষে যানবাহনটি কতক্ষণ অবধি ছিল।
সুপারক্যাট

4

আমি মনে করি যে এই ধরণের পরিস্থিতিতে যেখানে আপনি চান ব্যবসায়িক বিধিগুলি লক্ষ্যবস্তুগুলির বাইরে থাকা, সেখানে প্রকারের জন্য পরীক্ষা গ্রহণযোগ্যতার চেয়ে বেশি।

অবশ্যই, অনেক পরিস্থিতিতে আপনার স্ট্র্যাটেজি প্যাটার্ন ব্যবহার করা উচিত এবং বস্তুগুলিকে নিজেরাই জিনিসগুলি পরিচালনা করতে দেওয়া উচিত, তবে এটি সর্বদা কাম্য নয়।

বাস্তব বিশ্বে একজন কেরানী গাড়িটির ধরণটি দেখতেন এবং তার ভিত্তিতে তার করের ডেটা সন্ধান করতেন। আপনার সফ্টওয়্যারটি কেন একই ব্যস্ত বিধি অনুসরণ করবে না?


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

@ ডেভিডরবার্টজোনস - আদর্শভাবে, আমি গাড়ির লাইসেন্সের ভিত্তিতে পেমেন্টের ইতিহাস লগের সর্বশেষ অর্থ প্রদানের সন্ধান করব। শুল্ক প্রদান করের উদ্বেগ, গাড়ির উদ্বেগ নয়।
এরিক ফানকেনবাশ

5
@ ডেভিডরবার্টজোনস আমি মনে করি আপনি নিজের রূপকের সাথে নিজেকে বিভ্রান্ত করছেন। আপনার কাছে যা আছে তা আসল বাহন নয় যা একটি যানবাহন যা করে তার সমস্ত কাজ করা দরকার। পরিবর্তে, আপনি সরলতার জন্য একটি ট্যাক্সেবল (বা অনুরূপ কিছু) একটি যানবাহনের নাম দিয়েছেন have আপনার সম্পূর্ণ ডোমেন করের অর্থ প্রদান payments প্রকৃত যানবাহনগুলি কী করবে তা নিয়ে চিন্তা করবেন না। এবং, প্রয়োজনে রূপকটি ফেলে দিন এবং আরও উপযুক্ত একটি উপস্থাপন করুন।

3

আমি যা চাই না তা হ'ল (আমার মনে হয়):

২. বি) অ্যানিমিক ডোমেন, যার অর্থ ব্যবসায়িক সংস্থাগুলির মধ্যে ব্যবসায়িক যুক্তি।

আপনার এই পিছনের দিকে আছে। অ্যানিমিক ডোমেন হ'ল যুক্তিটি ব্যবসায়ের সত্তার বাইরে । যুক্তি বাস্তবায়নের জন্য অতিরিক্ত ক্লাস ব্যবহার করা কেন একটি খারাপ ধারণা; আপনার কেন এটি করা উচিত তার জন্য কেবল একটি দম্পতি।

এহেতু এটিকে রক্তস্বল্প বলা হবার কারণ: শ্রেণীর কোনও কিছুই নেই ..

আমি কি করব:

  1. আপনার বিমূর্ত যানবাহন ক্লাসটি একটি ইন্টারফেস হতে পরিবর্তন করুন।
  2. একটি ITaxPayment ইন্টারফেস যুক্ত করুন যা যানবাহনগুলি অবশ্যই প্রয়োগ করতে পারে। আপনার হ্যাশটোকে এখানে বন্ধ করে দিন।
  3. মোটরবাইকট্যাক্স পেমেন্ট, কারট্যাক্স পেমেন্ট, ট্যাক্স পেমেন্ট ক্লাসগুলি সরান। এগুলি অপ্রয়োজনীয় জটিলতা / বিশৃঙ্খলা।
  4. প্রতিটি গাড়ির ধরণের (গাড়ি, বাইক, মোটরহোম) ন্যূনতম যানবাহনে প্রয়োগ করা উচিত এবং যদি তারা কর আদায় করা হয় তবে এটি আইটিএক্সপেমেন্টও প্রয়োগ করতে হবে। এইভাবে আপনি যে যানবাহনগুলিতে শুল্ক আদায় করা হয় না এবং যেসব যানবাহন রয়েছে তাদের মধ্যে আপনি বর্ণনা করতে পারেন ... এই পরিস্থিতি এমনকি বিদ্যমান বলে ধরে নিচ্ছেন।
  5. প্রতিটি গাড়ির ধরণটি প্রয়োগ করা উচিত, ক্লাসের নিজের সীমানার মধ্যেই, আপনার ইন্টারফেসে বর্ণিত পদ্ধতিগুলি।
  6. এছাড়াও, আপনার ITaxPayment ইন্টারফেসে সর্বশেষ অর্থ প্রদানের তারিখ যুক্ত করুন।

তুমি ঠিক বলছো. মূলত প্রশ্নটি সেইভাবে তৈরি করা হয়নি, আমি একটি অংশ মুছে ফেলেছি এবং এর অর্থ পরিবর্তন হয়েছে। এটা এখন ঠিক। ধন্যবাদ!

2

কেন কোনও যানবাহনকে তার মূল্য দিতে হবে তা জানতে হবে? পাবলিক অ্যাডমিনিস্ট্রেশন উদ্বেগ না?

না, যেমন আমি এটি বুঝতে পারি আপনার সম্পূর্ণ অ্যাপ্লিকেশন কর দেওয়ার বিষয়ে। সুতরাং কোনও গাড়ির শুল্ক আদায় করা উচিত কিনা তা উদ্বেগ আর পাবলিক অ্যাডমিনিস্ট্রেটারেশন এর পরে আর পুরো প্রোগ্রামের আর কিছু নয়। এটিকে অন্য কোথাও রাখার কোনও কারণ নেই।

public class Car : Vehicle
{
    public override bool HasToPay()
    {
        return (DateTime.Today - this.LastPaidTime).TotalDays >= 30;
    }
}

public class Motorbike : Vehicle
{
    public override bool HasToPay()
    {
        return (DateTime.Today - this.LastPaidTime).TotalDays >= 60;
    }
}

এই দুটি কোড স্নিপেটগুলি কেবল ধ্রুবক দ্বারা পৃথক হয়। পুরো HasToPay () ফাংশনটিকে ওভাররাইড করার পরিবর্তে কোনও ফাংশন ওভাররাইড int DaysBetweenPayments()করে। ধ্রুবকটি ব্যবহার না করে কল করুন। যদি এগুলি হয় তবে তারা আসলে আলাদা হয়, আমি ক্লাসগুলি ফেলে দেব।

আমি আরও পরামর্শ দিচ্ছি যে মোটরবাইক / গাড়িটি তারপরে সাবক্লাসের পরিবর্তে গাড়ির একটি বিভাগের সম্পত্তি হওয়া উচিত। এটি আপনাকে আরও নমনীয়তা দেয়। উদাহরণস্বরূপ, এটি মোটরবাইক বা গাড়ির বিভাগ পরিবর্তন করা সহজ করে তোলে। অবশ্যই বাইকগুলি বাস্তব জীবনে গাড়িতে রূপান্তরিত হওয়ার সম্ভাবনা কম। তবে আপনি জানেন যে কোনও যান ভুল প্রবেশ করতে চলেছে এবং পরে এটি পরিবর্তন করা দরকার।

অবশ্যই, আমরা করের অর্থ পরিশোধের নির্মাতার কাছে মানটি পাস করতে পারি, তবে এটি যানবাহন আবরণ, বা দায়িত্বগুলি লঙ্ঘন করবে বা এই ওওপি প্রচারকরা যা বলুক না কেন, তা নয়?

আসলে তা না. একটি বস্তু যা পরামিতি হিসাবে ইচ্ছাকৃতভাবে তার ডেটা অন্য বস্তুর কাছে প্রেরণ করে এটি কোনও বৃহত এনক্যাপসুলেশন উদ্বেগ নয়। আসল উদ্বেগ হ'ল এই অবজেক্টের ভিতরে পৌঁছে যাওয়া অন্যান্য বস্তু যা তথ্য টেনে আনতে বা অবজেক্টের অভ্যন্তরে ডেটা ম্যানিপুলেট করে।


1

আপনি সঠিক পথে থাকতে পারেন। সমস্যাটি যেমনটি আপনি লক্ষ্য করেছেন যে, ট্যাক্সপমেন্টের মধ্যে লাস্টপেইডটাইম সদস্য নেই । এটি ঠিক যেখানে রয়েছে এটিই, যদিও এটি প্রকাশ্যে প্রকাশ করার দরকার নেই:

public interface ITaxPayment
{
    // Your base TaxPayment class will know the 
    // next due date. But you can easily create
    // one which uses (for example) fixed dates
    bool IsPaymentDue();
}

public interface IVehicle
{
    string Plate { get; }
    Person Owner { get; }
    ITaxPayment LastTaxPayment { get; }
} 

প্রতিবার আপনি কোনও অর্থ প্রদানের পরে, আপনি ITaxPaymentবর্তমান নীতিমালা অনুসারে এর একটি নতুন উদাহরণ তৈরি করেন , যার আগেরটির চেয়ে সম্পূর্ণ আলাদা বিধি থাকতে পারে।


জিনিসটি হ'ল পেমেন্টের প্রাপ্য মালিকের শেষ বার প্রদত্ত (বিভিন্ন গাড়ি, বিভিন্ন নির্ধারিত তারিখ) উপর নির্ভর করে। ITaxPayment কীভাবে জানতে পারে যে কোনও গাড়ি (বা মালিক) গণনা করার জন্য শেষবারের মতো অর্থ পরিশোধ করেছিল?

1

আমি @ সেবাস্তিয়ানজিগার এর উত্তরের সাথে একমত যে সমস্যাটি যানবাহনের পরিবর্তে গাড়ির মালিকানার বিষয়ে। আমি তার উত্তরটি ব্যবহার করার পরামর্শ দিচ্ছি তবে কয়েকটি পরিবর্তন নিয়ে। আমি Ownershipক্লাসটিকে একটি জেনেরিক ক্লাস করব:

public class Vehicle {}

public abstract class Ownership<T>
{
    public T Item { get; set; }

    public DateTime LastPaidTime { get; set; }

    public abstract TimeSpan PaymentInterval { get; }

    public virtual bool HasToPay
    {
        get { return (DateTime.Today - this.LastPaidTime) >= this.PaymentInterval; }
    }
}

এবং প্রতিটি গাড়ির ধরণের অর্থ প্রদানের ব্যবধান নির্দিষ্ট করতে উত্তরাধিকার ব্যবহার করুন। আমি TimeSpanসরল পূর্ণসংখ্যার পরিবর্তে দৃ strongly়-টাইপযুক্ত শ্রেণিটি ব্যবহার করার পরামর্শ দিই :

public class CarOwnership : Ownership<Vehicle>
{
    public override TimeSpan PaymentInterval
    {
        get { return new TimeSpan(30, 0, 0, 0); }
    }
}

public class MotorbikeOwnership : Ownership<Vehicle>
{
    public override TimeSpan PaymentInterval
    {
        get { return new TimeSpan(60, 0, 0, 0); }
    }
}

এখন আপনার আসল কোডটি কেবল একটি শ্রেণীর সাথে ডিল করতে হবে - Ownership<Vehicle>

public class PublicAdministration
{
    List<Ownership<Vehicle>> VehicleOwnerships { get; set; }

    public IEnumerable<Vehicle> GetVehiclesThatHaveToPay()
    {
        return VehicleOwnerships.Where(x => x.HasToPay).Select(x => x.Item);
    }
}

0

আমি এটি আপনার কাছে ভঙ্গ করতে পছন্দ করি না, তবে আপনার অ্যানিমিক ডোমেন রয়েছে , অর্থাত্‍ বস্তুর বাইরে ব্যবসায়িক যুক্তি। আপনি যদি এটির জন্য যাচ্ছেন ঠিকঠাক হয় তবে এটি এড়াতে আপনার কারণগুলি সম্পর্কে পড়া উচিত।

সমস্যা ডোমেনকে মডেল না করার চেষ্টা করুন, তবে সমাধানটির মডেল করুন। এজন্য আপনি সমান্তরাল উত্তরাধিকারের স্তরক্রম এবং আপনার প্রয়োজনের চেয়ে আরও জটিলতার সাথে শেষ করছেন।

এই উদাহরণটির জন্য আপনার প্রয়োজন এমন কিছু:

public class Vehicle
{
    public Boolean isMotorBike()
    public string PlateNumber { get; set; }
    public String Owner { get; set; }
    public DateTime LastPaidTime { get; set; }
}

public class TaxPaymentCalculator
{
    public List<Vehicle> GetVehiclesThatHaveToPay(List<Vehicle> all)
}

আপনি যদি সলাইড অনুসরণ করতে চান তবে তা দুর্দান্ত, তবে আঙ্কেল বব যেমন নিজে বলেছেন, তারা কেবল ইঞ্জিনিয়ারিং নীতি । এগুলি কঠোরভাবে প্রয়োগ করার উদ্দেশ্যে নয়, তবে নির্দেশিকাগুলি যা বিবেচনা করা উচিত are


4
আমি মনে করি আপনার সমাধানটি বিশেষভাবে স্কেলযোগ্য নয়। আপনার যুক্ত প্রতিটি ধরণের যানবাহনের জন্য আপনাকে একটি নতুন বুলিয়ান যুক্ত করতে হবে। এটি আমার মতে একটি খারাপ পছন্দ
এরিক ফানকেনবাশ

@ গ্যারেট হল, আমি পছন্দ করেছি আপনি আমার "ডোমেন" থেকে ব্যক্তি শ্রেণি সরিয়েছেন। আমার প্রথম ক্লাসটি ছিল না, তাই সম্পর্কে দুঃখিত। তবে ইসমোটারবাইকের কোনও অর্থ নেই। কোনটি বাস্তবায়ন হবে?

1
@ ডেভিডরবার্টজোনস: আমি মিস্ত্রি এর সাথে একমত, কোনও isMotorBikeপদ্ধতি যুক্ত করা ওওপি নকশা পছন্দ নয়। এটি বহুপ্রকারবাদকে কোনও টাইপ কোডের সাথে প্রতিস্থাপন করার মতো (একটি বুলিয়ান হিসাবে হলেও)।
গ্রো

@MystereMan, এক সহজে bools ড্রপ এবং ব্যবহার করতে পারেenum Vehicles
radarbob

+1 টি। সমস্যা ডোমেনকে মডেল না করার চেষ্টা করুন, তবে সমাধানটির মডেল করুনপিথি । স্মরণে ড। এবং নীতিগুলি মন্তব্য। আমি কঠোর আক্ষরিক ব্যাখ্যায় অনেক প্রচেষ্টা দেখছি ; ছাইপাঁশ.
রাডারবব

0

আমি মনে করি আপনি ঠিক বলেছেন যে অর্থ প্রদানের সময়টি আসল গাড়ি / মোটরবাইকের কোনও সম্পত্তি নয়। তবে এটি গাড়ির শ্রেণীর একটি বৈশিষ্ট্য।

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

তাহলে কেন এটি বেশ আক্ষরিক অর্থে তৈরি করা হয় না এবং এটিকে টানতে প্রতিবিম্ব ব্যবহার করে? এটার মতো কিছু:

[DaysBetweenPayments(30)]
public class Car : Vehicle
{
    // actual properties of the physical vehicle
}

[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class DaysBetweenPaymentsAttribute : Attribute, IPaymentRequiredCalculator
{
    private int _days;

    public DaysBetweenPaymentAttribute(int days)
    {
        _days = days;
    }

    public bool HasToPay(Vehicle vehicle)
    {
        return vehicle.LastPaid.AddDays(_days) <= DateTime.Now;
    }
}

যদি আপনি আরও স্বাচ্ছন্দ্য বোধ করেন তবে আপনি একটি স্থিতিশীল ভেরিয়েবলের সাথেও যেতে পারেন।

ডাউনসাইডগুলি হ'ল

  • এটি কিছুটা ধীর হয়ে যাবে এবং আমি ধরে নিচ্ছি আপনাকে প্রচুর যানবাহন প্রসেস করতে হবে। যদি এটি কোনও সমস্যা হয় তবে আমি আরও বাস্তববাদী দৃষ্টিভঙ্গি নিতে পারি এবং বিমূর্ত সম্পত্তি বা ইন্টারফেসড পদ্ধতির সাথে লেগে থাকি। (যদিও, আমিও টাইপ করে ক্যাশে বিবেচনা করব))

  • আপনাকে প্রারম্ভকালে যাচাই করতে হবে যে প্রতিটি যানবাহনের সাবক্লাসের একটি আইপায়মেন্টরাইকায়ার্ডক্যালকুলেটর বৈশিষ্ট্য রয়েছে (বা একটি ডিফল্টকে অনুমতি দিন), কারণ আপনি এটি 1000 গাড়ি প্রক্রিয়াকরণ করতে চান না, কেবল ক্র্যাশ করতে হবে কারণ মোটরবাইকটির পেমেন্টপরিড নেই।

উত্সাহটি হ'ল আপনি যদি পরে কোনও ক্যালেন্ডার মাস বা বার্ষিক অর্থ প্রদান করেন তবে আপনি কেবল একটি নতুন বৈশিষ্ট্য শ্রেণি লিখতে পারেন। এটি ওসিপির খুব সংজ্ঞা।


এর সাথে প্রধান সমস্যাটি হ'ল যদি আপনি কোনও যানবাহনের জন্য অর্থ প্রদানের মধ্যে দিনের সংখ্যা পরিবর্তন করতে চান তবে আপনাকে পুনর্নির্মাণ এবং পুনর্নির্মাণ করতে হবে এবং যদি সত্তার কোনও সংস্থার (যেমন ইঞ্জিনের আকার) ভিত্তিতে অর্থ প্রদানের ফ্রিকোয়েন্সি পরিবর্তিত হয় তবে তা হবে এটির জন্য একটি মার্জিত স্থির করা কঠিন।
এড জেমস

@ এডউডকক: আমি মনে করি প্রথম ইস্যু বেশিরভাগ সমাধানের ক্ষেত্রে সত্য এবং এটি আমাকে চিন্তিত করবে না। তারা যদি পরে সেই স্তরের নমনীয়তা চায় তবে আমি তাদের একটি ডিবি অ্যাপ্লিকেশন দেব। দ্বিতীয় বিষয়টিতে, আমি পুরোপুরি একমত নই। এই মুহুর্তে, আপনি কেবল হ্যাসটোপে () এর argumentচ্ছিক যুক্তি হিসাবে যানবাহন যুক্ত করুন এবং যেখানে আপনার এটির প্রয়োজন নেই তা এড়িয়ে যান।
পিডিআর

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

@ এডউডকক: আসলে, আমি কেবল এটি সম্পর্কে ভাবছিলাম এবং সর্বশেষ পেইড যুক্তিটি ইতিমধ্যে যানবাহনের সম্পত্তি হতে চলেছে। আপনার মন্তব্যে মাথায় রেখে, পরে যুক্তি পরিবর্তে - এখন যুক্তিটি প্রতিস্থাপনের উপযুক্ত হতে পারে - সম্পাদনা করবে।
pdr
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.