设计模式(未完结)

在这里插入图片描述

一、创建型模式

1.工厂模式

在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。


1.1 介绍

  1. 意图:一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,其创建过程让类进行

  2. 解决:主要解决接口选择的问题

  3. 使用:计划不同条件下创建不同实例时

  4. 应用实例
    (1)您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。
    (2)Hibernate 换数据库只需换方言和驱动就可以。

  5. 优点:
    (1)一个调用者想创建一个对象,只要知道其名称就可以了。
    (2)扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
    (3)屏蔽产品的具体实现,调用者只关心产品的接口。

  6. 缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工 厂,使得系统中类的个数成倍增加,增加了系统的复杂度,增加了系统具体 类的依赖

  7. 使用场景
    (1)日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
    (2)数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。
    (3)设计一个连接服务器的框架,需要三个协议,“POP3”、“IMAP”、“HTTP”,可以把这三个作为产品类,共同实现一个接口。

  8. 注意:在任何需要生成复杂对象的地方,都可以使用工厂方法模式


1.2 实现

1.创建一个 Shape 接口和实现 Shape 接口的实体类
2.定义工厂类 ShapeFactory
3.类使用 ShapeFactory 来获取 Shape 对象

  1. 创建接口
public interface Shape {
   void draw();
}
  1. 创建实现接口的实体类
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}
public class Square implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}
public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}
  1. 创建一个工厂,生成基于给定信息的实体类的对象。
public class ShapeFactory {
    
   //使用 getShape 方法获取形状类型的对象
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
}
  1. 使用该工厂,通过传递类型信息来获取实体类的对象
public class FactoryPatternDemo {
 
   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();
 
      //获取 Circle 的对象,并调用它的 draw 方法
      Shape shape1 = shapeFactory.getShape("CIRCLE");
 
      //调用 Circle 的 draw 方法
      shape1.draw();
 
      //获取 Rectangle 的对象,并调用它的 draw 方法
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
      //调用 Rectangle 的 draw 方法
      shape2.draw();
 
      //获取 Square 的对象,并调用它的 draw 方法
      Shape shape3 = shapeFactory.getShape("SQUARE");
 
      //调用 Square 的 draw 方法
      shape3.draw();
   }
}
  1. 输出结果
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.

2.抽象工厂模式

接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象


2.1 介绍

  1. 意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

  2. 解决:主要解决接口选择的问题

  3. 使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品

  4. 如何解决:在一个产品族里面,定义多个产品

  5. 关键代码:在一个工厂里聚合多个同类产品。

  6. 应用实例: 工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OOP 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。

  7. 优点: 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

  8. 缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码

  9. 使用场景
    (1)QQ 换皮肤,一整套一起换。
    (2) 生成不同操作系统的程序。

  10. 注意:产品族难扩展,产品等级易扩展。


2.2 实现

1.将创建 Shape 和 Color 接口和实现这些接口的实体类
2.创建抽象工厂类 AbstractFactory
3.定义工厂类 ShapeFactory 和 ColorFactory都继承 AbstractFactory
4.创建一个工厂创造器/生成器类 FactoryProducer
5.使用 FactoryProducer 来获取 AbstractFactory 对象
6.向 AbstractFactory 传递形状信息 Shape(以便获取它所需对象的类型。同时它还向 AbstractFactory 传递颜色信息 Color(RED / GREEN / BLUE),以便获取它所需对象的类型。

1.为形状创建一个接口

public interface Shape {
   void draw();
}

2.创建实现接口的实体类

public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}
public class Square implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}
public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

3.为颜色创建一个接口

public interface Color {
   void fill();
}

4.创建实现接口的实体类

public class Red implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Red::fill() method.");
   }
}
public class Green implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Green::fill() method.");
   }
}
public class Blue implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Blue::fill() method.");
   }
}

5.为 Color 和 Shape 对象创建抽象类来获取工厂

public abstract class AbstractFactory {
   public abstract Color getColor(String color);
   public abstract Shape getShape(String shape) ;
}

6.创建扩展了 AbstractFactory 的工厂类,基于给定的信息生成实体类的对象

public class ShapeFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      return null;
   }
}
public class ColorFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      if(color == null){
         return null;
      }        
      if(color.equalsIgnoreCase("RED")){
         return new Red();
      } else if(color.equalsIgnoreCase("GREEN")){
         return new Green();
      } else if(color.equalsIgnoreCase("BLUE")){
         return new Blue();
      }
      return null;
   }
}

7.创建一个工厂创造器/生成器类,通过传递形状或颜色信息来获取工厂

public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
      if(choice.equalsIgnoreCase("SHAPE")){
         return new ShapeFactory();
      } else if(choice.equalsIgnoreCase("COLOR")){
         return new ColorFactory();
      }
      return null;
   }
}

8.使用 FactoryProducer 来获取 AbstractFactory,通过传递类型信息来获取实体类的对象

public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {
 
      //获取形状工厂
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
 
      //获取形状为 Circle 的对象
      Shape shape1 = shapeFactory.getShape("CIRCLE");
 
      //调用 Circle 的 draw 方法
      shape1.draw();
 
      //获取形状为 Rectangle 的对象
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
      //调用 Rectangle 的 draw 方法
      shape2.draw();
      
      //获取形状为 Square 的对象
      Shape shape3 = shapeFactory.getShape("SQUARE");
 
      //调用 Square 的 draw 方法
      shape3.draw();
 
      //获取颜色工厂
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
 
      //获取颜色为 Red 的对象
      Color color1 = colorFactory.getColor("RED");
 
      //调用 Red 的 fill 方法
      color1.fill();
 
      //获取颜色为 Green 的对象
      Color color2 = colorFactory.getColor("Green");
 
      //调用 Green 的 fill 方法
      color2.fill();
 
      //获取颜色为 Blue 的对象
      Color color3 = colorFactory.getColor("BLUE");
 
      //调用 Blue 的 fill 方法
      color3.fill();
   }
}

9.输出结果

Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.

3.单例模式

  • 单例类只能有一个实例
  • 单例类必须自己创建自己的唯一实例
  • 单例类必须给所有其他对象提供这一实例

3.1 介绍

  1. 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点
  2. 解决:一个全局使用的类频繁地创建与销毁
  3. 使用:控制实例数目,节省系统资源
  4. 如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建
  5. 关键代码:构造函数私有
  6. 应用实例
  • 一个班级只有一个班主任。

  • Windows
    是多进程多线程的,在操作一个文件的时候,就不可避免地出现多个进程或线程同时操作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。

  • 一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。

  1. 优点
  • 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)

  • 避免对资源的多重占用(比如写文件操作)

  1. 缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

  2. 使用场景:

  • 要求生产唯一序列号。
  • 、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
  • 创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

10.注意事项:getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。

3.2 实现

1.SingleObject 类有它的私有构造函数和本身的一个静态实例,提供了一个静态方法,供外界获取它的静态实例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值