设计模式之六大原则 以及 简单工厂模式

      作为一个合格的程序员所写出来的程序是要具有灵活性的,就是写的代码,要维护性高,复用性高,扩展性高。通过面向对象的特点(封装,继承,多态...)把程序的耦合度降低,使其达到高内聚,低耦合。那么在有些时候使用适当的设计模式可以使得程序更加的灵活,易于修改,易于复用。


设计模式的六大原则

一、单一职责原则

该原则是指一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。它是实现高内聚、低耦合的指导方针,它是最简单但又最难运用的原则,需要设计人员发现类的不同职责并将其分离,而发现类的多重职责需要设计人员具有较强的分析设计能力和相关实践经验。

二、开闭原则

该原则是面向对象的可复用设计的第一块基石,它是最重要的面向对象设计原则。一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展,软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类。

三、里氏替换原则

该原则是指所有引用基类(父类)的地方必须能透明地使用其子类的对象。在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。

四、依赖倒置原则

抽象不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而不是针对实现编程。
在实现依赖倒转原则时,我们需要针对抽象层编程,而将具体类的对象通过依赖注入(DI)的方式注入到其他对象中,依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。常用的注入方式有三种,分别是:构造注入,设值注入(Setter注入)和接口注入。构造注入是指通过构造函数来传入具体类的对象,设值注入是指通过Setter方法来传入具体类的对象,而接口注入是指通过在接口中声明的业务方法来传入具体类的对象。这些方法在定义时使用的是抽象类型,在运行时再传入具体类型的对象,由子类对象来覆盖父类对象。

五、接口隔离原则

使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
在使用接口隔离原则时,我们需要注意控制接口的粒度,接口不能太小,如果太小会导致系统中接口泛滥,不利于维护;接口也不能太大,太大的接口将违背接口隔离原则,灵活性较差,使用起来很不方便。一般而言,接口中仅包含为某一类用户定制的方法即可,不应该强迫客户依赖于那些它们不用的方法。

六、迪米特法则

一个软件实体应当尽可能少地与其他实体发生相互作用。迪米特法则可降低系统的耦合度,使类与类之间保持松散的耦合关系。迪米特法则要求我们在设计系统时,应该尽量减少对象之间的交互,如果两个对象之间不必彼此直接通信,那么这两个对象就不应当发生任何直接的相互作用,如果其中的一个对象需要调用另一个对象的某一个方法的话,可以通过第三者转发这个调用。简言之,就是通过引入一个合理的第三者来降低现有对象之间的耦合度

在将迪米特法则运用到系统设计中时,要注意下面的几点:

1)在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及;

2)在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限;

3)在类的设计上,只要有可能,一个类型应当设计成不变类;在对其他类的引用上,一个对象对其他对象的引用应当降到最低。


简单工厂模式

现在我们有一个要做计算器需求,要求实现加减乘除的算法,用简单工厂模式就如下:

类图:

设计模式之六大原则 以及 简单工厂模式_第1张图片

1、新建一个Operation类

public class Operation {
    private double NumberA;
    private double NumberB;

    public Operation() {
        NumberA = 0.00;
        NumberB = 0.00;
    }

    public double getNumberA() {
        return NumberA;
    }

    public void setNumberA(double numberA) {
        NumberA = numberA;
    }

    public double getNumberB() {
        return NumberB;
    }

    public void setNumberB(double numberB) {
        NumberB = numberB;
    }

    public double getResult(double NumberA,double NumberB) throws Exception {

        double result = 0.0;
        return result;
    }
}

2、分别新建加、减、乘、除的类来继承这个Operation父类

1)加法:

public class OperationAdd extends Operation {
    /**
     * 加法
     */
    @Override
    public double getResult(double NumberA,double NumberB) {
        double result = NumberA + NumberB;

        return result;
    }
}

2)减法:

public class OperationSub extends Operation {
    /**
     * 减法
     */
    @Override
    public double getResult(double NumberA, double NumberB) {
        double result = NumberA - NumberB;

        return result;
    }
}

3)乘法:

public class OperationMul extends Operation {
    /**
     * 乘法
     */
    @Override
    public double getResult(double NumberA, double NumberB) {
        double result = NumberA * NumberB;

        return result;
    }
}

4)除法:

public class OperationDiv extends Operation {
    /**
     * 除法
     */
    @Override
    public double getResult(double NumberA, double NumberB) throws Exception {

        if (NumberB == 0) {
            throw new Exception("除数不能为0");
        }

        double result = NumberA / NumberB;

        return result;
    }
}

3、新建一个运算工厂类在实现这个运算

public class OperationFactory {
    public static Operation createOperation(String operate) {

        Operation ope = null;
        switch (operate) {
            case "+":
                ope = new OperationAdd();
                break;
            case "-":
                ope = new OperationSub();
                break;
            case "*":
                ope = new OperationMul();
                break;
            case "/":
                ope = new OperationDiv();
                break;
        }
        return ope;
    }
}

4、运行

public class Run {

    public static void main(String[] args) throws Exception{

        Operation operation = OperationFactory.createOperation("-");

        double NumberA = 1;
        double NumberB = 2;

        double result = operation.getResult(NumberA,NumberB);

        System.out.println(result);
    }
}

 简单工厂模式的优点:

 模块清晰化,每个部分都各司其职,分工明确。

缺点:

如果此时需要增加一产品,比如在计算器中加入一个新的功能,可以求M的N次方,这样个小功能我们就要去添加一个新的类,同时我们需要在Factory中改动到switch里面的代码,这是耦合性很高的表现。

你可能感兴趣的:(java)