引言
设计模式是我们开发中为了代码的可维护性和可复用性必须掌握的一项技能,设计模式分为23种,在讲解工厂方法模式之前,我们先来了解一下设计模式的原则以及分类。
设计模式原则
设计模式原则 | 英文缩写 | 意义 |
---|---|---|
单一职责原则 | SRP(Single responsibility principle) | 就一个类而言应该只有一个引起它变化的原因 |
开放关闭原则 | OCP(Open Closed Principle) | 一个软件实体应该对扩展开放,对修改关闭 |
里氏替换原则 | LSP liskov substitution principle | 所有引用基类(父类)的地方必须能透明地使用其子类的对象 |
依赖倒置原则 | DIP Dependency Inversion Principle | 抽象不应该依赖于细节,细节应该依赖于抽象 |
接口隔离原则 | ISP Interface Segregation Principle | 使用多个专门的接口,而不使用单一的接口 |
迪米特法则 | LOD Low Of Demeter | 一个软件实体应当尽可能少地与其它实体发生相互作用 |
单一职责原则:是为了让我们的接口职责单一,代码高内聚低耦合。
开放关闭原则:表格中的软件实体可以指一个软件模块,或者一个由多个类组成的局部结构或者一个独立类。
里氏替换原则:是实现开闭原则的重要方式之一,可以扩展父类功能,但是不能改变父类功能,尽量不要重写父类方法。
依赖倒置原则:在变量类型声明,参数声明,方法返回值类型声明使用接口或者抽象类。
接口隔离原则:即接口大小要适中,太小会接口泛滥,太大将违背接口隔离原则。
迪米特法则:可以降低系统的耦合度,使类与类之间保持松散的耦合关系,当一个模块需要修改时候,需要尽量少地影响其它模块,这样扩展起来会比较容易。
设计模式分类
类别 | 设计模式 |
---|---|
创建型模式(五种) | 工厂方法模式 抽象工厂模式 单例模式 建造者模式 原型模式 |
结构型模式(七种) | 适配器模式 装饰者模式 代理模式 外观模式 桥接模式 组合模式 享元模式 |
行为型模式(十一种) | 策略模式 模板方法模式 观察者模式 迭代器模式 责任链模式 命令模式 备忘录模式 状态模式 访问者模式 中介者模式 解释器模式 |
抽象工厂模式概述:
因为上一篇文章工厂方法模式最后的静态工厂方法模式对象的创建依赖于工厂类,想要扩展程序,就必须修改类,这样违背了OCP原则。那么怎么样才能不违背OCP原则呢?我们可以我们抽象出来一个接口获取Animal对象,创建多个工厂类获取不同的对象。这样如果想要新获取一个新的实例,就需要创建一个类比如Bird,就要实现Animal接口,然后创建一个工厂类BirdFactory单独实现IAnimal接口获取Animal对象(Bird对象),Talk is cheap,show me the code:
public interface Animal {
/**
* 定义的统一接口
*/
void eat();
}
public interface IAnimal {
//抽象出来的接口,用来获取Animal
Animal getAnimal();
}
这样的话我们想要获取Dog
实例的话就直接创建一个DogFactory
:
public class Dog implements Animal {
@Override
public void eat() {
System.out.println("dog eat meat");
}
}
public class DogFactory implements IAnimal {
@Override
public Animal getAnimal() {
return new Dog();
}
}
想获取Cat
实例的话就直接创建一个CatFactory
:
public class Cat implements Animal {
@Override
public void eat() {
System.out.println("cat eat fish");
}
}
public class CatFactory implements IAnimal {
@Override
public Animal getAnimal() {
return new Cat();
}
}
或者你想获取一个Bird
的话,创建一个BirdFactory
:
public class Bird implements Animal {
@Override
public void eat() {
System.out.println("bird eat worm");
}
}
public class BirdFactory implements IAnimal {
@Override
public Animal getAnimal() {
return new Bird();
}
}
这么做的好处是不是很明显了,没有违反OCP原则,以后想添加一个对象,直接创建一个就可以了,扩展性也很好,我们测试一下:
public class Test {
public static void main(String[] args) {
System.out.println("抽象工厂方法模式:");
new DogFactory().getAnimal().eat();
new CatFactory().getAnimal().eat();
new BirdFactory().getAnimal().eat();
System.out.println("------------------");
}
}
抽象工厂方法模式: dog eat meat cat eat fish bird eat worm ------------------
总结
如果一个系统不依赖于对象是如何被创建,组合以及内部细节的表达时候,可以考虑使用工厂模式。