设计模式学习笔记
面向对象六大设计原则
开闭原则
- Open Closed Principle
- 核心思想:对扩展开放,对修改关闭
- 也就是说,对已经使用的类的改动是通过增加代码进行的,而不是修改现有代码
单一职责原则
- Single Responsibility Principle
- 高内聚、低耦合
- 每个类只有一个职责,对外只提供一种功能,而引起变化的原因应只有一个
- 在设计模式中, 所有的设计模式都遵循这一原则
里式替换原则
- Liskov Substitution Principle
- 核心思想:在任何父类出现的地方都可以用它的子类来替换(多态)
- 也就是说,同一个继承体系中的对象应该有共同的行为特征
- 总结:只要是子类中想被其它类调用的方法,都需要在父类或者接口中出现
依赖倒转原则
- Dependency Inversion Principle
- 核心思想:要依赖抽象和接口,不要依赖于具体实现
- 其实就是说:在应用程序中,所有的类如果使用或依赖于其他的类,则应该依赖这些其他类的抽象类或者接口,而不是直接依赖这些其他类的具体类。
- 为了实现这一原则,就要求我们在编程的时候针对抽象类或者接口编程,而不是针对具体实现编程。
接口分离原则
- Interface Segregation Principle
- 核心思想:不应该强迫程序依赖它们不需要使用的方法
- 其实就是说:一个接口不需要提供太多行为,一个接口应该只提供一种对外的功能,不应该把所有操作都封装到一个接口中
迪米特原则
- Principle of Least Knowledge,也叫:最少认知原则
- 核心思想:一个对象应当对其他对象尽可能少的了解
- 其实就是说:降低各个对象之间的耦合,提高系统的可维护性。在模块之间应该只通过接口编程,而不理会模块的内部工作原理,它可以使各个模块耦合度降到最低,促进软件的复用
认识设计模式
设计模式概述
- 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。
- 设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案,这些方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
- 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
- 设计模式不是一种方法和技术,而是一种思想。
- 设计模式和具体的语言无关,学习设计模式就是要建立面向对象的思想,尽可能的面向接口编程,低耦合,高内聚,使设计的程序可复用。
- 学习设计模式能够促进对面向对象思想的理解,反之亦然。它们相辅相成。
设计模式的类型
总体来说,设计模式分为三类23种:
- 创建型(5种):工厂模式(简单工厂、工厂方法)、抽象工厂模式、单例模式、原型模式、构建者模式
- 结构型(7种):适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式
- 行为型(11种):模板方法模式、策略模式、观察者模式、中介者模式、状态模式、责任链模式、命令模式、迭代器模式、访问者模式、解释器模式、备忘录模式
JavaEE设计模式:MVC、委托模式
设计模式
创建型
工厂模式
简单工厂模式
- 简单工厂模式包含3个角色:SimpleFactory(简单工厂)、AbstractProduct(抽象产品)和ConcreteProduct(具体产品),工厂拥有一个工厂方法(create),接收一个参数,通过不同的参数实例化不同的产品类。
- 图示
- 优点:很明显,“简单粗暴”,通过一个含参的工厂方法,可以实例化任何产品,上至飞机火箭、下至土豆面条,无所不能。简单工厂又名:上帝类,上帝工厂。
- 缺点:任何东西的子类都可以被生产,负担太重。当需要生产的产品种类非常多时,工厂方法的代码量可能会很庞大。在遵循开闭原则的条件下,简单工厂对于增加新产品,无能为力,因为增加新产品只能通过修改工厂方法来实现。
- 代码示例:
/**
* 抽象产品类
*/
public abstract class Product {
// 所有产品类的公共业务方法
public void methodSame(){
// 公共方法具体实现
}
// 声明抽象业务方法
public abstract void methodDiff();
}
/**
* 具体产品A
*/
public class ConcreteProductA extends Product {
@Override
public void methodDiff() {
System.out.println("ConcreteProductA");
}
}
/**
* 具体产品B
*/
public class ConcreteProductB extends Product {
@Override
public void methodDiff() {
System.out.println("ConcreteProductB");
}
}
/**
* 产品类型
*/
public class ProductTypes {
final static String TYPE_A = "A";
final static String TYPE_B = "B";
}
/**
* 普通-简单工厂
*/
public class PlainSimpleFactory {
public static Product create(String type){
Product product = null;
if(type.equalsIgnoreCase(ProductTypes.TYPE_A)){
product = new ConcreteProductA();
}else if(type.equalsIgnoreCase(ProductTypes.TYPE_B)){
product = new ConcreteProductB();
}
return product;
}
}
/**
* 静态方法-简单工厂
*/
public class StaticSimpleFactory {
public static ConcreteProductA createA(){
return new ConcreteProductA();
}
public static ConcreteProductB createB(){
return new ConcreteProductB();
}
}
/**
* 测试
*/
public class Test {
public static void main(String[] args) {
Product productA1 = PlainSimpleFactory.create(ProductTypes.TYPE_A);
productA1.methodDiff();
Product productB1 = PlainSimpleFactory.create(ProductTypes.TYPE_B);
productB1.methodDiff();
Product productA2 = StaticSimpleFactory.createA();
productA2.methodDiff();
Product productB2 = StaticSimpleFactory.createB();
productB2.methodDiff();
}
}
工厂方法模式
- 工厂方法是针对每一种产品提供一个工厂类,通过不同的工厂实例来创建不同的产品实例
- 工厂方法模式包含4个角色:AbstractProduct(抽象产品)、ConcreteProduct(具体产品)、FactoryMethod(工厂方法接口)和ConcreteFactory(具体工厂)
- 图示
- 优点:很好地减轻了工厂类的负担,把某一类/某一种东西交由一个工厂生产;同时增加某一类东西并不需要修改工厂类,只需要添加生产这类东西的工厂即可,使得工厂类符合开闭原则
- 缺点:对于某些可以形成产品族的情况处理比较复杂
- 示例代码:
/**
* 方法工厂接口
*/
public interface MethodFactory {
public Product create();
}
/**
* 具体的方法工厂A
*/
public class ConcreteFactoryA implements MethodFactory {
@Override
public Product create() {
return new ConcreteProductA();
}
}
/**
* 具体的方法工厂B
*/
public class ConcreteFactoryB implements MethodFactory {
@Override
public Product create() {
return new ConcreteProductB();
}
}
/**
* 测试
*/
public class Test {
public static void main(String[] args) {
MethodFactory factoryA = new ConcreteFactoryA();
Product productA = factoryA.create();
productA.methodDiff();
MethodFactory factoryB = new ConcreteFactoryB();
Product productB = factoryB.create();
productB.methodDiff();
}
}
抽象工厂模式
- 抽象工厂是应对产品族概念的,上边的工厂方法模式是一种极端情况下的抽象工厂模式(即只生产一种产品的抽象工厂模式),而抽象工厂模式可以看成是工厂方法模式的一种推广。
- 图示:
- 抽象工厂模式包含4个角色:AbstractProduct(抽象产品,有多个)、ConcreteProduct(具体产品)、AbstractFactory(抽象工厂接口)和ConcreteFactory(具体工厂)
- 示例代码
/**
* 抽象产品A
*/
public abstract class ProductA {
// 所有产品类的公共业务方法
public void methodSame(){
// 公共方法具体实现
}
// 声明抽象业务方法
public abstract void methodDiff();
}
/**
* 抽象产品B
*/
public abstract class ProductB {
// 所有产品类的公共业务方法
public void methodSame(){
// 公共方法具体实现
}
// 声明抽象业务方法
public abstract void methodDiff();
}
/**
* 具体产品A1
*/
public class ConcreteProductA1 extends ProductA {
@Override
public void methodDiff() {
System.out.println("ConcreteProductA1");
}
}
/**
* 具体产品A2
*/
public class ConcreteProductA2 extends ProductA {
@Override
public void methodDiff() {
System.out.println("ConcreteProductA2");
}
}
/**
* 具体产品B1
*/
public class ConcreteProductB1 extends ProductB {
@Override
public void methodDiff() {
System.out.println("ConcreteProductB1");
}
}
/**
* 具体产品B2
*/
public class ConcreteProductB2 extends ProductB {
@Override
public void methodDiff() {
System.out.println("ConcreteProductB2");
}
}
/**
* 抽象工厂
*/
public interface AbstractFactory {
ProductA createA();
ProductB createB();
}
/**
* 具体工厂1
*/
public class ConcreteFactory1 implements AbstractFactory {
@Override
public ProductA createA() {
return new ConcreteProductA1();
}
@Override
public ProductB createB() {
return new ConcreteProductB1();
}
}
/**
* 具体工厂2
*/
public class ConcreteFactory2 implements AbstractFactory {
@Override
public ProductA createA() {
return new ConcreteProductA2();
}
@Override
public ProductB createB() {
return new ConcreteProductB2();
}
}
/**
* 测试
*/
public class Test {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
ProductA productA = factory1.createA();
productA.methodDiff();
ProductB productB = factory1.createB();
productB.methodDiff();
AbstractFactory factory2 = new ConcreteFactory2();
productA = factory2.createA();
productA.methodDiff();
productB = factory2.createB();
productB.methodDiff();
}
}
构建者模式
- 将一个复杂的对象的构造与它的表示分离,使同样的构造过程可以创建不同的表示。
- 构建者模式包含4个角色:AbstractBuilder(抽象构建者)、ConcreteBuilder(具体构建者)、Product(产品)和Director(指挥者)
- 图示:
- 示例代码
/**
* 产品类
*/
public class Product {
// 定义产品的各个部件
private String partA;
private String partB;
private String partC;
public String getPartA() {
return partA;
}
public void setPartA(String partA) {
this.partA = partA;
}
public String getPartB() {
return partB;
}
public void setPartB(String partB) {
this.partB = partB;
}
public String getPartC() {
return partC;
}
public void setPartC(String partC) {
this.partC = partC;
}
@Override
public String toString() {
return "Product [partA=" + partA + ", partB=" + partB + ", partC=" + partC + "]";
}
}
/**
* 构建者接口
*/
public interface Builder {
Builder buildPartA();
Builder buildPartB();
Builder buildPartC();
Product build();
}
/**
* 具体构建者
*/
public class ConcreteBuilder implements Builder {
private