সি # তে কারখানার প্যাটার্ন: কীভাবে নিশ্চিত করা যায় যে কেবল কোনও কারখানার শ্রেণি দ্বারা কোনও অবজেক্ট উদাহরণ তৈরি করা যায়?


94

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

আসুন কিছু উদাহরণ চেষ্টা করুন:

public MyBusinessObjectClass
{
    public string MyProperty { get; private set; }

    public MyBusinessObjectClass (string myProperty)
    {
        MyProperty = myProperty;
    }
}

public MyBusinessLogicClass
{
    public MyBusinessObjectClass CreateBusinessObject (string myProperty)
    {
        // Perform some check on myProperty

        if (true /* check is okay */)
            return new MyBusinessObjectClass (myProperty);

        return null;
    }
}

আপনি যতক্ষণ না মনে করেন আপনি ঠিক ততক্ষণে ইনপুটটি পরীক্ষা না করেই সরাসরি MyBusinessObjectClass উদাহরণ তৈরি করতে পারবেন এটি ঠিক আছে। আমি সেই প্রযুক্তিগত সম্ভাবনাটি পুরোপুরি বাদ দিতে চাই।

সুতরাং, সম্প্রদায় এ সম্পর্কে কী ভাববে?


মাইবোক্লাস পদ্ধতিটি ভুলভাবে জড়িত?
প্রদীপটিপ

4
আমি বিভ্রান্ত হয়ে পড়েছি, আপনি কেন নিজের ব্যবসায়িক জিনিসগুলিকে তাদের নিজস্ব আক্রমণকারীদের রক্ষার জন্য দায়ী করতে চান না? কারখানার প্যাটার্নটির বিন্দু (যেহেতু আমি এটি বুঝতে পারি) হয় এ) অনেকগুলি নির্ভরশীলতা বা বি সহ একটি জটিল শ্রেণি তৈরির সাথে সম্পর্কিত) কারখানাটি কী রানটাইম টাইপটি ফিরে আসবে তা সিদ্ধান্ত নিতে পারে, কেবল একটি ইন্টারফেস / বিমূর্ততা প্রকাশ করে ক্লায়েন্ট ক্লায়েন্ট। আপনার ব্যবসায়ের নিয়মগুলিকে আপনার ব্যবসায়িক আইটেমগুলিতে স্থাপন করা ওওপির খুব ESSENCE।
সারা

@ কাই সত্য, ব্যবসায়ের বস্তুটি তার আক্রমণকারীটিকে রক্ষা করার জন্য দায়ী, তবে কনস্ট্রাক্টর কলারটি কনস্ট্রাক্টারে যাওয়ার আগে আর্গুমেন্টগুলি বৈধ কিনা তা নিশ্চিত করা ! CreateBusinessObjectপদ্ধতির উদ্দেশ্য হ'ল আর্গুমেন্টগুলি বৈধ করা এবং একটি একক পদ্ধতিতে কল করার সময় (কোনও নতুন বৈধ অবজেক্ট ফেরত দেওয়া বা ত্রুটি ফিরিয়ে দেওয়া) যখন একজন কলকারী তাত্ক্ষণিকভাবে জানতে না পারে যে কনস্ট্রাক্টরের কাছে যাওয়ার জন্য আর্গুমেন্টগুলি বৈধ কিনা।
লাইটম্যান

4
আমি একমত নই নির্ধারক প্রদত্ত প্যারামিটারগুলির জন্য প্রয়োজনীয় চেক করার জন্য দায়বদ্ধ। যদি আমি কোনও কনস্ট্রাক্টরকে কল করি এবং কোনও ব্যতিক্রম ছুঁড়ে না দেওয়া হয় তবে আমি বিশ্বাস করি যে তৈরি করা বস্তুটি একটি বৈধ অবস্থায় রয়েছে। শারীরিকভাবে "ভুল" যুক্তি ব্যবহার করে কোনও শ্রেণি ইনস্ট্যান্ট করা উচিত নয়। Distanceনেতিবাচক যুক্তি দিয়ে একটি উদাহরণ তৈরি করা উদাহরণস্বরূপ হওয়া উচিত ArgumentOutOfRangeException, আপনি DistanceFactoryএকই চেকটি তৈরি করে কোনও কিছুই অর্জন করতে চাইবেন না । আপনি এখানে কী অর্জন করার পক্ষে দাঁড়িয়েছেন তা আমি এখনও দেখতে পাচ্ছি না।
সারা

