深入浅出设计模式第一章笔记

    一:找出应用中可能需要变化之处,把它们独立出来, 不要和那些不需要变化的代码混在一起。把会变化的部分取出并「封装」起来,好让其他部分不会受到影响。

    二:针对接口编程,而不是针对实现编程。由行为类实现行为接口。

    sheji01

假设有一个抽象类Animal,有两个具体的实现(Dog与Cat)继承自Animal。「针对实现编程」,作法如下:

Dog d = new Dog();
d.bark();

但是「针对接口/超类型编程」,作法会如同下面:

Animal animal = new Dog();
animal.makeSound();

更棒的是,子类型实例化的动作不再需要在代码中硬编码,例如new Dog(),而是「在运行时才指定具体实现的对象」。

a = getAnimal();
a.makeSound();

关键在于,鸭子现在会将飞行和呱呱叫的动作,「委托」(delegate)别人处理,而不是使用定义在自己类(或子类)内的方法。

public class Duck {
    QuackBehavior quackBehavior;  //每只鸭子都会引用实现QuackBehavior接口的对象。
    // 还有更多
    public void performQuack() {
        quackBehavior.quack();  //不亲自处理呱呱叫行为,而是委托quackBehavior对象帮Duck呱呱叫。
    }
}

好吧!现在来关心「如何设定flyBehavior 与quackBehavior的实例变量」。看看MallardDuck类:

public class MallardDuck extends Duck {
    public MallardDuck() {
        quackBehavior = new Quack();//绿头鸭使用Quack类处理呱呱叫,所以当 performQuack()被调用,就把责任交给Quack对象进行真正的呱呱叫。
        flyBehavior = new FlyWithWings();
    }

    public void display() {
        System.out.println(“I’m a real Mallard duck”);
    }
}

sheji02

『有一个』关系相当有趣: 每一鸭子都有一个F l y B e h a v i o r 且有一个QuackBehavior,让鸭子将飞行和呱呱叫委托它们代为处理。

当你将两个类结合起来使用,如同本例一般,这就是组合( c o m p o s i t i o n ) 。这种作法和『继承』不同的地方在于,鸭子的行为不是继承而来,而是和适当的行为对象『组合』而来。


这是一个很重要的技巧。其实是使用了我们的第三个设计原则:

三:多用组合,少用继承。

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

观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都
会收到通知并自动更新。

设计原则:类应该对扩展开放,对修改关闭。

继承无法完全解决问题包括:类数量爆炸、设计死板,以及基类加入的新功能并不适用于所有的子类。

装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。


装饰者模式——动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。

大话设计模式:

sheji03

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

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

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

}

客户端主要代码如下:
double total = 0.0d;//用于总计
private void btnOk_Click(object sender, EventArgs e)
{
    CashContext cc = new CashContext();
    switch (cbxType.SelectedItem.ToString())
    {
        case "正常收费":
            cc.setBehavior(new CashNormal());
            break;
        case "满300返100":
            cc.setBehavior(new CashReturn("300", "100"));
            break;
        case "打8折":
             cc.setBehavior(new CashRebate("0.8"));
             break;
    }
    double totalPrices = 0d;
    totalPrices = cc.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
     total = total + totalPrices;
    lbxList.Items.Add("单价:" + txtPrice.Text +" 数量:" + txtNum.Text + " " + cbxType.SelectedItem +" 合计:" + totalPrices.ToString());
    lblResult.Text = total.ToString();
}

上面的策略模式是有缺点的,客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

.net的反射技术:

1//实例化方法一

2//原来我们把一个类实例化是这样的

3Animal animal=new Cat(); //声明一个动物对象,名称叫animal,然后将animal实例化成猫类的对象4

5//实例化方法二

6//我们还可以用反射的办法得到这个实例

7using System.Reflection;//先引用System.Reflection

8//假设当前程序集是AnimalSystem,名称空间也是AnimalSystem

9Animal animal = (Animal)Assembly.Load("AnimalSystem").CreateInstance("AnimalSystem.Cat");

其中关键是

Assembly.Load("程序集名称").CreateInstance("名称空间.类名称")

那也就是说,我们可以在实例化的时候,再给计算机一个类的名称字符串,来让计算机知道应该实例化哪一个类。

因为这里是字符串,可以用变量来处理,也就可以根据需要更换。所以实例二比实例一灵活。差别主要在原来的实例化是写死在程序里的,而现在用了反射就可以利用字符串来实例化对象,而变量是可以更换的。

让程序去读XML的配置文件,来生成这个下拉列表框,然后再根据用户的选择,通过反射实时的实例化出相应的算法对象,最终利用策略模式计算最终的结果。

所谓单一职责原则,就是指就一个类而言,应该仅有一个引起它变化的原因,就刚才修电脑的事,显然内存坏了,不应该成为更换CPU的理由。

开放—封闭原则是说对扩展开发,对修改关闭,通俗的讲,就是我们在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,换句话说就是,应当可以在不必修改源代码的情况下改变这个模块的行为。比如内存不够只要插槽多就可以加,比如硬盘不够了,可以用移动硬盘等,PC的接口是有限的,所以扩展有限,软件系统设计得好,却可以无限的扩展。

依赖倒转原则,原话解释是抽象不应该依赖细节,细节应该依赖于抽象,这话绕口,说白了,就是要针对接口编程,不要对实现编程,无论主板、CPU、内存、硬盘都是在针对接口编程,如果针对实现编程,那就会出现换内存需要把主板也换了的尴尬。

三层架构:用来界面显示和处理的,它们可以看作是一层,叫界面层或者叫UI层、表现层。访问配置文件或处理数据库叫做数据访问层(Data Access Layer)或简称DAL层。业务(Business)或叫商务,这其实是软件的核心,我们就是根据业务规则来开发软件提供服务的,所以这个层叫做业务逻辑层(Business Logic Layer)。不过它应该是中间的一层,介于另两者之间。所谓的三层开发,就是关于表现层、业务逻辑层和数据访问层的开发

迪米特法则(LoD)’ 也叫最少知识原则,简单的说,就是如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值