大话设计模式(一)简单工厂模式 策略模式 单一职责原则 开放-封闭原则 依赖倒置原则 装饰模式


简单工厂模式

public class Operation
{
    private double _numberA=0;
    private double _numberB=0;

    public double NumberA
    {
        get
        {
            return _numberA;
        }set
        {
            _numberA=value;
        }
    }
    public double NumberB
    {
        get
        {
            return _numberB;

        }
        set
        {
            _numberB=value;
        }
    }
    
    public virtual double GetResule()
    {
        double result=0;
        return result;
    }
}
class OperationAdd:Operation
{
    public override double GetResult()
    {
        double result=0;
        result=NumberA+NumberB;
        return result;
    }
}

class OperationSub:Operation
{
    public override double GetResult()
    {
        double result=0;
        result=NumberA-NumberB;
        return result;
    }
}
class OperationMul:Operation
{
    public override double GetResult()
    {
        double result=0;
        result=NumberA*NumberB;
        return result;
    }
}
class OperationDiv:Operation
{
    public override double GetResult()
    {
        double result=0;
        if (NumberB==0)
            throw new Exception("除数不能为0")
        result=NumberA+NumberB;
        return result;
    }
}

public class OperationFactory
{
    public static Operation createOperate(string operate)
    {
        Operation oper =null;
        switch(operate)
        {
            case "+":
                oper=new OperationAdd();
            break;
            case "-":
                oper=new OperationSub();
            break;
            case "*":
                oper=new OperationMul();
            break;
            case "/":
                oper=new OperationDiv();
            break;
        }
        return oper;
    }
}

//客户端代码
Operation oper;
oper=OperationFactory.createOperate("+");
oper.NumberA=1;
oper.NumberB=2;
double result=oper.GetResult();

策略模式

实现原理:

//Strategy类,定义所有支持算法的公共接口
abstract class Strategy
{
    //算法方法
    public abstract void AlgorithmInterface();
}
//ConcreteStrategy,封装了具体的算法或行为,继承与Strategy
//具体算法A
class  ConcreteStrategyA:Strategy
{
    public override void AlgorithmInterface()
    {
        Console.WriteLine("算法A实现");
    }
}
//具体算法B
class  ConcreteStrategyA:Strategy
{
    public override void AlgorithmInterface()
    {
        Console.WriteLine("算法B实现");
    }
}
//具体算法C
class  ConcreteStrategyC:Strategy
{
    public override void AlgorithmInterface()
    {
        Console.WriteLine("算法C实现");
    }
}
//用一个Concretestrategy来配置,维护一个对Strategy对象的引用
//上下文
class Context
{
    Strategy strategy;
    //初始化时,传入具体策略对象
    public Context(Strategy strategy)
    {
        this.strategy=strategy;
    }
    //上下文接口--根据具体的策略对象,调用其算法的方法
    public void ContextInterface()
    {
        strategy.AlgorithmInterface();
    }
}
//客户端代码
static void Main (string[] args)
{
    Contect context;
    //由于实例化不同的策略,所以最终在调用context.ContextInterface();时,所获得的结果就不尽相同
    context= new Context(new ConcreteStrategyA());
    context.ContextInterface();

    context= new Context(new ConcreteStrategyA());
    context.ContextInterface();
    context= new Context(new ConcreteStrategyA());
    context.ContextInterface();
}

面向对象编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类。

策略模式的实现:

//现金收费抽象类
abstract class CashSuper
{
    public abstract double aceptCash(double money);
}
//正常收费子类
class CashNormal : CashSuper
{
    public abstract double acceptCash(double money);
}
//打折收费子类
class CashRebate:CashSuper
{
    private double moneyRebate=1d;
    
    //打八折 就是0.8
    public CashRebate(string moneyRebate)
    {
        this.moneyRebate=double.parse(moneyRebate);
    }
    public override double accepCash(double money)
    {
        return money* moneyRebate;
    }
        
}

//返利收费子类
class CashReturn : CashSuper
{
    //满足了那些条件。
    private double moneyCondition=0.0d;
    //返回多少
    private double moneyReturn=0.0d;