উত্তর:


55

দেখে মনে হচ্ছে আপনি অবজেক্টটি তৈরি করার আগে কিছুটা ব্যবসায়িক যুক্তি চালাতে চান - তবে আপনি কেন "বিজনেসক্লাস" এর ভিতরে একটি স্থির পদ্ধতি তৈরি করেন না যা সমস্ত নোংরা "মাইপ্রোপার্টি" পরীক্ষার কাজ করে এবং নির্মাণকারীকে ব্যক্তিগত করে তোলে?

public BusinessClass
{
    public string MyProperty { get; private set; }

    private BusinessClass()
    {
    }

    private BusinessClass(string myProperty)
    {
        MyProperty = myProperty;
    }

    public static BusinessClass CreateObject(string myProperty)
    {
        // Perform some check on myProperty

        if (/* all ok */)
            return new BusinessClass(myProperty);

        return null;
    }
}

এটি কল করা বেশ সহজবোধ্য হবে:

BusinessClass objBusiness = BusinessClass.CreateObject(someProperty);

6
আহ, আপনি নাল ফেরার পরিবর্তে একটি ব্যতিক্রমও ছুঁড়ে ফেলতে পারেন।
রিকার্ডো নলদে

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

কোনও ইন্টারফেস / অ্যাবস্ট্রাক্ট বেস ক্লাসের মাধ্যমে এই আর্কিটেকচারটির প্রয়োজনীয় কোনও ভাল উপায়? অর্থাত্ একটি ইন্টারফেস / অ্যাবস্ট্রাক্ট বেস ক্লাস যা আদেশ দেয় যে প্রয়োগকারীরা কোনও কর্টির বহিঃপ্রকাশ করা উচিত নয়।
আরশ মোতামেদী

4
@ আরশ নং ইন্টারফেসগুলি কনস্ট্রাক্টরকে সংজ্ঞায়িত করতে পারে না এবং কোনও সুরক্ষিত বা অভ্যন্তরীণ কনস্ট্রাক্টরকে সংজ্ঞায়িত করে এমন একটি বিমূর্ত শ্রেণি তার নিজস্ব পাবলিক কনস্ট্রাক্টরের মাধ্যমে উত্তরাধিকার সূত্রে প্রাপ্ত ক্লাসগুলি প্রকাশ করতে বাধা দিতে পারে না।
রিকার্ডো নলদে

66

আপনি কনস্ট্রাক্টরকে বেসরকারী এবং কারখানাকে নেস্টেড টাইপ করতে পারেন:

public class BusinessObject
{
    private BusinessObject(string property)
    {
    }

    public class Factory
    {
        public static BusinessObject CreateBusinessObject(string property)
        {
            return new BusinessObject(property);
        }
    }
}

এটি কাজ করে কারণ নেস্টেড প্রকারের তাদের ঘেরের ধরণের ব্যক্তিগত সদস্যদের অ্যাক্সেস রয়েছে। আমি জানি এটি কিছুটা সীমাবদ্ধ তবে আশা করি এটি সাহায্য করবে ...


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

@ তাই-পরীক্ষক: আপনি এখনও কারখানাটিতে বিজনেসঅবজেক্টের ধরণের চেয়ে চেকগুলি রাখতে পারেন।
জন স্কিটি

4
@ জোনস্কিট আমি জানি এই প্রশ্নটি আসলেই পুরানো, তবে আমি স্থির পদ্ধতিটি ক্লাসের সরাসরি একটি পদ্ধতি হওয়ার পরিবর্তে CreateBusinessObjectকোনও নীড়বিত্ত Factoryশ্রেণীর ভিতরে পদ্ধতি স্থাপন করার সুবিধা কী তা নিয়ে আমি কৌতূহল বোধ করছি BusinessObject... আপনি কি আপনার স্মরণ করতে পারবেন এটা করার জন্য অনুপ্রেরণা?
কিলি ন্যারো

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

53

অথবা, আপনি যদি সত্যিই অভিনব হয়ে যেতে চান, তবে উল্টা নিয়ন্ত্রণ করুন: ক্লাসটি কারখানাটি ফিরিয়ে দিন এবং ক্লাস তৈরি করতে পারে এমন একটি প্রতিনিধি দিয়ে কারখানায় সরঞ্জাম তৈরি করুন।

