23种设计模式之我见(1)

原创 2015年11月18日 11:52:44
23种设计模式之我见(1)
本文是我对设计模式的理解,旨在与大家分享心得,探讨心得。希望可以共同探讨。

工厂方法模式

定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。

其实工厂模式,可以分成三种,简单工厂模式,工厂方法模式和抽象工厂模式。


对于简单的工厂模式,其实有一个类方法(或静态方法就可以实现)。

假如我们设定一个枚举,表示一个按钮(Button)的显示风格。那么我们就可以在一个类方法的内部来决定我们到底用生成那种对象。

有人可能会说,我可以在按钮类的内部进行类型的判断,把枚举当成一个构造函数的参数,这样还可以减少代码以及减少很多碎片类。例如:

Button(ButtonType type)
{
      switch type
       case 0:
{
 //draw
       }
      case 1:
     {
            //draw
     }
}



但是我们也可以明显的看出这种代码的利弊。

代码应该是高内聚的(内聚:最简单的可以理解为,一个子程序/函数应该只干一件事儿),面向对象的精髓并不是我要写一个万能类,而是在于每个对象干一件简单的事儿,由它的上一级进行合理的分工。最重要的是,这种写法不利于以后的扩展和维护。我们一旦增加一种风格,我们就要去这个类里面找,这个类就跟风格枚举耦合性太高(耦合:两个不同对象/类型的关联程度,简单来说就是互相影响的程度,动一个类的代码,是否会牵扯到另一个类)。对于维护,我们不能因为改变某一个风格的显示效果,就去动按钮类。这样会让按钮类,变得非常大,非常乱。

我们虽然有一个万能类,但是我们无法很好地驾驭它。

那我们应该怎么做呢?

其实我们只需要把每一种风格定义一个子类,定义一个父类来作为抽象按钮,每一个子类来进行特定风格的处理。

例如:

class baseButton
{
    draw();
}
class A_Button
{
    draw();
}
class B_Button
{
    draw();
}

public  static baseButton createButton(ButtonType type)
{
      switch type
      {
            case 0:return new A_Button();
            case 1:return new B_Button();
      }
}

client:
baseButton btn = createButton(typeA);
btn.addToSuperView();


这样处理之后,当我们某个风格出现问题,只需要改掉该风格对应的子类,即可。以后对于增加一种风格,也不需要去button内部,我们只需要添加一个枚举,增加一个子类即可。

我们可以看到,我们通过一个静态方法,合理的将不同的子类合理的分配好,这样大大增加了我们代码适应需要变化的能力。


对于工厂方法模式,相比简单工厂,又有一些区别。可以说是简单工厂模式的升级版。我们现在可以避免写万能类的,但是如果我们不同的产品类之间差异性较大,我们还用简单工厂模式,那么我们的switch块会变得非常复杂,那么我们的switch块也将不再有良好的内聚性。我们就可以同时对于产品A和产品B创建工厂A和工厂B,在工厂的内部处理A和B的差异性。每个工厂处理自己风格的产品。例如:

class baseButton{}
class A_Button:baseButton{}
class B_Button:baseButton{}

interface factory{
      createButton();
}

class factoryA:factory{
baseButton createButton()
{
     //给A_Button 添加子视图
     return new A_Button();
}
};
class factoryB:factory{
baseButton createButton()
{
     //给B_Button 给B_Button旋转45度
     return new B_Button();
}
};

client:
factory f = new factoryA();
f.createButton(type);


这样处理之后,我们的代码逻辑将更加清晰。不同类型的耦合性非常低,我们对于新需求,只需要添加新的工厂和新的产品即可。不用动以前的类,我们如果切换新的工厂,只需要new一个新的子类即可(改动一行代码)。



关于类簇模式

类族模式,可以说是简单工厂模式的变种。由抽象基类派生出一些具体的子类,抽象基类提供工厂方法来创建具体的子类。而最终要隐藏具体子类的实现,让外部表现为抽象基类的指针。

这样既能降低不同产品类之间的耦合度。也能让使用者的学习成本降低。因为对外暴露的只是基类的接口,所以只要使用者掌握了基类的接口就可以完全掌握所有具体子类,因为具体子类外部是不可见的。例如:


class Dog
{
       Color whatColor();
       static Dog createDogWithType(int type)
       {   
                swtich (type)
                case  0: return new 黑背;
                case 1: return new 金毛;
                case 2:return new 萨摩;
       };
}

class 黑背:Dog
{
         color whatColor()
        {
             return 黑;
        }
}


class 金毛: Dog
{
   color whatColor()
        {
             return 金;
        }
}

class 萨摩: Dog
{
   color whatColor()
        {
             return 白;
        }
}


client:

Dog  d = Dog::createDogWithType(0);
Color  c = d.whatColor();



使用这种方法的要求比较苛刻,必须你的产品对象高度符合面向对象的继承原则,子类之间对于外部表现性是一样的,依赖同一组API,并且不会产生歧义。当合理的运用类簇模式的话,程序的开发效率会大大增加,也可以很好地解耦。


简单工厂模式和工厂方法模式,是接触类之间耦合的有效方法和常用方法。 可以说也是比较合理运用类的多态性的设计模式。大家在实践中,可以先熟悉简单工厂模式和类簇模式,在反复使用这两个模式中,体会此设计模式的目的和脊髓,将有助于代码质量的提高。


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

23种设计模式之我见----创建型模式(1)

创建型模式:          创建型模式抽象了实例化过程。他们帮助一个系统独立于如何创建、组合和表示他的那些对象。一个类创建型模式使用继承改变被实例化的类。而一个对象创建型模式将实例化委托给另...

(四)23种设计模式之我见-----------观察者模式(Observer)

设计模式这本书中对观察者模式做了如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。下面我对深入浅出设计模式这本书中的观察者模式,进行自己...

23种设计模式之我见----结构型设计模式(2)

在软件工程中,创建型模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象。基本的对象创建方式可能会导致设计上的问题,或增加设计的复杂度。创建型模式通过以某种方式控制对象的创建来解决问题...

23种设计模式之我见----结构型设计模式之2(3)

9.外观模式(Facade) 门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行,也就是对于子系统的操作通过暴漏出来的门面进行操作就行,并不需要了解具体的操作是什...

23种设计模式之我见----结构型设计模式之2(3)

9.外观模式(Facade) 门面模式要求一个子系统的外部与其内部的通信必须通过一个统一的门面(Facade)对象进行,也就是对于子系统的操作通过暴漏出来的门面进行操作就行,并不需要了解具体的操作是...

23种设计模式之我见----结构型设计模式(2)

在软件工程中,创建型模式是处理对象创建的设计模式,试图根据实际情况使用合适的方式创建对象。基本的对象创建方式可能会导致设计上的问题,或增加设计的复杂度。创建型模式通过以某种方式控制对象的创建来解决问题...

设计模式(GOF)之我见(1)——Factory

java GOF Factory(工厂)设计模式

设计模式之我见

  • 2012-09-07 12:55
  • 72KB
  • 下载

设计模式之我见源代码

  • 2016-07-12 17:36
  • 87KB
  • 下载

设计模式之三大原则(fyun之我见系列三)

我们先来回顾下策略模式,一般策略模式主要满足以下情况: 1: 多个对象(类)只是在其特征或表现出来的行为不同,运行时需要动态来分别执行它们。 2:需要在不同情况下,调用一个对象(子类)来实现不同的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)