none
Gof Factory Method Design Pattern RRS feed

  • Question

  • Hi Friends,

    I am confused, while learning the Factory Method Design Pattern, it says that objects are not created until they are used or until runtime. I was not aware that when you use the new key word  objects are created during compile time. Could I please get some clarity concerning when objects are created. Also I was looking at a video that stated that New is Glue and i wasnt sure what they meant by this. Thanks !


    • Edited by Ronald Rex Thursday, January 10, 2019 2:14 AM
    Thursday, January 10, 2019 2:13 AM

Answers

  • I was not aware that when you use the new key word  objects are created during compile time.

    No, the New keyword means that a class  is instanced into an object at runtime that has memory allocated for it. An object lives in memory.

    It follows OOP 101 principles of class vs object vs instance Java and .NET are OOP lanauage platforms.

    https://alfredjava.wordpress.com/2008/07/08/class-vs-object-vs-instance/

    The factory pattern generates objects like a car factory generates a car. A Ford factory creator creates an EcoSport. The Ford creator creates an Escape. Both are SUVs, but they have different characteristics. The  factory pattern for Pie is going to create an instance of the Apple pie object as opposed to a  Cherry  pie object. Both are Pie objects and have some of the same characteristics, but the objects are different. However, they are generated from the Pie factory object.     

    https://www.dofactory.com/net/factory-method-design-pattern

    That's my understanding of the factory pattern.


    • Edited by DA924x Thursday, January 10, 2019 4:01 AM
    • Marked as answer by Ronald Rex Thursday, January 10, 2019 6:04 PM
    Thursday, January 10, 2019 3:57 AM

  • Also I was looking at a video that stated that New is Glue and i wasnt sure what they meant by this. 

    That's an odd way to put it, but I can guess what they're trying to say.

    Here's the mental model that I use.  Objects live in a big, nameless, anonymous space.  When you do "new Point(3,4);" for example, that creates an object.  That object does not have a name.  In fact, it cannot have a name.  It's just an object floating in object space.

    When I do "Point one = new Point(3,4);", that creates a nameless object in anonymous space, but it "binds" the variable named "one" to that object.  I guess you could consider that binding to be a form of glue.

    It's important to remember that the Point object has NO IDEA that there is a name called "one" that is bound to it.  It knows there is one reference, but not what the name is.  From the object, you can't get the name "one".  Consider if I did this:

    Point one = new Point(3,4);
    Point two = one;

    Now I have two names that are bound to the SAME nameless object.  Again, the object doesn't know where it is bound; it only knows that there are two references to it.  If you could change the Point object, it would change both "one" and "two".  However, like many objects, a Point cannot be changed.  When you do "Point.Add", for example, it return a NEW Point with the new coordinates.  If I do this:

        Point two = Point.Add(one, new Size(10,10));

    now "two" is bound to a new nameless object.  "one" is still bound to the (3,4) point.

    If I now do:

        Point one = new Point(9,10);

    then that original Point(3,4) no longer has any names that refer to it.  Its reference count is 0.  There is no way for anyone to use that object ever again.  It will sit all alone in anonymous object space, unused, until the garbage collector runs.  The garbage collector scans the nameless anonymous object space looking for objects that have no references, and deletes them.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    • Marked as answer by Ronald Rex Saturday, January 12, 2019 3:23 AM
    Thursday, January 10, 2019 11:58 PM
  • I think when they say new is glue that has to do with tight coupling?
    • Marked as answer by Ronald Rex Friday, January 18, 2019 8:33 PM
    Saturday, January 12, 2019 3:26 AM
  • I think when they say new is glue that has to do with tight coupling?

    https://ardalis.com/new-is-glue

    <copied>

    Decoupling Services from Providers
    New is Glue. It binds your code to a particular collaborator.
    If there is any chance you’ll need to be flexible about which implementation your code will need, it’s worth introducing an interface to keep your code loosely coupled.
    It doesn’t matter what the service is you need – you can always replace it with an interface even if your class is the only one that uses it.

    <end>

    https://msdn.microsoft.com/en-us/magazine/mt703433.aspx?f=255&MSPPError=-2147217396

    <copied>

    When looking at code to evaluate its coupling, remember the phrase “new is glue.”
    That is, anywhere you see the “new” keyword instantiating a class, realize you’re gluing your implementation to that specific implementation code.
    The Dependency Inversion Principle (bit.ly/DI-Principle) states: “Abstractions should not depend on details; details should depend on abstractions.” In this example, the details of how the controller pulls together the data to pass to the
    view depend on the details of how to get that data—namely, EF.

    <end>

    https://www.c-sharpcorner.com/blogs/understanding-interfaces-via-loose-coupling-and-tight-coupling

    https://dzone.com/articles/absolute-beginners-tutorial

    In the code example, I am using inversion of control and dependency injection. with the Unity IoC and using a layered style as opposed to n-tier.

    https://en.wikipedia.org/wiki/Separation_of_concerns

    https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10)

    The only time I am using the New keyword is in the DAO in the DAL that is using Entity Framework and MS SQL Server, becuase there,  I want the low-level database technology highly coupled to the DAO, which is being used with the WCF Web service. You don't see WCF and DAO being used in DAL, although the DAO is being DI into the WCF service implementation. 

    https://en.wikipedia.org/wiki/Data_access_object

    https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm

    using System.Data;
    using System.Data.Common;
    using System.Web;
    using System.Web.Mvc;
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.Owin.Security;
    using Microsoft.Practices.Unity;
    using Unity.Mvc5;
    using ServiceLayer;
    using WebAPI.Controllers;
    using MVC.Models;
    
    
    namespace MVC.App_Start
    {
        public static class IocExtensions
        {
            public static void BindInRequestScope<T1, T2>(this IUnityContainer container) where T2 : T1
            {
                container.RegisterType<T1, T2>(new HierarchicalLifetimeManager());
            }
    
            public static void BindInSingletonScope<T1, T2>(this IUnityContainer container) where T2 : T1
            {
                container.RegisterType<T1, T2>(new ContainerControlledLifetimeManager());
            }
        }
    
        public class UnityMVC5
        {
            public static void Start()
            {
                var container = BuildUnityContainer();
                DependencyResolver.SetResolver(new UnityDependencyResolver(container));
            }
    
            private static IUnityContainer BuildUnityContainer()
            {
                var container = new UnityContainer();
    
                //Models
                container.BindInRequestScope<IStudentModels, StudentModels>();
                container.BindInRequestScope<IEnrollmentModels, EnrollmentModels>();
    
                //SeviceLayer
                container.BindInRequestScope<IServiceA, ServiceA>();
    
                //WebAPI controllers
                container.BindInRequestScope<IStudentControllerAPI, StudentController>();
                container.BindInRequestScope<IEnrollmentControllerAPI, EnrollmentController>();
    
                //asp.net idenity
    
                container.RegisterType<ApplicationDbContext>();
                container.RegisterType<ApplicationSignInManager>();
                container.RegisterType<ApplicationUserManager>();
                container.RegisterType<IAuthenticationManager>(
                                 new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
                container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
                            new InjectionConstructor(typeof(ApplicationDbContext)));
    
                return container;
            }
        }
    }

    using System.Web.Mvc;
    using MVC.Models;
    
    namespace MVC.Controllers
    {
        [Authorize]
        public class StudentsController : BaseController  
        {
            private IStudentModels studmods;
            public StudentsController(IStudentModels studentModels)
            {
                studmods = studentModels;
            }
    
            // GET: Students
    
            [AllowAnonymous]
            public ActionResult Index()
            {
                return View(studmods.GetStudents());
            }
    
            //[AllowAnonymous]
            public ActionResult Details(int id = 0)
            {
                return id == 0 ? null : View(studmods.GetStudentById(id));
            }
            public ActionResult Create()
            {
                return View(studmods.Create());
            }
    
            [HttpPost]
            public ActionResult Create(StudentViewModels.Student student)
            {
                if (ModelState.IsValid)
                {
                    studmods.Create(student);
                    return RedirectToAction("Index");
                }
    
                return View(student);
            }
    
            public ActionResult Edit(int id = 0)
            {
                return id == 0 ? null : View(studmods.Edit(id));
            }
    
            [HttpPost]
            public ActionResult Edit(StudentViewModels.Student student)
            {
                if (ModelState.IsValid)
                {
                    studmods.Edit(student);
                    return RedirectToAction("Index");
                }
    
                return View(student);
            }
    
            public ActionResult Delete(int id = 0 )
            {
                if (id > 0) studmods.Delete(id);
                
                return RedirectToAction("Index");
             }
        }
    }

    using System.Collections.Generic;
    
    namespace MVC.Models
    {
        public interface IStudentModels
        {
            StudentViewModels GetStudents();
            StudentViewModels.Student GetStudentById(int id);
            StudentViewModels.Student Create();
            void Create(StudentViewModels.Student student);
            StudentViewModels.Student Edit(int id);
            void Edit(StudentViewModels.Student student);
            void Delete(int id);
        }
    }
    
    ==========================================================
    
    using System.Collections.Generic;
    using Entities;
    using WebAPI.Controllers;
    
    namespace MVC.Models
    {
        public class StudentModels : IStudentModels
        {
            private IStudentControllerAPI studapi;
            public StudentModels(IStudentControllerAPI studentControllerApi)
            {
                studapi = studentControllerApi;
            }
    
            public StudentViewModels GetStudents()
            {
                var dtos = studapi.GetStudents();
               
                var vm = new StudentViewModels {Students = new List<StudentViewModels.Student>()};
    
                foreach (var dto in dtos)
                {
                    var student = new StudentViewModels.Student
                    {
                        StudentID = dto.StudentID,
                        LastName = dto.LastName,
                        FirstName = dto.FirstName,
                        EnrollmentDate = dto.EnrollmentDate
                    };
    
                    vm.Students.Add(student);
                }
    
                return vm;
            }
    
            public StudentViewModels.Student GetStudentById(int id)
            {
                var dto = studapi.GetStudentById(id);
    
                var student = new StudentViewModels.Student
                {
                    StudentID = dto.StudentID,
                    FirstName = dto.FirstName,
                    LastName = dto.LastName,
                    EnrollmentDate = dto.EnrollmentDate,
                    EnrollsandCourses = new List<EnrollandCourseViewModel.EnrollandCourse>()
                };
    
                foreach (var dtoec in dto.EnrollsandCourses)
                {
                    var ec = new EnrollandCourseViewModel.EnrollandCourse
                    {
                        Credits = dtoec.Credits,
                        Grade = dtoec.Grade,
                        Title = dtoec.Title
                    };
    
                    student.EnrollsandCourses.Add(ec);
                }
    
                return student;
            }
    
            public StudentViewModels.Student Create()
            {
                var student = new StudentViewModels.Student();
    
                return student;
            }
    
            public void Create(StudentViewModels.Student student)
            {
                var dto = new DTOStudent
                {
                    StudentID = student.StudentID,
                    FirstName = student.FirstName,
                    LastName = student.LastName,
                    EnrollmentDate = student.EnrollmentDate
                };
    
                studapi.CreateStudent(dto);
            }
    
            public StudentViewModels.Student Edit(int id)
            {
                var dto = studapi.GetStudentById(id);
    
                var student = new StudentViewModels.Student
                {
                    StudentID = dto.StudentID,
                    FirstName = dto.FirstName,
                    LastName = dto.LastName,
                    EnrollmentDate = dto.EnrollmentDate
                };
    
                return student;
            }
    
            public void Edit(StudentViewModels.Student student)
            {
                var dto = new DTOStudent
                {
                    StudentID = student.StudentID,
                    FirstName = student.FirstName,
                    LastName = student.LastName,
                    EnrollmentDate = student.EnrollmentDate
                };
    
                studapi.UpdateStudent(dto);
            }
    
            public void Delete(int id)
            {
                studapi.DeleteStudent(id);
            }
        }
    }

    • Marked as answer by Ronald Rex Sunday, January 13, 2019 2:49 AM
    Saturday, January 12, 2019 4:56 AM