public class BusinessObject
{
  public static BusinessObjectFactory GetFactory()
  {
    return new BusinessObjectFactory (p => new BusinessObject (p));
  }

  private BusinessObject(string property)
  {
  }
}

public class BusinessObjectFactory
{
  private Func<string, BusinessObject> _ctorCaller;

  public BusinessObjectFactory (Func<string, BusinessObject> ctorCaller)
  {
    _ctorCaller = ctorCaller;
  }

  public BusinessObject CreateBusinessObject(string myProperty)
  {
    if (...)
      return _ctorCaller (myProperty);
    else
      return null;
  }
}

:)


খুব সুন্দর কোড। অবজেক্ট তৈরির যুক্তি একটি পৃথক শ্রেণিতে রয়েছে এবং কেবলমাত্র কারখানাটি ব্যবহার করে অবজেক্ট তৈরি করা যেতে পারে।
নিকোলাই সামতেলেজ

শীতল। এমন কোনও উপায় আছে যে আপনি বিজনেসঅজেক্টফ্যাক্টরি তৈরিটিকে স্থির বিজনেসবজেক্ট.গেটফ্যাক্টির মধ্যে সীমাবদ্ধ করতে পারবেন?
ফেলিক্স কেয়েল

4
এই বিপরীতে সুবিধা কী?
ইয়াতস্কোস্কি

4
@ আইটস্কোভস্কি এটি নিশ্চিত করার একমাত্র উপায় যে এখনও কোনও নিয়ন্ত্রিত ফ্যাশনে বস্তুটি কেবল ইনস্ট্যান্ট করা যেতে পারে এবং তবুও কোনও উত্সর্গীকৃত শ্রেণিতে সৃষ্টির যুক্তিকে ফ্যাক্ট করতে সক্ষম হয়।
ফ্যাবিয়ান শমিড

15

আপনি আপনার MyBusinessObjectClass শ্রেণীর অভ্যন্তরীণে কনস্ট্রাক্টর তৈরি করতে পারেন এবং এটি এবং কারখানাকে তাদের নিজস্ব সমাবেশে স্থানান্তর করতে পারেন। এখন কেবল কারখানাটি ক্লাসের একটি উদাহরণ তৈরি করতে সক্ষম হবে।


7

জনের পরামর্শ অনুসারে আপনি কারখানার পদ্ধতিতে (চেক সহ) প্রথম স্থানে বিজনেসঅবজেক্টের একটি স্থির পদ্ধতি হতে পারেন। তারপরে, কনস্ট্রাক্টরকে ব্যক্তিগত রাখুন এবং অন্য প্রত্যেকে স্থির পদ্ধতিটি ব্যবহার করতে বাধ্য হবে।

public class BusinessObject
{
  public static Create (string myProperty)
  {
    if (...)
      return new BusinessObject (myProperty);
    else
      return null;
  }
}

তবে আসল প্রশ্নটি হল - আপনার এ প্রয়োজনীয়তা কেন? কারখানা বা কারখানার পদ্ধতিটি ক্লাসে স্থানান্তরিত করা কি গ্রহণযোগ্য?


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

আপনি যদি কেবল সুবিধার জন্য পর্যালোচনা করার জন্য যুক্তি এবং একটি শ্রেণির কাঠামো পৃথক করতে চান তবে আপনি সর্বদা একটি আংশিক শ্রেণি ব্যবহার করতে পারেন এবং উভয় পৃথক ফাইলে থাকতে পারেন ...
Grx70

7

এত বছর পরে এটি জিজ্ঞাসা করা হয়েছে, এবং আমি যে সমস্ত উত্তর দেখছি তা দুর্ভাগ্যক্রমে আপনাকে বলছে যে আপনার সরল উত্তর দেওয়ার পরিবর্তে আপনার কোডটি কীভাবে করা উচিত। আপনি যে প্রকৃত উত্তরটির সন্ধান করছিলেন তা হ'ল প্রাইভেট কনস্ট্রাক্টর কিন্তু একটি পাবলিক ইনস্ট্যান্টিয়েটারের সাথে আপনার ক্লাস করা, যার অর্থ আপনি কেবলমাত্র অন্য বিদ্যমান দৃষ্টান্তগুলি থেকে নতুন উদাহরণ তৈরি করতে পারবেন ... যা কেবলমাত্র কারখানায় উপলভ্য:

