工厂模式和策略模式区别

旧城冷巷雨未停 提交于 2020-01-11 08:29:20

 

先上代码:

定义一个抽象类

//抽象类
abstract class AbsClass
{
    //抽象方法:提供一些列的算法操作
    public abstract void acceptCash(string org);
}
 
//继承自抽象类
class A:AbsClass
{
    //具体方法:提供一些列的算法操作
    public override double acceptCash(string org)
 {
         Console.WriterLine("A类方法");
  }
}
 
//继承自抽象类
class B:AbsClass
{
    //具体方法:提供一些列的算法操作
    public override double acceptCash(string org)
 { 
         Console.WriterLine("B类方法");
  }
}


简单工厂模式:

//现金收取工厂
class CashFactory
{
    //根据条件返回相应的对象
    public static AbsClass createCashAccept(string type)
    {
        AbsClass cs = null;
        switch (type)
        {
            case "A":
                cs = new Al();
                break;
            case "B":
                cs = new B();
                break;
            case "...":
                ........ ....
                break;
        }
        return cs;
    }
}

客户端调用:

//利用简单工厂模式根据下拉选择框,生成相应的对象
AbsClass csuper = CashFactory.createCashAccept("A");

 

策略模式:

前面的类没有任何变化,只是把Factory变成了CaseContext策略类

//策略Context
class CashContext
{
    //声明一个现金收费父类对象
    private AbsClass cs;
 
    //设置策略行为,参数为具体的现金收费子类(正常,打折或返利)
    public CashContext(AbsClass csuper)
    {
        this.cs = csuper;
    }
 
    //得到现金促销计算结果(利用了多态机制,不同的策略行为导致不同的结果)
    public double GetResult(double money)
    {
        return cs.acceptCash(money);
    }
}


客户端调用:

        AbsClass cc = null;
         switch (cbxType.SelectedItem.ToString())
            {
                case "A":
                    cc = new CashContext(new A());
                    break;
                case "B":
                    cc = new CashContext(new B());
                    break;
                case "...":
                    ... ....
                    break;
            }

 

    策略模式和简单工厂模式看起来非常相似,都是通过多态来实现不同子类的选取,这种思想应该是从程序的整体来看得出的。如果从使用这两种模式的角度来看的话,我们会发现在简单工厂模式中我们只需要传递相应的条件就能得到想要的一个对象,然后通过这个对象实现算法的操作。而策略模式,使用时必须首先创建一个想使用的类对象,然后将该对象最为参数传递进去,通过该对象调用不同的算法。在简单工厂模式中实现了通过条件选取一个类去实例化对象,策略模式则将选取相应对象的工作交给模式的使用者,它本身不去做选取工作。

结合上面的代码和下面的释义不难看出,其实两个的差别很微妙,Factory是直接创建具体的对象并用该对象去执行相应的动作,而Context将这个操作给了Context类,没有创建具体的对象,实现的代码的进一步封装,客户端代码并不需要知道具体的实现过程。

 

 

 不同点

简单工厂模式

策略模式

作用

用来创建对象

表示可替换的算法

模式类别

创建型模式

行为型模式

适应范围

适应对象的变化

适应行为的变化

关注点

对象创建

行为选择

 

实例化的过程进行了延后

更多的是依赖倒置之类的东西

 

工厂模式封装对象,实例化对象后调用的时候要知道具体的方法

调用的时候必须先指定实例化具体的类,再调用抽象的方法

 

生成型的模式,在你需要的时候构建具体的实例.

生成型的模式,在你需要的时候构建具体的实例.

从客户端看耦合性

简单工厂是把父类直接摆在客户端

将父类隐藏在类Context里面,这样封装得更好一点。更低

 

 

工厂/策略 实际是同样的实现,针对这种实现的不同特性做出不同的命名,一个强调 统一接口,另一个强调 父类的调用子类的特性

策略模式一般是和工厂模式一起使用的,用工厂来创建算法类。工厂模式是对父类进行重写

 

而策略模式是调用不同类方法。其它他们俩本来就是解决类似问题的,可以说是孪生兄弟:

 