All replies

  • I was not aware that when you use the new key word  objects are created during compile time.

    No, the New keyword means that a class  is instanced into an object at runtime that has memory allocated for it. An object lives in memory.

    It follows OOP 101 principles of class vs object vs instance Java and .NET are OOP lanauage platforms.

    https://alfredjava.wordpress.com/2008/07/08/class-vs-object-vs-instance/

    The factory pattern generates objects like a car factory generates a car. A Ford factory creator creates an EcoSport. The Ford creator creates an Escape. Both are SUVs, but they have different characteristics. The  factory pattern for Pie is going to create an instance of the Apple pie object as opposed to a  Cherry  pie object. Both are Pie objects and have some of the same characteristics, but the objects are different. However, they are generated from the Pie factory object.     

    https://www.dofactory.com/net/factory-method-design-pattern

    That's my understanding of the factory pattern.


    • Edited by DA924x Thursday, January 10, 2019 4:01 AM
    • Marked as answer by Ronald Rex Thursday, January 10, 2019 6:04 PM
    Thursday, January 10, 2019 3:57 AM
  • Its called a factory "METHOD" design pattern. And you also have the abstract factory design pattern. You might want to understand the different nuances of these designs so you will know when to use which. Thanks for your help. 
    Thursday, January 10, 2019 6:04 PM

  • Also I was looking at a video that stated that New is Glue and i wasnt sure what they meant by this. 

    That's an odd way to put it, but I can guess what they're trying to say.

    Here's the mental model that I use.  Objects live in a big, nameless, anonymous space.  When you do "new Point(3,4);" for example, that creates an object.  That object does not have a name.  In fact, it cannot have a name.  It's just an object floating in object space.

    When I do "Point one = new Point(3,4);", that creates a nameless object in anonymous space, but it "binds" the variable named "one" to that object.  I guess you could consider that binding to be a form of glue.

    It's important to remember that the Point object has NO IDEA that there is a name called "one" that is bound to it.  It knows there is one reference, but not what the name is.  From the object, you can't get the name "one".  Consider if I did this:

    Point one = new Point(3,4);
    Point two = one;

    Now I have two names that are bound to the SAME nameless object.  Again, the object doesn't know where it is bound; it only knows that there are two references to it.  If you could change the Point object, it would change both "one" and "two".  However, like many objects, a Point cannot be changed.  When you do "Point.Add", for example, it return a NEW Point with the new coordinates.  If I do this:

        Point two = Point.Add(one, new Size(10,10));

    now "two" is bound to a new nameless object.  "one" is still bound to the (3,4) point.

    If I now do:

        Point one = new Point(9,10);

    then that original Point(3,4) no longer has any names that refer to it.  Its reference count is 0.  There is no way for anyone to use that object ever again.  It will sit all alone in anonymous object space, unused, until the garbage collector runs.  The garbage collector scans the nameless anonymous object space looking for objects that have no references, and deletes them.


    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    • Marked as answer by Ronald Rex Saturday, January 12, 2019 3:23 AM
    Thursday, January 10, 2019 11:58 PM
  • I think when they say new is glue that has to do with tight coupling?
    • Marked as answer by Ronald Rex Friday, January 18, 2019 8:33 PM
    Saturday, January 12, 2019 3:26 AM
  • I think when they say new is glue that has to do with tight coupling?

    https://ardalis.com/new-is-glue

    <copied>

    Decoupling Services from Providers
    New is Glue. It binds your code to a particular collaborator.
    If there is any chance you’ll need to be flexible about which implementation your code will need, it’s worth introducing an interface to keep your code loosely coupled.
    It doesn’t matter what the service is you need – you can always replace it with an interface even if your class is the only one that uses it.

    <end>

    https://msdn.microsoft.com/en-us/magazine/mt703433.aspx?f=255&MSPPError=-2147217396

    <copied>

    When looking at code to evaluate its coupling, remember the phrase “new is glue.”
    That is, anywhere you see the “new” keyword instantiating a class, realize you’re gluing your implementation to that specific implementation code.
    The Dependency Inversion Principle (bit.ly/DI-Principle) states: “Abstractions should not depend on details; details should depend on abstractions.” In this example, the details of how the controller pulls together the data to pass to the
    view depend on the details of how to get that data—namely, EF.

    <end>

    https://www.c-sharpcorner.com/blogs/understanding-interfaces-via-loose-coupling-and-tight-coupling

    https://dzone.com/articles/absolute-beginners-tutorial

    In the code example, I am using inversion of control and dependency injection. with the Unity IoC and using a layered style as opposed to n-tier.

    https://en.wikipedia.org/wiki/Separation_of_concerns

    https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10)

    The only time I am using the New keyword is in the DAO in the DAL that is using Entity Framework and MS SQL Server, becuase there,  I want the low-level database technology highly coupled to the DAO, which is being used with the WCF Web service. You don't see WCF and DAO being used in DAL, although the DAO is being DI into the WCF service implementation. 

    https://en.wikipedia.org/wiki/Data_access_object

    https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm

    using System.Data;
    using System.Data.Common;
    using System.Web;
    using System.Web.Mvc;
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.Owin.Security;
    using Microsoft.Practices.Unity;
    using Unity.Mvc5;
    using ServiceLayer;
    using WebAPI.Controllers;
    using MVC.Models;
    
    
    namespace MVC.App_Start
    {
        public static class IocExtensions
        {
            public static void BindInRequestScope<T1, T2>(this IUnityContainer container) where T2 : T1
            {
                container.RegisterType<T1, T2>(new HierarchicalLifetimeManager());
            }
    
            public static void BindInSingletonScope<T1, T2>(this IUnityContainer container) where T2 : T1
            {
                container.RegisterType<T1, T2>(new ContainerControlledLifetimeManager());
            }
        }
    
        public class UnityMVC5
        {
            public static void Start()
            {
                var container = BuildUnityContainer();
                DependencyResolver.SetResolver(new UnityDependencyResolver(container));
            }
    
            private static IUnityContainer BuildUnityContainer()
            {
                var container = new UnityContainer();
    
                //Models
                container.BindInRequestScope<IStudentModels, StudentModels>();
                container.BindInRequestScope<IEnrollmentModels, EnrollmentModels>();
    
                //SeviceLayer
                container.BindInRequestScope<IServiceA, ServiceA>();
    
                //WebAPI controllers
                container.BindInRequestScope<IStudentControllerAPI, StudentController>();
                container.BindInRequestScope<IEnrollmentControllerAPI, EnrollmentController>();
    
                //asp.net idenity
    
                container.RegisterType<ApplicationDbContext>();
                container.RegisterType<ApplicationSignInManager>();
                container.RegisterType<ApplicationUserManager>();
                container.RegisterType<IAuthenticationManager>(
                                 new InjectionFactory(c => HttpContext.Current.GetOwinContext().Authentication));
                container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(
                            new InjectionConstructor(typeof(ApplicationDbContext)));
    
                return container;
            }
        }
    }

    using System.Web.Mvc;
    using MVC.Models;
    
    namespace MVC.Controllers
    {
        [Authorize]
        public class StudentsController : BaseController  
        {
            private IStudentModels studmods;
            public StudentsController(IStudentModels studentModels)
            {
                studmods = studentModels;
            }
    
            // GET: Students
    
            [AllowAnonymous]
            public ActionResult Index()
            {
                return View(studmods.GetStudents());
            }
    
            //[AllowAnonymous]
            public ActionResult Details(int id = 0)
            {
                return id == 0 ? null : View(studmods.GetStudentById(id));
            }
            public ActionResult Create()
            {
                return View(studmods.Create());
            }
    
            [HttpPost]
            public ActionResult Create(StudentViewModels.Student student)
            {
                if (ModelState.IsValid)
                {
                    studmods.Create(student);
                    return RedirectToAction("Index");
                }
    
                return View(student);
            }
    
            public ActionResult Edit(int id = 0)
            {
                return id == 0 ? null : View(studmods.Edit(id));
            }
    
            [HttpPost]
            public ActionResult Edit(StudentViewModels.Student student)
            {
                if (ModelState.IsValid)
                {
                    studmods.Edit(student);
                    return RedirectToAction("Index");
                }
    
                return View(student);
            }
    
            public ActionResult Delete(int id = 0 )
            {
                if (id > 0) studmods.Delete(id);
                
                return RedirectToAction("Index");
             }
        }
    }

    using System.Collections.Generic;
    
    namespace MVC.Models
    {
        public interface IStudentModels
        {
            StudentViewModels GetStudents();
            StudentViewModels.Student GetStudentById(int id);
            StudentViewModels.Student Create();
            void Create(StudentViewModels.Student student);
            StudentViewModels.Student Edit(int id);
            void Edit(StudentViewModels.Student student);
            void Delete(int id);
        }
    }
    
    ==========================================================
    
    using System.Collections.Generic;
    using Entities;
    using WebAPI.Controllers;
    
    namespace MVC.Models
    {
        public class StudentModels : IStudentModels
        {
            private IStudentControllerAPI studapi;
            public StudentModels(IStudentControllerAPI studentControllerApi)
            {
                studapi = studentControllerApi;
            }
    
            public StudentViewModels GetStudents()
            {
                var dtos = studapi.GetStudents();
               
                var vm = new StudentViewModels {Students = new List<StudentViewModels.Student>()};
    
                foreach (var dto in dtos)
                {
                    var student = new StudentViewModels.Student
                    {
                        StudentID = dto.StudentID,
                        LastName = dto.LastName,
                        FirstName = dto.FirstName,
                        EnrollmentDate = dto.EnrollmentDate
                    };
    
                    vm.Students.Add(student);
                }
    
                return vm;
            }
    
            public StudentViewModels.Student GetStudentById(int id)
            {
                var dto = studapi.GetStudentById(id);
    
                var student = new StudentViewModels.Student
                {
                    StudentID = dto.StudentID,
                    FirstName = dto.FirstName,
                    LastName = dto.LastName,
                    EnrollmentDate = dto.EnrollmentDate,
                    EnrollsandCourses = new List<EnrollandCourseViewModel.EnrollandCourse>()
                };
    
                foreach (var dtoec in dto.EnrollsandCourses)
                {
                    var ec = new EnrollandCourseViewModel.EnrollandCourse
                    {
                        Credits = dtoec.Credits,
                        Grade = dtoec.Grade,
                        Title = dtoec.Title
                    };
    
                    student.EnrollsandCourses.Add(ec);
                }
    
                return student;
            }
    
            public StudentViewModels.Student Create()
            {
                var student = new StudentViewModels.Student();
    
                return student;
            }
    
            public void Create(StudentViewModels.Student student)
            {
                var dto = new DTOStudent
                {
                    StudentID = student.StudentID,
                    FirstName = student.FirstName,
                    LastName = student.LastName,
                    EnrollmentDate = student.EnrollmentDate
                };
    
                studapi.CreateStudent(dto);
            }
    
            public StudentViewModels.Student Edit(int id)
            {
                var dto = studapi.GetStudentById(id);
    
                var student = new StudentViewModels.Student
                {
                    StudentID = dto.StudentID,
                    FirstName = dto.FirstName,
                    LastName = dto.LastName,
                    EnrollmentDate = dto.EnrollmentDate
                };
    
                return student;
            }
    
            public void Edit(StudentViewModels.Student student)
            {
                var dto = new DTOStudent
                {
                    StudentID = student.StudentID,
                    FirstName = student.FirstName,
                    LastName = student.LastName,
                    EnrollmentDate = student.EnrollmentDate
                };
    
                studapi.UpdateStudent(dto);
            }
    
            public void Delete(int id)
            {
                studapi.DeleteStudent(id);
            }
        }
    }

    • Marked as answer by Ronald Rex Sunday, January 13, 2019 2:49 AM
    Saturday, January 12, 2019 4:56 AM