আপনার ক্লাসের জন্য ইন্টারফেস:

public interface FactoryObject
{
    FactoryObject Instantiate();
}

তোমার শ্রেণী:

public class YourClass : FactoryObject
{
    static YourClass()
    {
        Factory.RegisterType(new YourClass());
    }

    private YourClass() {}

    FactoryObject FactoryObject.Instantiate()
    {
        return new YourClass();
    }
}

এবং, অবশেষে, কারখানা:

public static class Factory
{
    private static List<FactoryObject> knownObjects = new List<FactoryObject>();

    public static void RegisterType(FactoryObject obj)
    {
        knownObjects.Add(obj);
    }

    public static T Instantiate<T>() where T : FactoryObject
    {
        var knownObject = knownObjects.Where(x => x.GetType() == typeof(T));
        return (T)knownObject.Instantiate();
    }
}

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


4

তবুও আরেকটি (লাইটওয়েট) বিকল্প হ'ল বিজনেসঅবজেক্ট ক্লাসে একটি স্ট্যাটিক কারখানার পদ্ধতি তৈরি করা এবং কনস্ট্রাক্টরকে ব্যক্তিগত রাখা।

public class BusinessObject
{
    public static BusinessObject NewBusinessObject(string property)
    {
        return new BusinessObject();
    }

    private BusinessObject()
    {
    }
}

2

সুতরাং, দেখে মনে হচ্ছে যা আমি চাই তা "বিশুদ্ধ" উপায়ে করা যায় না। এটি সর্বদা যুক্তি শ্রেণীর কাছে একরকম "কল ব্যাক" থাকে।

সম্ভবত আমি এটি একটি সহজ উপায়ে করতে পারলাম, কেবলমাত্র অবজেক্ট ক্লাসে একটি কনট্রাক্টর পদ্ধতি তৈরি করুন ইনপুটটি পরীক্ষা করার জন্য প্রথমে লজিক ক্লাসে কল করুন?

public MyBusinessObjectClass
{
    public string MyProperty { get; private set; }

    private MyBusinessObjectClass (string myProperty)
    {
        MyProperty  = myProperty;
    }

    pubilc static MyBusinessObjectClass CreateInstance (string myProperty)
    {
        if (MyBusinessLogicClass.ValidateBusinessObject (myProperty)) return new MyBusinessObjectClass (myProperty);

        return null;
    }
}

public MyBusinessLogicClass
{
    public static bool ValidateBusinessObject (string myProperty)
    {
        // Perform some check on myProperty

        return CheckResult;
    }
}

এইভাবে, ব্যবসায়ের অবজেক্টটি সরাসরি তৈরিযোগ্য নয় এবং ব্যবসায়িক যুক্তিতে পাবলিক চেক পদ্ধতিতে কোনও ক্ষতি করতে হবে না।


2

ইন্টারফেস এবং বাস্তবায়নের মধ্যে ভাল বিভাজনের ক্ষেত্রে
সুরক্ষিত-নির্মাণকারী-পাবলিক-ইনিশিয়ালাইজার প্যাটার্ন একটি খুব ঝরঝরে সমাধানের অনুমতি দেয়।

একটি ব্যবসায়িক বস্তু দেওয়া হয়েছে:

public interface IBusinessObject { }

class BusinessObject : IBusinessObject
{
    public static IBusinessObject New() 
    {
        return new BusinessObject();
    }

    protected BusinessObject() 
    { ... }
}

এবং একটি ব্যবসায়িক কারখানা:

public interface IBusinessFactory { }

class BusinessFactory : IBusinessFactory
{
    public static IBusinessFactory New() 
    {
        return new BusinessFactory();
    }

    protected BusinessFactory() 
    { ... }
}

BusinessObject.New()আরম্ভকারীকে নিম্নলিখিত পরিবর্তন সমাধান দেয়:

class BusinessObject : IBusinessObject
{
    public static IBusinessObject New(BusinessFactory factory) 
    { ... }

    ...
}

BusinessObject.New()ইনিশিয়ালাইজারকে কল করার জন্য এখানে কংক্রিট বিজনেস কারখানার একটি রেফারেন্স প্রয়োজন needed তবে কেবলমাত্র যার কাছে প্রয়োজনীয় রেফারেন্স রয়েছে তা হ'ল ব্যবসায় কারখানা।

