zoukankan      html  css  js  c++  java
  • 设计模式之建造者模式和工厂模式 使用小结

    Builder(In Test)建造者模式是什么

    Normal Pattern

    public class Employee
    {
        public Employee(int id, string firstname, string lastname, DateTime birthdate, string street)
        {
            this.ID = id;
            this.FirstName = firstname;
            this.LastName = lastname;
            this.BirthDate = birthdate;
            this.Street = street;
        }
    
        public int ID { get; private set; }
    
        public string FirstName { get; private set; }
    
        public string LastName { get; private set; }
    
        public DateTime BirthDate { get; private set; }
    
        public string Street { get; private set; }
    
        public string getFullName()
        {
            return this.FirstName + " " + this.LastName;
        }
    
        public int getAge()
        {
            DateTime today = DateTime.Today;
            int age = today.Year - BirthDate.Year;
            if (BirthDate > today.AddYears(-age)) age--;
            return age;
        }
    }
    
    
    • All values are passed in in the constructor
    • All properties are read-only (at least from outside of this class)
    • Methods provide access to calculated values (getFullName and getAge)

    The Builder Pattern & The Factory Pattern

    工厂方法模式注重的是整体对象的创建方法,而建造者模式注重的是部件构建的过程,旨在通过一步一步地精确构造创建出一个复杂的对象。

    工厂模式关心整体,建造者模式关心细节。

    我们举个简单例子来说明两者的差异,如要制造一个超人,如果使用工厂方法模式,直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人;

    而如果使用建造者模式,则需要组装手、头、脚、躯干等部分,然后再把内裤外穿,于是一个超人就诞生了。参考

    更加的Flexible and expressive

    The Builder Pattern 建造者模式

    应用案例:麦当劳套餐基本上都是以一个汉堡和一杯饮料组成套餐。

    public class EmployeeBuilder
    {
        private int id = 1;
        private string firstname = "first";
        private string lastname = "last";
        private DateTime birthdate = DateTime.Today;
        private string street = "street";
    
        public Employee Build()
        {
            return new Employee(id, firstname, lastname, birthdate, street);
        }
    
        public EmployeeBuilder WithFirstName(string firstname)
        {
            this.firstname = firstname;
            return this;
        }
    
        public EmployeeBuilder WithLastName(string lastname)
        {
            this.lastname = lastname;
            return this;
        }
    
        public EmployeeBuilder WithBirthDate(DateTime birthdate)
        {
            this.birthdate = birthdate;
            return this;
        }
    
        public EmployeeBuilder WithStreet(string street)
        {
            this.street = street;
            return this;
        }
    
        public static implicit operator Employee(EmployeeBuilder instance)
        {
            return instance.Build();
        }
    }
    

    The resulting unit tests

    public class EmployeeTest
    {
    
        [Test]
        public void GetFullNameReturnsCombination()
        {
            // Arrange
            Employee emp = new EmployeeBuilder().WithFirstName("Kenneth")
                                                .WithLastName("Truyers");
    
            // Act
            string fullname = emp.getFullName();
    
            // Assert
            Assert.That(fullname, Is.EqualTo("Kenneth Truyers"));
        }
    
        [Test]
        public void GetAgeReturnsCorrectValue()
        {
            // Arrange
            Employee emp = new EmployeeBuilder().WithBirthDate(new DateTime(1983, 1,1));
    
            // Act
            int age = emp.getAge();
    
            // Assert
            Assert.That(age, Is.EqualTo(DateTime.Today.Year - 1983));
        }
    }
    

    工厂模式

    定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

    在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

    应用案例:如果需要一个汽车,只需要去车场提车就好了,不用知道车子是怎么造的。

    优点:

    1. 一个调用者想创建一个对象,只要知道其名称就可以了。

    2. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。

    3. 屏蔽产品的具体实现,调用者只关心产品的接口。

    public class ProductFactory {
        public static Product produce(String productName) throws Exception {
            switch (productName) {
                case "tv":
                    return new Tv();
                case "car":
                    return new Car();
                default:
                    throw new Exception("没有该产品");
            }
        }
    }
    
    
    

    测试方法:

    try {
        ProductFactory.produce("car");
    } catch (Exception e) {
        e.printStackTrace();
    }
    

    其他参考

    参考

    参考

    参考


    想要看到更多玮哥的学习笔记、考试复习资料、面试准备资料?想要看到IBM工作时期的技术积累和国外初创公司的经验总结?

    敬请关注:

    玮哥的博客 —— CSDN的传送门

    玮哥的博客 —— 简书的传送门

    玮哥的博客 —— 博客园的传送门

  • 相关阅读:
    Win7停止更新升Win10教程
    linux 进程管理
    linux vi/Vim编辑器
    linux 文件管理
    linux 目录管理
    [开发笔记]-C#判断文件类型
    [开发笔记]-C#获取pdf文档的页数
    [转载]每周问问你的团队这10个问题
    [转载]番茄时间管理法(Pomodoro Technique):一个番茄是如何让你工作更有效率的
    [开发笔记]-Linq to xml学习笔记
  • 原文地址:https://www.cnblogs.com/vigorz/p/10501934.html
Copyright © 2011-2022 走看看