    public CashReturn(string moneyConditon , string moneyReturn)
    {
        this.moneyCondition=double.Parse(moneyCondition);
        this.moneyReturn=double.Parse(moneyReturn);
    }
    public override double acceptCash(double money)
    {
        double result=money;
        if (money>=moneyCondition)
        {
            result=money-Math.Floor(money/moneyCondition)*moneyReturn;
        }
        return result;
    }

}

简单工厂:

//现金收费工厂类
class CashFactory
{
    public static CashSuper createCashAccept(string type)
    {
        CashSuper cs=null;
        switch (type)
        {

            case "正常收费":
                cs=new CashNormal();
                break;
            case "满300返100":
                CashReturn cr1=new CashReturn("300","100");
                cs=cr1;
                break;
            case "打8折":
                CashRebate cr2=new CashRebate("0.8");
                cs=cr2;
                break;
        }
        return cs;
    }
}
//客户端主要部分
//客户端代码
double total=0.0d;
private void btn_Click(object sender , EventArgs e)
{
    CashSuper csuper=CashFactory.createCashAccept(cbxType.SelectItem.Tostring());
    double totalPrice=0d;
    //利用简单工厂模式根据下拉选择框,生成相应的对象     totalPrices=csuper.AcceptCash(Convert.ToDouble(txtPrice.Text)*Convert.ToDouble(txtNum.Text));
    total=total+totalPrices;
    lbx.List.Items.Add("单价:"+txtPrice.Text+"数量:"+txtNum.Text+""+cbxType.SelectItem+"合计:"+totalPrice.Tostring());
    lblResult.Text=total.Tostring();
}

策略模式:

//CashContext
class CashContext
{
    //声明一个CashSuper对象
    private CashSuper cs;
    
    //通过构造方法。传入具体的收费策略
    public CashContext(CashSuper csuper)
    {
        this.cs=csuper;
    }
    public double GetResult(double money)
    {      //根据收费策略的不同获得计算结果
        return cs.acceptCash(money)
    }
}

//客户端主要部分
//客户端代码
double total=0.0d;
private void btn_Click(object sender , EventArgs e)
{
    CashContext cc=null;
    switch (cbxType.SelectedItem.ToString())
    {

        case "正常收费":
            cc=new CashContext(new CashContext());
            break;
        case "满300返100":
            cc=new CashContext(new CashReturn("300","100"));
            
            break;
        case "打8折":
            cc=new CashContext(new CashRebate("0.8"));
            break;
    }
    double totalPrice=0d;
    //通过对Context的GetResult方法的调用,可以得到收费结果,让具体算法与客户进行了隔离
    totalPrices=cc.GetResult(Convert.ToDouble(txtPrice.Text)*Convert.ToDouble(txtNum.Text));
    total=total+totalPrices;
    lbx.List.Items.Add("单价:"+txtPrice.Text+"数量:"+txtNum.Text+""+cbxType.SelectItem+"合计:"+totalPrice.Tostring());
    lblResult.Text=total.Tostring();
}

策略与简单工厂结合--改造后的CashContext:

class CashContext
{
    //声明一个CashSuper对象
    CashSuper cs =null;
    public CashContext(string type)//注意参数不是具体策略对象,而是一个字符串,表示收费类型
    {
        switch(type)
        {
            //将实例化策略的过程有客户端转移到Context类中,简单工厂的应用
            case "正常收费":
                CashNormal cs0=new CashNormal();
                cs=cs0;
                break;
            case "满300返100":
                CashNormal cs1=new CashReturn("300","100");
                cs=cs1;
                break;
            case "打八折":
                CashNormal cs2=new CashNormal("0.8");
                cs=cs2;
                break;

        }
    }
    public double GetResult(double money)
    {
        return cs.acceptCash(money);
    }
}