শুধুমাত্র এক যারা তৈরি করতে পারেন: আমরা যা চেয়েছিলাম পেয়েছিলাম BusinessObjectহয় BusinessFactory


সুতরাং আপনি নিশ্চিত হন যে অবজেক্টের একমাত্র কর্মক্ষম পাবলিক কনস্ট্রাক্টরের জন্য একটি কারখানা প্রয়োজন, এবং প্রয়োজন কারখানার প্যারামিটার কেবলমাত্র কারখানার স্থির পদ্ধতিতে কল করে ইনস্ট্যান্ট করা যেতে পারে? একটি কার্যনির্বাহী সমাধানের মতো মনে হচ্ছে তবে আমি অনুভূতিটি পেয়েছি যে স্নিপেটগুলি public static IBusinessObject New(BusinessFactory factory) অন্য কেউ কোডটি বজায় রাখলে অনেকগুলি ভ্রু বাড়াবে।
ফ্ল্যাটার

@ ফ্লাটার সম্মত আমি প্যারামিটার নাম পরিবর্তন হবে factoryমধ্যে asFriend। আমার কোড বেসে এটি তখন প্রদর্শিত হবেpublic static IBusinessObject New(BusinessFactory asFriend)
রিউভেন বাস

আমি এটা মোটেও পাই না। এটা কিভাবে কাজ করে? কারখানাটি আই বিজনেসঅবজেক্টের নতুন দৃষ্টান্ত তৈরি করতে পারে না বা এটি করার কোনও ইচ্ছা (পদ্ধতি) নেই ...?
ল্যাপস

2
    public class HandlerFactory: Handler
    {
        public IHandler GetHandler()
        {
            return base.CreateMe();
        }
    }

    public interface IHandler
    {
        void DoWork();
    }

    public class Handler : IHandler
    {
        public void DoWork()
        {
            Console.WriteLine("hander doing work");
        }

        protected IHandler CreateMe()
        {
            return new Handler();
        }

        protected Handler(){}
    }

    public static void Main(string[] args)
    {
        // Handler handler = new Handler();         - this will error out!
        var factory = new HandlerFactory();
        var handler = factory.GetHandler();

        handler.DoWork();           // this works!
    }

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

4
আপনার উদাহরণে, নিম্নলিখিতগুলি কী সম্ভব হবে না (যা বোঝায় না?): কারখানা.ডো ওয়ার্ক ();
কেন

1

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

public class Person
{
  internal Person()
  {
  }
}

public class PersonFactory
{
  public Person Create()
  {
    return new Person();
  }  
}

যাইহোক, আমি অবশ্যই আপনার পদ্ধতির প্রশ্ন করা উচিত :-)

আমি মনে করি আপনি যদি নিজের ব্যক্তি শ্রেণিটি তৈরির ভিত্তিতে বৈধ হয়ে উঠতে চান তবে আপনাকে অবশ্যই কোডটি কনস্ট্রাক্টরে রেখে দিতে হবে।

public class Person
{
  public Person(string firstName, string lastName)
  {
    FirstName = firstName;
    LastName = lastName;
    Validate();
  }
}

1