工厂模式:根据你给出的目的来生产不同用途的斧子,例如要砍人,那么工厂生产砍人斧子,要伐木就生产伐木斧子。

即根据你给出一些属性来生产不同行为的一类对象返回给你。

关注对象创建

 

策略模式:用工厂生产的斧子来做对应的事情,例如用砍人的斧子来砍人,用伐木的斧子来伐木。

即根据你给出对应的对象来执行对应的方法。

关注行为的选择

 

两者最根本的区别是,一个是对对象类型的扩展,一个是对行为类型的扩展。

      如果说所有的对象类型有相同的行为,而对象类型有可能增加,就用工厂方法(只生产对象,不关注行为)

      如果说某类(父类)对象类型有很多行为,而且行为有可能增加,使用策略模式(只关注行为的增加,不关注对象类型)

简单来说,如果有一个父类(抽象类),它的子类有很多中,而且可能扩展,用工厂模式

                                                     它的动作方法很多而且可能扩展,用策略模式

 

 如果说两者都有可能增加,就要把两种方式结合起来

拿工厂模式中的运动员举个栗子:

原来运动员有跑和跳两种行为,但是如果加上一个喊的行为,或者说如果哪一天篮球运动员的跑的方式有变化。那就要打开所有的运行员类型,加上一个行为或者修改行为。

那在定义行为的时候就是用策略模式

先定义一个跑的策略

    public interface IRunBehavior
    {
        object run();
    }

然后实现类

public class RunForBasketBall : IRunBehavior
    {
        ...
    }

public class RunForFoottBall : IRunBehavior
    {
        ...
    }

public class RunPingPang : IRunBehavior
    {
        ...
    }


同样在定义两个策略跳和喊

    public interface IJumpBehavior
    {
        object jump();
    }

    public interface IHanBehavior
    {
        object han();
    }

 

然后策略模式里有一个应用场景,这里就是运动员父类

public abstract class player
    {
        protected IRunBehavior runBehavior;
        protected IJumpBehavior jumpBehavior;
        protected IHanBehavior  hanBehavior;

        public string eat()
        {
            return "all plays eat!";
        }

        public object PerformRun()
        {
            return runBehavior.Run();
        }

        public object PerformJump()
        {
            return jumpBehavior.Jump();
        }

        public object PerformHan()
        {
            return hanBehavior.Han();
        }


        public void SetRunBehavior(IRunBehavior qck)
        {
            this.runBehavior = qck;
        }

        public void SetJumpBehavoir(IJumpBehavior jump)
        {
            this.jumpBehavior = jump;
        }

        public void SetHanBehavoir(IHanBehavior han)
        {
            this.hanBehavior = han;
        }

        public abstract object Display();     
    }


然后在实例化运动员时:

 

篮球运动员.java
public class FootBallPlayer implements Player {

        public BasketBallPlay()
        {
             base.SetRunBehavior(new RunForBasketBall());
             base.JumpBehavoir(new JumpForBasketBall());
        base.HanBehavoir(new HanForBasketBall());
        }
      public override object Display()        {            return "我是科比我怕谁!";        }}

 

然后再相应的定义足球运动员等...

然后下面实例化运动员就是工厂模式登场了:

体育协会.java
public interface 体育协会 {
        public 运动员 注册();
}

足球协会.java
public class 足球协会 implements 体育协会 {
        public 运动员 注册(){
                return new 足球运动员();
        }
}

篮球协会.java
public class 篮球协会 implements 体育协会 {
        public 运动员 注册(){
                return new 篮球运动员();
        }
}

俱乐部.java
public class 俱乐部 {
        private 运动员 守门员;
        private 运动员 后卫;
        private 运动员 前锋;

        public void test() {
                体育协会 中国足协 = new 足球协会();
                
                this.前锋 = 中国足协.注册();
                this.后卫 = 中国足协.注册();

                守门员.跑();
                后卫.跳();
        }
}

  所以呢,如果运动员的行为发生变化,通过策略方法可以实现修改

  运动员类型发生变化,通过工厂方法可以修改

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!