//客户端代码
double total=0.0d;
private void btn_Click(object sender , EventArgs e)
{
    CashContext csuper=new CashContext(cbxType.SelectItem.Tostring());
    double totalPrice=0d;
    //通过对Context的GetResult方法的调用,可以得到收取费用的结果,让具体算法与客户进行隔离
    totalPrices=csuper.GetResult(Convert.ToDouble(txtPrice.Text)*Convert.ToDouble(txtNum.Text));
    total=total+totalPrices;
    lbx.List.Items.Add("单价:"+txtPrice.Text+"数量:"+txtNum.Text+""+cbxType.SelectItem+"合计:"+totalPrice.Tostring());
    lblResult.Text=total.Tostring();
}

两者比较:

//简单工厂模式用法 CashSuper csuper = CashFactory.createCashAccept(cbxType.SeletedItem.ToString()); //策略模式与简单工厂模式结合的用法 CashContext csuper = new CashContext(cbxType.SelectItem.ToString());

策略模式的定义:

策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都相同的工作,只是实现不同,他可以以相同的方式调用所有算法,减少了各种算法类与使用算法类之间的耦合

策略模式的有点: 策略模式的Stragegy类层次为Context定义了一系列的可供重用的算法或行为,继承有助于析取出这些算法的公共功能。 策略模式简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试

单一职责原则

单一职责原则(SRP),就一个类而言,应该仅有一个引起它变化的原因。 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能削弱或者抑制之歌类完成其他职责的能力,这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。 软件设计真正要做的许多内容,就是发现职责并把哪些职责相互分离。 如何判断:如果你能想到多于一个的冬季去改变一个类,那么这个类就具有多于一个的职责。

开放-封闭原则

开放-封闭原则,是说软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。

怎样的设计才能面对需求的改变却可以保持相对稳定,从而使得系统可以在第一个版本以后不管推出新版本呢?

开放封闭原则就是:你设计的时候时刻考虑尽量让这个类设计的足够好,写了就不去修改他。

无论模块多么的封闭,都会存在一些无法对之封闭的变化。既然不可能完成封闭,设计人员必须对于他设计的模块应该对那种变化封闭做出选择。他必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化

开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那部分做出抽象,然而,对于应用程序中的每个部分都可以进行抽象同样不是好事,拒绝不成熟的抽象和抽象本身一样重要

依赖倒转原则

A.搞成模块不应该依赖底层模块,两个都应该依赖抽象。

B.抽象不应该依赖细节。细节应该依赖抽象。

里氏代换原则

一个软件试题如果使用的是一个弗雷的话,那么一定适用于其子类,而且他察觉不出父类对象和子类对象的区别,爷爷就是说,在软件里面,吧弗雷都替换成他的子类,程序的行为没有变化。

定义:子类型必须能够替换掉他们的父类型。

依赖倒置日式可以输哦是面向对象设计的标志,用那种语言来编程不重要,如果编程时考虑的都是如何针对抽象面呈而不是针对细节编程,即程序中所有依赖关系都是终止与抽象类或者接口,那就是面向对象的设计。反之就是过程化的设计了

装饰模式

Compontent是定义一个对象接口,可以给这些对象动态添加职责,ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责,Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Decorator
{
    class Program
    {
        static void Main(string[] args)
        {
            //Decorator1.Run.Go();
            FishDemo.Run.Go();
        }
    }


}
namespace Decorator1
{

    public class Run
    {
        //客户端代码
        public static void Go()
        {
            ConcreteComponent c = new ConcreteComponent();
            ConcreteDecoratorA d1 = new ConcreteDecoratorA();
            ConcreteDecoratorB d2 = new ConcreteDecoratorB();

            /* 装饰的方法是:首先用ConcreteComponent实例化对象c,
             * 然后用ConcreteDecoratorA的实例化d1来包装c,再用ConcreteDecoratorB
             * 的对象d2包装d1,最终执行d2的Operation
             */
            d1.SetComponent(c);
            d2.SetComponent(d1);
            d2.Operation();
            Console.Read();
        }
    }

    //装饰者模式
    abstract class Component
    {
        public abstract void Operation();
    }
    //ConcrereComponent类
    class ConcreteComponent : Component
    {
        public override void Operation()
        {
            Console.WriteLine("具体对象的操作");
        }
    }
    //Decorator 类
    abstract class Decorator : Component
    {
        protected Component component;
        //设置Component
        public void SetComponent(Component component)
        {
            this.component = component;
        }