এই সমাধানটি কনস্ট্রাক্টরে একটি টোকেন ব্যবহার করার ক্ষুদ্র ধারণাটি ভিত্তিক । এই উত্তরের কাজটি নিশ্চিত হয়ে নিন যে কেবলমাত্র কারখানায় তৈরি সিটি তৈরি করা হয়েছে (সি #)

  public class BusinessObject
    {
        public BusinessObject(object instantiator)
        {
            if (instantiator.GetType() != typeof(Factory))
                throw new ArgumentException("Instantiator class must be Factory");
        }

    }

    public class Factory
    {
        public BusinessObject CreateBusinessObject()
        {
            return new BusinessObject(this);
        }
    }

1

বিভিন্ন ট্রেড অফের সাথে একাধিক পদ্ধতির উল্লেখ করা হয়েছে।

  • বেসরকারীভাবে নির্মিত ক্লাসে কারখানার শ্রেণিতে বাসা বাঁধাই কেবল কারখানাকে 1 টি শ্রেণি তৈরির অনুমতি দেয়। এই মুহুর্তে আপনি একটি সঙ্গে ভাল বন্ধCreate পদ্ধতি এবং একটি প্রাইভেট সিটার better
  • উত্তরাধিকার এবং একটি সুরক্ষিত ctor ব্যবহার করে একই সমস্যা রয়েছে।

আমি কারখানাকে আংশিক শ্রেণি হিসাবে প্রস্তাব দিতে চাই যাতে সরকারী নির্মাতাদের সাথে প্রাইভেট নেস্টেড ক্লাস থাকে। আপনার ফ্যাক্টরিটি যে বস্তুটি তৈরি করছে তা আপনি 100% লুকিয়ে রেখেছেন এবং কেবল এক বা একাধিক ইন্টারফেসের মাধ্যমে আপনি যা চয়ন করছেন তা প্রকাশ করছে।

আপনি যে কারখানার 100% উদাহরণ ট্র্যাক করতে চান তা এর জন্য শুনেছি ব্যবহারের কেসটি। এই নকশাটি কারও গ্যারান্টি দেয় না তবে কারখানার "কারখানায়" সংজ্ঞায়িত "রাসায়নিক" উদাহরণ তৈরি করতে অ্যাক্সেস রয়েছে এবং এটি অর্জনের জন্য এটি পৃথক সমাবেশের প্রয়োজনীয়তা সরিয়ে দেয়।

== ChemicalFactory.cs ==
partial class ChemicalFactory {
    private  ChemicalFactory() {}

    public interface IChemical {
        int AtomicNumber { get; }
    }

    public static IChemical CreateOxygen() {
        return new Oxygen();
    }
}


== Oxygen.cs ==
partial class ChemicalFactory {
    private class Oxygen : IChemical {
        public Oxygen() {
            AtomicNumber = 8;
        }
        public int AtomicNumber { get; }
    }
}



== Program.cs ==
class Program {
    static void Main(string[] args) {
        var ox = ChemicalFactory.CreateOxygen();
        Console.WriteLine(ox.AtomicNumber);
    }
}

0

আপনি কেন "ব্যবসায়িক বিষয়" থেকে "ব্যবসায়িক যুক্তি" আলাদা করতে চান তা আমি বুঝতে পারি না। এটি অবজেক্ট ওরিয়েন্টেশনের বিকৃতির মতো শোনাচ্ছে এবং আপনি এই পদ্ধতির সাহায্যে নিজেকে গিঁটে বেঁধে ফেলবেন।


আমি এই পার্থক্যটিও বুঝতে পারি না। কেউ কেন এটি করা হচ্ছে তা ব্যাখ্যা করতে পারেন এবং ব্যবসায়ের ক্ষেত্রে কী কোড থাকবে?
পাইপজাইক

এটি কেবলমাত্র একটি পন্থা যা ব্যবহার করা যেতে পারে আমি চাই ব্যবসায়ের অবজেক্টটি মূলত ডেটা স্ট্রাকচার হতে পারে তবে পড়ার / লেখার জন্য সমস্ত ক্ষেত্র খোলা থাকে না। তবে প্রশ্নটি ছিল সরাসরি কোনও কারখানার পদ্ধতির সাহায্যে কোনও অবজেক্টকে ইনস্ট্যান্ট করতে সক্ষম হওয়া সম্পর্কে।
ব্যবহারকারী

@ জিম: আমি ব্যক্তিগতভাবে আপনার বক্তব্যের সাথে একমত, তবে পেশাগতভাবে, এটি নিয়মিতভাবে করা হয়। আমার বর্তমান প্রকল্পটি এমন একটি ওয়েবসার্চ যা একটি এইচটিএমএল স্ট্রিং নেয়, কিছু প্রিসেট নিয়ম অনুসারে এটি পরিষ্কার করে, তারপরে সাফ স্ট্রিংটি দেয়। আমার নিজস্ব কোডের 7 টি স্তরটি অতিক্রম করতে হবে "কারণ আমাদের সমস্ত প্রকল্প অবশ্যই একই প্রকল্পের টেম্পলেট থেকে তৈরি করা উচিত"। এটি কারণ হিসাবে দাঁড়িয়েছে যে বেশিরভাগ লোকেরা এসও এই প্রশ্নগুলি জিজ্ঞাসা করে তাদের কোডের পুরো প্রবাহ পরিবর্তন করার স্বাধীনতা পায় না।
ফ্লাটার

0

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

একটি বিকল্প হ'ল একটি স্ট্যাটিক কনস্ট্রাক্টর যা কোনও আইওসি পাত্রের মতো কিছু দিয়ে কারখানায় নিবন্ধন করে।


0

"কেবলমাত্র আপনার বোঝানো উচিত নয়" এর শিরায় আরও একটি সমাধান দেওয়া হল ...

এটি ব্যবসায়িক অবজেক্ট কনস্ট্রাক্টরকে ব্যক্তিগত রাখার এবং কারখানার যুক্তিকে অন্য শ্রেণিতে রাখার প্রয়োজনীয়তা পূরণ করে। এর পরে এটি কিছুটা স্কেচিযুক্ত হয়ে যায়।

কারখানার শ্রেণিতে ব্যবসায়িক অবজেক্ট তৈরির জন্য একটি স্থিত পদ্ধতি রয়েছে। এটি স্ট্যাটিক সুরক্ষিত নির্মাণ পদ্ধতি অ্যাক্সেস করার জন্য ব্যবসায়িক অবজেক্ট শ্রেণি থেকে উদ্ভূত যা প্রাইভেট কনস্ট্রাক্টরকে অনুরোধ করে।

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

কি আটকানো না ক্লায়েন্ট কোড এছাড়াও ব্যবসা বস্তুর ক্লাস থেকে আহরিত এবং সুরক্ষিত (কিন্তু unvalidated) স্ট্যাটিক নির্মাণ পদ্ধতি কলিং। বা আরও খারাপ, সুরক্ষিত ডিফল্ট কনস্ট্রাক্টরকে কল করে আমাদের ফ্যাক্টরি ক্লাসটি প্রথম স্থানে সংকলনের জন্য যুক্ত করতে হয়েছিল। (যা ঘটনাক্রমে কোনও প্যাটার্নে সমস্যা হতে পারে যা কারখানার শ্রেণিটি ব্যবসায়ের বস্তু শ্রেণি থেকে পৃথক করে))

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

