GVKun编程网logo

通过商场促销来看策略模式+vb.net实现(了解各大商场的促销方式有哪些)

16

在这里,我们将给大家分享关于通过商场促销来看策略模式+vb.net实现的知识,让您更了解了解各大商场的促销方式有哪些的本质,同时也会涉及到如何更有效地.Net行为型设计模式之策略模式(Stragety

在这里,我们将给大家分享关于通过商场促销来看策略模式+vb.net实现的知识,让您更了解了解各大商场的促销方式有哪些的本质,同时也会涉及到如何更有效地.Net行为型设计模式之策略模式(Stragety)、0036-商场促销、C#实现策略模式、golang的框架如何通过策略模式实现代码复用?的内容。

本文目录一览:

通过商场促销来看策略模式+vb.net实现(了解各大商场的促销方式有哪些)

通过商场促销来看策略模式+vb.net实现(了解各大商场的促销方式有哪些)

商场经常在节日期间做出不同的促销计划,因此商场的计费机制要不停地变动,因此在设计时应该考虑使用策略模式

策略模式(Strategy),策略模式定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化,不会影响到使用算法的客户。

通过UML图来说事:

其中CashContext算是一个简单工厂吧。现在有些理解简单工厂了,其实并不是一个设计模式,只是多态的使用而已(个人理解,欢迎指正)。

下面看看用vb.net如何实现:(实现的和《大话》上写的不太一样,我觉得这样写更方便一些)

其实仔细看这个模式会发现其中只是运用了面向对象中的两个机制:

一、多态

二、封装。

只不过这是将多态和封装组合起来使用,就像是搭积木一样。

.Net行为型设计模式之策略模式(Stragety)

.Net行为型设计模式之策略模式(Stragety)

一、动机(Motivate)

在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

二、意图(Intent)

定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用它的客户而变化。                                 ——《设计模式》GoF

三、结构图(Structure)

四、模式的组成

可以看出,在策略模式的结构图有以下角色:
(1)、环境角色(Context):持有一个Strategy类的引用。
需要使用ConcreteStrategy提供的算法。
内部维护一个Strategy的实例。
负责动态设置运行时Strategy具体的实现算法。
负责跟Strategy之间的交互和数据传递
(2)、抽象策略角色(Strategy):定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
(3)、具体策略角色(ConcreteStrategy):实现了Strategy定义的接口,提供具体的算法实现。

五、策略模式的代码实现

在现实生活中,策略模式的例子也是很多的,例如:一个公司会有很多工作种类,每个工作种类负责的工作不同,自然每个工种的工资计算方法也会有千差万别,我们今天就以工资的计算为例来说明策略模式的使用,我们直接上代码,但是实际编码中切记别这样,我们要通过迭代的方式使用模式。实现代码如下:

public static void Main(String[] args)
{
    //普通员工的工资
    SalaryContext context = new SalaryContext(new NormalPeopleSalary());
    context.GetSalary(3000);

    //CEO的工资
    context.ISalaryStrategy = new CEOSalary();
    context.GetSalary(6000);

    Console.Read();
}
//环境角色---相当于Context类型
public sealed class SalaryContext
{
    private ISalaryStrategy _strategy;

    public SalaryContext(ISalaryStrategy strategy)
    {
        this._strategy = strategy;
    }

    public ISalaryStrategy ISalaryStrategy
    {
        get { return _strategy; }
        set { _strategy = value; }
    }

    public void GetSalary(double income)
    {
        _strategy.CalculateSalary(income);
    }
}

//抽象策略角色---相当于Strategy类型
public interface ISalaryStrategy
{
    //工资计算
    void CalculateSalary(double income);
}

//程序员的工资--相当于具体策略角色ConcreteStrategyA
public sealed class ProgrammerSalary : ISalaryStrategy
{
    public void CalculateSalary(double income)
    {
        Console.WriteLine("我的工资是:基本工资(" + income + ")底薪(" + 8000 + ")+加班费+项目奖金(10%)");
    }
}

//普通员工的工资---相当于具体策略角色ConcreteStrategyB
public sealed class NormalPeopleSalary : ISalaryStrategy
{
    public void CalculateSalary(double income)
    {
        Console.WriteLine("我的工资是:基本工资(" + income + ")底薪(3000)+加班费");
    }
}

//CEO的工资---相当于具体策略角色ConcreteStrategyC
public sealed class CEOSalary : ISalaryStrategy
{
    public void CalculateSalary(double income)
    {
        Console.WriteLine("我的工资是:基本工资(" + income + ")底薪(20000)+项目奖金(20%)+公司股票");
    }
}

六、策略模式的实现要点:

Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换,所谓封装算法,支持算法的变化。Strategy模式提供了用条件判断语句以外的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。
与State类似,如果Strategy对象没有实例变量,那么各个上下文可以共享一个Strategy对象,从而节省对象开销。Strategy模式适用的是算法结构中整个算法的改变,而不是算法中某个部分的改变。

  • Template Method方法:执行算法的步骤协议是本身放在抽象类里面的,允许一个通用的算法操作多个可能实现
  • Strategy模式:执行算法的协议是在具体类,每个具体实现有不同通用算法来做。

1、策略模式的主要优点有:

1】、策略类之间可以自由切换。由于策略类都实现同一个接口,所以使它们之间可以自由切换。
2】、易于扩展。增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码。
3】、避免使用多重条件选择语句,充分体现面向对象设计思想。

2、策略模式的主要缺点有:

1】、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这点可以考虑使用IOC容器和依赖注入的方式来解决,关于IOC容器和依赖注入(Dependency Inject)的文章可以参考:IoC 容器和Dependency Injection 模式。
2】、策略模式会造成很多的策略类。

3、在下面的情况下可以考虑使用策略模式:

1】、一个系统需要动态地在几种算法中选择一种的情况下。那么这些算法可以包装到一个个具体的算法类里面,并为这些具体的算法类提供一个统一的接口。
2】、如果一个对象有很多的行为,如果不使用合适的模式,这些行为就只好使用多重的if-else语句来实现,此时,可以使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句,并体现面向对象涉及的概念。

七、.NET 策略模式的实现

在.NET Framework中也不乏策略模式的应用例子。例如,在.NET中,为集合类型ArrayList和List<T>提供的排序功能,其中实现就利用了策略模式,定义了IComparer接口来对比较算法进行封装,实现IComparer接口的类可以是顺序,或逆序地比较两个对象的大小,具体.NET中的实现可以使用反编译工具查看List<T>.Sort(IComparer<T>)的实现。其中List<T>就是承担着环境角色,而IComparer<T>接口承担着抽象策略角色,具体的策略角色就是实现了IComparer<T>接口的类,List<T>类本身实现了存在实现了该接口的类,我们可以自定义继承与该接口的具体策略类。

到此这篇关于.Net行为型设计模式之策略模式(Stragety)的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:
  • .Net行为型设计模式之备忘录模式(Memento)
  • .Net行为型设计模式之访问者模式(Visitor)
  • .Net行为型设计模式之职责链模式(Chain of Responsibility)
  • .Net行为型设计模式之状态模式(State)
  • .Net行为型设计模式之中介者模式(Mediator)
  • .Net行为型设计模式之观察者模式(Observer)
  • .Net行为型设计模式之迭代器模式(Iterator)
  • .Net行为型设计模式之命令模式(Command)
  • .Net行为型设计模式之模板方法模式(Template Method)
  • .Net行为型设计模式之解释器模式(Interpreter)

0036-商场促销

0036-商场促销

题目

商场促销 难度级别:A; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述

商场购物现金结算促销,单张购物小票满300元全款九折,满500元全款八折,满1000元立减300元。现输入用户单张小票购物的金额 x(0<x<2000),输出用户的应付款数,用到的变量都使用double类型。

输入
一个数,表示单张购物小票的金额。
输出
一个数,表示客户实际应付款的数额。 
输入示例
350
输出示例
315

分析

    分支,不多说。

代码

#include<bits/stdc++.h>
using namespace std;
double a;
int main()
{
	cin>>a;
	if(a<300) cout<<a;//不够300元不打折。
	else if(a<500) cout<<a*0.9;//满300元打九折。
	else if(a<1000) cout<<a*0.8;//满500元打八折。
	else if(a>1000) cout<<a-300;//满1000元减300元。
	return 0;
}

C#实现策略模式

C#实现策略模式

场景:有一个喜欢吃饺子,他有三种不同的方式去吃,蒸饺子,煮饺子,煎饺子,想要用策略模式来设计这个场景,怎么弄?

1.复习简单工厂模式

具体的代码:

EatMethod.cs

?
1
2
3
4
5
6
7
public class EatMethod
{
   public virtual void Eat()
   {
      Console.WriteLine("This is the base class!");
   }
}

Steamed.cs

?
1
2
3
4
5
6
7
class Steamed : EatMethod
{
   public override void Eat()
   {
       Console.WriteLine("This is steamed dumplings!");
   }
}

Boiled.cs

?
1
2
3
4
5
6
7
class Boiled : EatMethod
{
   public override void Eat()
   {
     Console.WriteLine("This is boiled dumplings!");
   }
}

Fried.cs

?
1
2
3
4
5
6
7
class Boiled : EatMethod
{
   public override void Eat()
   {
     Console.WriteLine("This is boiled dumplings!");
   }
}

EatFactory.cs

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static class EatFactory
{
   public static EatMethod CreateEatMethod(string eatMethod)
   {
       EatMethod eat = null;
       switch (eatMethod)
       {
          case "Steamed":
               eat = new Steamed();
               break;
          case "Boiled":
               eat = new Boiled();
               break;
          case "Fried":
               eat = new Fried();
               break;
          default:
               break;
            }
        return eat;
    }
}

Program.cs

?
1
2
3
4
5
6
7
8
9
10
11
12
class Program
{
    static void Main(string[] args)
    {
        EatMethod eat = EatFactory.CreateEatMethod("Steamed");
        eat.Eat();
        eat = EatFactory.CreateEatMethod("Boiled");
        eat.Eat();
        eat = EatFactory.CreateEatMethod("Fried");
        eat.Eat();
    }
}

测试结果:

2.策略模式来设计

上面虽然用简单工厂实现了,但是感觉各种吃饺子的方式,用工厂来创建还是显得比较生硬,每一种吃法应该看成是一种算法,最终的目的都是吃掉,所以这里就引出了策略模式的概念了。

策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

这个模式涉及到三个角色:

环境(Context)角色:持有一个Strategy类的引用。抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

看了UML图感觉和简单工厂也没啥区别啊,不过是把Factory变成了Context而已,但是还是有些不同的,详见//www.jb51.net/article/254877.htm

这里和上面的简单工厂只有EatContext和客户端不一样

EatContext.cs

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class EatContext 
 {
      private EatMethod _eat;
 
      public EatContext(EatMethod eat)
      {
          _eat = eat;
      }
 
      public void Eat()
      {
         _eat.Eat();
      }
 }

Program.cs

?
1
2
3
4
5
6
EatContext ec = new EatContext(new Steamed());
ec.Eat();
ec = new EatContext(new Boiled());
ec.Eat();
ec = new EatContext(new Fried());
ec.Eat();

测试执行结果:

3.对比策略模式和简单工厂模式

我的理解是这样的:

首先是简单工厂模式:

客户端去调用工厂中的CreateEatMenthod方法,从输入上看,是一个字符串,指明了我想要的对象,然后工厂方法,就返回了一个我想要的对象,后面的具体的Eat(),是在客户端使用返回的对象进行调用的。

然后是策略模式:

客户端实例化一个EatContext对象,传入的参数是一个具体的怎么做饺子的对象,然后EatContext根据传入的对象,来初始化一个EatContext对象,后续的客户端操作通过的是EatContext的实例对象来完成的。

上面也能看出来,简单工厂用于创建对象,而策略模式更在乎控制行为,所以前者是创建型模式,后者是行为型模式。

实际应用中,可以将两者在进一步结合,再修改一下程序

EatFactoryContext.cs

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class EatFactoryContext
{
    EatMethod _eat = null;
    public EatFactoryContext(string eatMethod)
    {
        switch (eatMethod)
        {
            case "Steamed":
                _eat = new Steamed();
                break;
            case "Boiled":
                _eat = new Boiled();
                break;
            case "Fried":
                _eat = new Fried();
                break;
            default:
                break;
            }
        }
 
   public void Eat()
   {
      _eat.Eat();
   }
}

Program.cs

?
1
2
3
4
5
6
7
8
#region 结合
EatFactoryContext efc = new EatFactoryContext("Steamed");
efc.Eat();
efc = new EatFactoryContext("Boiled");
efc.Eat();
efc = new EatFactoryContext("Fried");
efc.Eat();
#endregion

测试结果:

4.总结

经过学习呢,发现是能够把简单工厂和策略模式进行基本的了解,但是如果工作中没有实际遇到,的确对于两者的区别的理解感到困惑,可能很多人和我一样,都是看到UML图发现,两者好像没有什么差别,可能理解还不深入吧,写得可能有些地方还不是很正确,希望看到的高手能指点一二。

到此这篇关于C#实现策略模式的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:

golang的框架如何通过策略模式实现代码复用?

golang的框架如何通过策略模式实现代码复用?

go语言中,利用策略模式可通过接口和结构体实现代码复用。通过定义 log() 方法的 logger 接口,并实现具体的 consolelogger 和 filelogger 结构体,可以根据不同的日志级别动态选择并使用不同的日志记录策略。这有助于提高日志记录的可扩展性,方便修改日志记录行为。

golang的框架如何通过策略模式实现代码复用?

Go语言中利用策略模式实现代码复用

策略模式简介

策略模式是一种设计模式,它允许你根据不同的情况动态地选择不同的算法或行为。这有助于提高代码的可复用性,因为你可以将算法的实现与它们的调用方式分离。

在 Go 中实现策略模式

立即学习“go语言免费学习笔记(深入)”;

在 Go 中,策略模式可以通过接口和结构体来实现:

type Strategy interface {
    DoSomething()
}

type ConcreteStrategyA struct{}

func (s ConcreteStrategyA) DoSomething() {
    fmt.Println("ConcreteStrategyA: DoSomething")
}

type ConcreteStrategyB struct{}

func (s ConcreteStrategyB) DoSomething() {
    fmt.Println("ConcreteStrategyB: DoSomething")
}
登录后复制

实战案例:日志记录

让我们看一个实战案例,使用策略模式实现日志记录:

package main

import (
    "context"
    "fmt"
    "log"
    "os"
)

type LogLevel int

const (
    INFO LogLevel = iota
    WARNING
    ERROR
)

type Logger interface {
    Log(ctx context.Context, level LogLevel, message string)
}

type ConsoleLogger struct {
    Level LogLevel
}

func (l *ConsoleLogger) Log(ctx context.Context, level LogLevel, message string) {
    if l.Level <= level {
        fmt.Fprintln(os.Stdout, message)
    }
}

type FileLogger struct {
    Level LogLevel
    File  *os.File
}

func (l *FileLogger) Log(ctx context.Context, level LogLevel, message string) {
    if l.Level <= level {
        fmt.Fprintln(l.File, message)
    }
}

func main() {
    // 创建不同的日志记录器
    consoleLogger := &ConsoleLogger{Level: INFO}
    fileLogger, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    if err != nil {
        log.Fatal(err)
    }
    defer fileLogger.Close()
    fileLogger := &FileLogger{Level: ERROR, File: fileLogger}

    // 使用策略模式写日志
    consoleLogger.Log(context.Background(), INFO, "This is an info message.")
    fileLogger.Log(context.Background(), ERROR, "This is an error message.")
}
登录后复制

在这个示例中,Logger 接口定义了 Log() 方法,该方法根据日志级别记录一条消息。ConsoleLogger 和 FileLogger 结构体实现了 Logger 接口,指定了如何记录消息以及使用哪个日志级别。

使用策略模式,我们可以在不同的上下文和要求中动态地选择不同的日志记录策略。这使我们可以轻松地扩展和修改日志记录行为,而无需修改调用代码。

以上就是golang的框架如何通过策略模式实现代码复用?的详细内容,更多请关注php中文网其它相关文章!

今天关于通过商场促销来看策略模式+vb.net实现了解各大商场的促销方式有哪些的分享就到这里,希望大家有所收获,若想了解更多关于.Net行为型设计模式之策略模式(Stragety)、0036-商场促销、C#实现策略模式、golang的框架如何通过策略模式实现代码复用?等相关知识,可以在本站进行查询。

本文标签:

上一篇淘宝最新促销手段(淘宝最新促销手段是什么)

下一篇Stream冬季大促销:半价GTA5轻松收入囊中(gta5steam打折2021)