Back to list
Views:   0
Replies:  0
Archived
,
Reply 1
My Understanding -there are three supplier with whom we have to xml interfacing to perform some operations. such as car rental website does same thing with different car suppliers for book/cancel/availability etc...

Factory Method design pattern  to create instance of supplier
Facade can also be used.

Thanks,
Dharmesh
Dharmesh Parekh, Nov 20, 2016
Reply 2
How about the Strategy and Factory patterns.

See example, below. I left out error checking for clarity.

How you want to pass around the derived classes (Agency1, Agency2, ... the data) is up to you. I find this way to be the easiest, but will vary depending on your app.

You could also add a property to set the behavior and pass in the required data in some other fashion.

I think you'll get the idea, though.

And, of course, the "swtich" statement in the main controller is not ideal. That too could be put into a factory.

I just wanted to illustrate and suggest the Strategy pattern without writing an entire app.

Hope this helps,

Mike

using System;

namespace MyCompany.Agency
{
    interface IAgencyBehavior
    {
        int GetNumberOfCarsAvailable();
        void SubmitRental();
    }

    public abstract class Agency
    {
        public string AgencyName { get; set;}
        public string FirstName { get; set; }
        public string LastName { get; set; }
        // all other properties common to all agencies
    }

    // A specialized agency:
    public class Agency1 : Agency
    { 
        public Agency1() 
        {
            AgencyName = "Agency1";
        }
        public DateTime DOB {get; set;} 
    }

    // A specialized agency:
    public class Agency2 : Agency
    {
        public Agency2() 
        {
            AgencyName = "Agency2";
        }
        public string LicenseNumber { get; set; }
    }

    // Main controller:
    public class AgencyMainController : IAgencyBehavior
    {
        private IAgencyBehavior _behavior;

        public AgencyMainController(Agency agency)
        {
            NewBehavior(agency);
        }

        public void NewBehavior(Agency agency)
        {
            switch (agency.AgencyName.ToLower())
            {
                case "agency1":
                    _behavior = new Agency1Behavior((Agency1)agency);
                    break;

                case "agency2":
                    _behavior = new Agency2Behavior((Agency2)agency);
                    break;

                default:
                    // Maybe throw an exception here
                    break;
            }
        }
        public int GetNumberOfCarsAvailable()
        {
            if (_behavior == null) throw new ArgumentException("Behavior has not yet been set");
            return _behavior.GetNumberOfCarsAvailable();
        }

        public void SubmitRental()
        {
            if (_behavior == null) throw new ArgumentException("Behavior has not yet been set");
            _behavior.SubmitRental();
        }
    }

    // Specialized controllers:
    public class Agency1Behavior : IAgencyBehavior
    {
        private Agency1 _agency;
        public Agency1Behavior(Agency1 agency)
        {
            _agency = agency;
        }
        public int GetNumberOfCarsAvailable()
        {
            return 1;
        }

        public void SubmitRental()
        {
            // Code here to submit Agency1's XML 
            Console.WriteLine("<Rental AgencyName=\"Agency1\"><Name>" + _agency.FirstName + " " + _agency.LastName + "><DOB>" + _agency.DOB.ToString("MM/dd/yy") + "</DOB></Rental>");
        }
    }

    public class Agency2Behavior : IAgencyBehavior
    {
        private Agency2 _agency;

        public Agency2Behavior(Agency2 agency)
        {
            _agency = agency;
        }

        public int GetNumberOfCarsAvailable()
        {
            return 2;
        }

        public void SubmitRental()
        {
            // Code here to submit Agency2's XML 
            Console.WriteLine("<Rental AgencyName=\"Agency2\"><Name>" + _agency.FirstName + " " + _agency.LastName + "<LicenseNumber>" + _agency.LicenseNumber + "</LicenseNumber></Rental>");
        }
    }


    // Example client code:
    public class MyApp
    {
        public static void Main(string[] args) 
        {
            // Somehow, somewhere you retrieved information and determined it's Agency2 and constructed an Agency2 object (perhaps through a factory):
            Agency2 agency2Object = new Agency2() {LicenseNumber="ABC123", FirstName="John", LastName="Doe"};

            AgencyMainController controller = new AgencyMainController(agency2Object);
            controller.SubmitRental();
            Console.WriteLine(controller.GetNumberOfCarsAvailable().ToString());

            // Agency1:
            Agency1 agency1Object = new Agency1() { DOB = DateTime.Now.AddYears(-20) , FirstName = "Jane", LastName = "Doe" };
            controller.NewBehavior(agency1Object);
            controller.SubmitRental();
            Console.WriteLine(controller.GetNumberOfCarsAvailable().ToString());
            Console.ReadKey();

        }
    }
}

 
Michael Lopez, Jul 20, 2012
Reply 3
Just sharing my thoughts here, may need to fine tune - as I have not tried this solution yet (may be I can get back)

Two key aspects here:
1) If you are going to process all of your Agency's XMLs (whatever may their format) into a common format - Adapter Pattern.
2) If you want to have classes or entities into your system, to represent each Agency XML , then you would need - Factory Pattern

For case 1 , you can read an agency XML into an XML object and then "adapt" its contents to your target class - Say Agency Mapper
Whenever a new schema comes into scope, you need to adapt it to the AgencyMapper class. 

For case 2:

You have build Factory pattern, that each Agency XML becomes a concrete product. I hope you would not need another layer of abstraction here. In this case whenever a new (type of) Agency comes in you may need to add a new COncrete class. I think IOC containers will help here to avoid adding code into the system.


Quick steps:

1) Have multiple Schema files each representing an Agency XML, (saved to your working directory) like Agency1.XSD..etc.,
2) When you start processing, your system should read an Agency XML file and try validating it against the existing schemas.
3) when it matches with one of the Schemas , your code should assign a type (enum?) like Agency1 or AgencyTwo etc.,
4) Pass the type Factory class that it creates the corresponding Agency Class
5) Have a mapper method in each class that it reads XML and initializes corresponding members ( I maintain the class name and XML attribute name to be the same, that I can use reflection to loop through and assign at runtime)
6) then call Submit rental()

To answer Abstract Factory or interface, if you want to enforce things against unrelated entities - interface
To enfore and enable versioning across related entities - abstract classes

Thanks and Regards
Tarriq
Tarriq Ferrose Khan, Jul 19, 2012
Stay Inspired!
Join other developers and designers who have already signed up for our mailing list.
Terms     Privacy     Licensing       EULA       Sitemap      
© Data & Object Factory, LLC.
Made with    in Austin, Texas