using System;

public class MyBusinessObjectClass
{
    public string MyProperty { get; private set; }

    private MyBusinessObjectClass(string myProperty)
    {
        MyProperty = myProperty;
    }

    // Need accesible default constructor, or else MyBusinessObjectFactory declaration will generate:
    // error CS0122: 'MyBusinessObjectClass.MyBusinessObjectClass(string)' is inaccessible due to its protection level
    protected MyBusinessObjectClass()
    {
    }

    protected static MyBusinessObjectClass Construct(string myProperty)
    {
        return new MyBusinessObjectClass(myProperty);
    }
}

public abstract class MyBusinessObjectFactory : MyBusinessObjectClass
{
    public static MyBusinessObjectClass CreateBusinessObject(string myProperty)
    {
        // Perform some check on myProperty

        if (true /* check is okay */)
            return Construct(myProperty);

        return null;
    }

    private MyBusinessObjectFactory()
    {
    }
}

0

এই সমাধান সম্পর্কে কিছু চিন্তা শুনে প্রশংসা করবে। 'মাই ক্লাসপ্রাইভেলিজকি' তৈরি করতে সক্ষম একমাত্র কারখানাটি। এবং 'মাইক্লাস' এর কনস্ট্রাক্টরে এটি প্রয়োজন। এভাবে কারখানায় বেসরকারী ঠিকাদার / "নিবন্ধকরণ" প্রতিফলন এড়ানো।

public static class Runnable
{
    public static void Run()
    {
        MyClass myClass = MyClassPrivilegeKey.MyClassFactory.GetInstance();
    }
}

public abstract class MyClass
{
    public MyClass(MyClassPrivilegeKey key) { }
}

public class MyClassA : MyClass
{
    public MyClassA(MyClassPrivilegeKey key) : base(key) { }
}

public class MyClassB : MyClass
{
    public MyClassB(MyClassPrivilegeKey key) : base(key) { }
}


public class MyClassPrivilegeKey
{
    private MyClassPrivilegeKey()
    {
    }

    public static class MyClassFactory
    {
        private static MyClassPrivilegeKey key = new MyClassPrivilegeKey();

        public static MyClass GetInstance()
        {
            if (/* some things == */true)
            {
                return new MyClassA(key);
            }
            else
            {
                return new MyClassB(key);
            }
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.