zoukankan      html  css  js  c++  java
  • 设计模式-工厂方法模式(FactoryMethod)

    简介:

    简单工厂模式将类的示例化放在工厂对象中。

    工厂方法模式是简单工厂模式的延伸,不同的是其将子类的实例化延迟到子类工厂中实现,本身仅定义一个创建对象的接口。

    工厂方法模式主要由四部分组成:

    1.抽象产品(product) -同简单工厂模式

    是所有具体产品角色的父类,它负责描述所有实例所共有的公共接口,抽象类或者接口

    2.具体产品(Concrete Product) -同简单工厂模式
    即为Product的实现对象,特指某一具体产品,一般有多个这样的类。

    3.工厂角色(Creator) -同简单工厂模式

    工厂基类,可以为接口、抽象类、实体类,声明工厂方法,工厂方法一般为抽象方法,返回Product对象,也可以在工厂方法中提供默认实现,返回一个Default的Product实例对象。

    4.具体工厂角色(ConcreteCreator)

    重写Creator中的工厂方法,返回具体的Product实例。

    具体实例:

    上面简单工厂的例子,已经很好的实现了对交易修改备案的操作。不管后续新增任何交易,稍微改下代码即可轻松实现修改备案记录。

    现在客户提到,要对系统中账户修改、对手修改记录修改备案,PS:以后可能还会有其他对象的修改备案。

    代码实现:

    public abstract class DiffClass
    {
        public abstract void Diff(Object aOldObject, Object aNewObject);
    }
    
    public class AccountDiff : DiffClass
    {
        public override void Diff(Object aOldAccount, Object aNewAccount)
        {
            Console.WriteLine("记录账户修改备案信息");
        }
    }
    
    public class PartyDiff : DiffClass
    {
        public override void Diff(Object aOldParty, Object aNewParty)
        {
            Console.WriteLine("记录交易对手修改备案信息");
        }
    }
    
    interface IFactoryMethod
    {
        DiffClass CreateDiffClass();
    }
    
    public class AccountFactory : IFactoryMethod
    {
        public DiffClass CreateDiffClass()
        {
            return new AccountDiff();
        }
    }
    
    public class PartyFactory : IFactoryMethod
    {
        public DiffClass CreateDiffClass()
        {
            return new PartyDiff();
        }
    }
    
    class FactoryMethodTest
    {
        static void Main(String[] args)
        {
            Account oldAccount = new Account();
            Account newAccount = new Account();
            IFactoryMethod factory1 = new AccountFactory();
            factory1.CreateDiffClass().Diff(oldAccount, newAccount);
    
            Party oldParty = new Party();
            Party newParty = new Party();
            IFactoryMethod factory2 = new PartyFactory();
            factory2.CreateDiffClass().Diff(oldParty, newParty);
    
            Console.ReadLine();
        }
    }
    后续如果用户提到需要记录用户修改备案,不用修改原始代码,新增代码如下即可:
    public class UserDIff : DiffClass
    {
        public override void Diff(object aOldUser, object aNewUser)
        {
            Console.WriteLine("记录用户修改备案信息");
        }
    }
    
    public class UserFactory : IFactoryMethod
    {
        public DiffClass CreateDiffClass()
        {
            return new UserDIff();
        }
    }

    补充分析:

    工厂方法模式的本质:延迟到子类来选择实现

    优点:

    a.工厂方法给子类提供了一个挂钩,使得扩展新的对象更容易。例如上面提到的新增用户修改备案或者后续新增其它对象的修改备案,不需要修改原有任何代码。新增新的工厂方法和新的子类即可。

    b.可以在不知道具体实现的情况下编程

    父类的工厂模式本身一般不实例化具体产品对象,不关心细节,创建具体产品对象的任务延迟到子类中。

    缺点:

    工厂方法中需要创建产品对象,也就是需要选择具体的产品对象并创建他们的实例,具体产品对象和工厂方法耦合。

    跟简单工厂模式的区别:

    简单工厂模式,直接在工厂类中选择实现具体产品实例。

    工厂方法模式,将具体产品的实例放在具体工厂里(工厂角色的子类)。父类工厂角色里面的工厂方法,依赖于抽象而不是具体实现,面向接口编程。

    其它代码:

    简单工厂模式本身是工厂方法模式的一种特殊情况。其实显示中两种模式是可以混和使用的。

    参考代码如:

        #region 简单工厂
        public abstract class DiffClass
        {
            public abstract void Diff(Object aOldObject, Object aNewObject);
        }
    
        public class BondTradeDiff : DiffClass
        {
            public override void Diff(Object aOldTrade, Object aNewTrade)
            {
                Console.WriteLine("记录现券交易备案!");
            }
        }
    
        public class FutureTradeDiff : DiffClass
        {
            public override void Diff(Object aOldTrade, Object aNewTrade)
            {
                Console.WriteLine("记录期货交易备案");
            }
        }
    
        public class FactoryMethod
        {
            public virtual DiffClass CreateDiffClass(object aObject)//参数化工厂方法
            {
                if (aObject is BondTrade)
                    return new BondTradeDiff();
                else if (aObject is FutureTrade)
                    return new FutureTradeDiff();
                else
                    return null;
            }
        }
        #endregion
    
        #region 工厂方法
        public class AccountDiff : DiffClass
        {
            public override void Diff(Object aOldAccount, Object aNewAccount)
            {
                Console.WriteLine("记录账户修改备案信息");
            }
        }
    
        public class AccountFactory : FactoryMethod
        {
            public override DiffClass CreateDiffClass(object aObject)
            {
                return new AccountDiff();
            }
        }
        #endregion
    
        #region 测试代码
        public class SimpleFactoryAndFactoryMethod
        {
            static void Main(String[] args)
            {
                FactoryMethod factory = new FactoryMethod();
    
                //测试现券交易修改备案
                Trade oldBondTrade = new BondTrade();
                Trade newBondTrade = new BondTrade();
                factory.CreateDiffClass(newBondTrade).Diff(oldBondTrade, newBondTrade);
    
                //测试期货交易修改备案
                Trade oldFutureTrade = new FutureTrade();
                Trade newFutureTrade = new FutureTrade();
                factory.CreateDiffClass(newFutureTrade).Diff(oldFutureTrade, newFutureTrade);
    
                //测试账户修改备案
                Account oldAccount = new Account();
                Account newAccount = new Account();
                FactoryMethod factory1 = new AccountFactory();
                factory1.CreateDiffClass(newAccount).Diff(oldAccount, newAccount);
    
                Console.ReadLine();
            }
        }
        #endregion
    }
  • 相关阅读:
    Linux下Tomcat重新启动
    Navicat远程连接不上mysql解决方案
    Tomcat 启动时 SecureRandom 非常慢解决办法,亲测有效
    SpringMVC Controller接收参数总结
    maven source 1.3 中不支持泛型 解决办法
    css background-image 自适应宽高——转载
    IntellIJ IDEA 配置 Maven 以及 修改 默认 Repository
    使用Idea从github上获取项目
    取消IDEA默认打开最近的项目(设置打开选择创建页面)
    GameFreamWork框架----事件系统的应用
  • 原文地址:https://www.cnblogs.com/liaozh/p/3383174.html
Copyright © 2011-2022 走看看