        //重写Operation(),实际执行的是Component的Operation()
        public override void Operation()
        {
            if (component != null)
            {
                component.Operation();
            }
        }
    }

    //ConcreteDecoratorA类
    class ConcreteDecoratorA : Decorator
    {
        //本类的独有功能,以区别于ConcreteDecoratorB
        private string addedState;

        //首先运行原Component的Operation(),在执行本类的功能,如addedState,相当于对原Component进行了装饰。
        public override void Operation()
        {
            base.Operation();
            addedState = "New State";
            Console.WriteLine("具体装饰对象A的操作");
        }
    }

    //ConcreteDecoratorB类
    class ConcreteDecoratorB : Decorator
    {
        //首先运行原Component的Operation(),在执行本类的功能,如AddedBehavior(),相当于对原Component进行了装饰。
        public override void Operation()
        {
            base.Operation();
            AddedBehavior();
            Console.WriteLine("具体装饰对象B的操作");
        }
        private void AddedBehavior()
        {
        }
    }

}
namespace FishDemo
{
    class Person
    {
        public Person() { }

        private string name;
        public Person(string name)
        {
            this.name = name;
        }
        public virtual void Show()
        {
            Console.WriteLine("装扮的{0}", name);
        }
    }

    class Finery : Person
    {
        protected Person component;
        //打扮
        public void Decorate(Person component)
        {
            this.component = component;
        }

        public override void Show()
        {
            if (component != null)
            {
                component.Show();
            }
        }
    }

    class Tshirts : Finery
    {
        public override void Show()
        {
            Console.WriteLine("大T恤");
            base.Show();
        }
    }
    class BigTrouser : Finery
    {
        public override void Show()
        {
            Console.WriteLine("垮裤");
            base.Show();
        }
    }

    class Sneakers : Finery
    {
        public override void Show()
        {
            Console.WriteLine("破球鞋");
            base.Show();
        }
    }

    class WearSuit : Finery
    {
        public override void Show()
        {
            Console.WriteLine("西装");
            base.Show();
        }
    }

    class WearTie : Finery
    {
        public override void Show()
        {
            Console.WriteLine("领带");
            base.Show();
        }
    }

    class WearLeatherShoes : Finery
    {
        public override void Show()
        {
            Console.WriteLine("皮鞋");
            base.Show();
        }
    }


    class Run
    {
        public static void Go()
        {
            Person xc = new Person("小菜");
            Console.WriteLine("\n第一种装扮:");

            Sneakers pqx = new Sneakers();
            BigTrouser kk = new BigTrouser();
            Tshirts dtx = new Tshirts();

            pqx.Decorate(xc);
            kk.Decorate(pqx);
            dtx.Decorate(kk);
            dtx.Show();

            Console.WriteLine("\n第二种装饰:");
            WearLeatherShoes px = new WearLeatherShoes();
            WearTie ld = new WearTie();
            WearSuit xz = new WearSuit();

            px.Decorate(xc);
            ld.Decorate(px);
            xz.Decorate(ld);
            xz.Show();

            Console.Read();

        }
    }
}

装饰者模式总结:

在起初设计中,当系统需要新功能的时候,是向旧的类中添加新的代码,这些新加的代码通常装饰了原有类的核心职责或主要行为。在主类中加入的东西仅仅是为了班组一些只在某种特定情况下才会执行的特殊行为的需要,而装饰模式去额提供了一个非常好的解决方案,他把每个要装饰的功能放在单独的类中,并让这个类包括他所要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地,按顺序的使用装饰功能包装对象了

装饰模式的有点:把类中的装饰功能从类中搬移去除,这样可以简化原有的类。有效的把类的核心职责和装饰功能区分开了。

优质内容筛选与推荐>>
1、go获取windows的hostid
2、HihoCoder#1509:异或排序(二进制)
3、教你用Python解决非平衡数据问题(附代码)
4、仿今日头条滑动评论效果
5、SAP最佳业务实践:SD–含客户预付款的销售订单处理(201)-6开票


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn