Java设计模式-创造设计模式

设计模式是面向对象开发中的最佳实践,如工厂模式用于对象创建,抽象工厂模式处理相关对象的工厂,单例模式保证类只有一个实例,Builder模式构建复杂对象,原型模式用于高效复制对象。这些模式提供通用解决方案,提升代码灵活性、可重用性和可维护性。
摘要由CSDN通过智能技术生成

设计模式代表有经验的面向对象软件开发人员使用的最佳实践。 设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。 这些解决方案是由许多软件开发人员在相当长的时间内通过试错获得的。

设计模式四人帮(GOF)是什么?

1994年,有四位作者:Erich GammaRichard HelmRalph JohnsonJohn Vlissides发表了一本题为《设计模式 - 可重用的面向对象软件元素》的图书,该书在软件开发中开创了设计模式的概念。

这些作者被统称为四人帮(GOF)。 根据这些作者,设计模式主要基于以下面向对象设计的原则:

  • 程序到一个接口不用实现。
  • 有利于对继承对象组合。

设计模式的使用

设计模式在软件开发中有两个主要用途。

开发人员的通用平台

设计模式提供了标准术语,并且特定于应用折场景。 例如,单例设计模式表示使用单个对象,所以熟悉单一设计模式的所有开发人员都将使用单个对象,并且他们可以告诉对方程序正在遵循单例模式。

最佳实践

设计模式已经经过一段很长的时间发展,它们为软件开发过程中面临的某些问题提供了最佳解决方案。 学习这些模式有助于无经验的开发人员以一种简单快捷的方式学习软件设计。

设计模式的类型

根据设计模式参考《设计模式 - 可重用的面向对象软件元素》一书中所述,一共有23种设计模式可以分为三类:创造模式,结构模式和行为模式。在这里我们还将讨论另一类设计模式:J2EE设计模式。

编号模式和说明
1创造模式 -这些设计模式提供了一种创建对象而隐藏创建逻辑的方法,而不是直接使用 new 操作符来实例化对象。 这使程序在决定对于给定的用例需要创建哪些对象时具有更大的灵活性。
2结构模式 - 这些设计模式涉及类和对象组成。 继承概念用于组成接口并定义方法组合对象以获得新功能。
3行为模式 - 这些设计模式是特别侧重于对象之间的通信。
4J2EE模式 - 这些设计模式特别涉及表示层。 这些模式由Sun Java Center标识。

另外,设计模式是与编程语言无关的,它是用于解决常见的面向对象的设计问题。
设计模式代表一个想法,而不是一个实现。
通过使用设计模式,可以使我们的代码更灵活,可重用和可维护。
Java本身内部遵循设计模式。

在核心java中,主要有三种类型的设计模式,它们可进一步分为以下子部分:

1. 创造设计模式

工厂模式

抽象工厂模式

单例模式

原型模式

Builder模式

2.结构设计模式

适配器(Adapter)模式

桥接(Bridge)模式

组合模式

装饰者(Decorator)模式

外观(Facade)模式

享元(Flyweight)模式

代理(Proxy)模式

3.行为设计模式

责任链模式

命令模式

解释器模式

迭代器模式

调解者(Mediator)模式

备忘录模式

观察者模式

状态模式

策略模式

模板模式

访问者模式

工厂设计模式

工厂模式是Java中最常用的设计模式之一。 这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方法之一。

在工厂模式中,我们没有创建逻辑暴露给客户端创建对象,并使用一个通用的接口引用新创建的对象。

实现方法

我们将创建一个Shape接口和实现Shape接口的具体类。 一个工厂类ShapeFactory会在下一步中定义。

FactoryPatternDemo这是一个演示类,将使用ShapeFactory来获取一个Shape对象。 它会将信息(CIRCLE/RECTANGLE/SQUARE)传递给ShapeFactory以获取所需的对象类型。

实现工厂模式的结构如下图所示 -

第1步

创建一个接口-

Shape.java

public interface Shape {
   void draw();
}

第2步

创建实现相同接口的具体类。如下所示几个类 -
Rectangle.java

public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Square.java

public class Square implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}

Circle.java

public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

第3步

创建工厂根据给定的信息生成具体类的对象。

ShapeFactory.java

public class ShapeFactory {

   //use getShape method to get object of type shape 
   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;
   }
}

第4步

使用工厂通过传递类型等信息来获取具体类的对象。

FactoryPatternDemo.java

public class FactoryPatternDemo {

   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();

      //get an object of Circle and call its draw method.
      Shape shape1 = shapeFactory.getShape("CIRCLE");

      //call draw method of Circle
      shape1.draw();

      //get an object of Rectangle and call its draw method.
      Shape shape2 = shapeFactory.getShape("RECTANGLE");

      //call draw method of Rectangle
      shape2.draw();

      //get an object of Square and call its draw method.
      Shape shape3 = shapeFactory.getShape("SQUARE");

      //call draw method of circle
      shape3.draw();
   }
}

第5步

验证输出结果如下-

Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.

抽象工厂模式

抽象工厂模式是一个超级工厂,用来创建其他工厂。 这个工厂也被称为工厂的工厂。 这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方法之一。

在抽象工厂模式中,接口负责创建相关对象的工厂,而不明确指定它们的类。 每个生成的工厂可以按照工厂模式提供对象。

实现实例

我们将创建一个ShapeColor接口并实现这些接口的具体类。在下一步中,将创建一个抽象工厂类AbstractFactory。在每个工厂类ShapeFactoryColorFactory定义都是扩展自AbstractFactory。创建工厂创建者/生成器类 - FactoryProducer

AbstractFactoryPatternDemo这是一个演示类,使用FactoryProducer来获取AbstractFactory对象。 它会将信息(CIRCLE / RECTANGLE / SQUARE)传递给AbstractFactory以获取所需的对象类型。 它还将信息(用于ColorRED / GREEN / BLUE)传递给AbstractFactory以获取所需的对象类型。

第1步

创建Shape的接口。

Shape.java

public interface Shape {
   void draw();
}

Java

第2步

创建实现相同接口的具体类。

Rectangle.java

public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Java

Square.java

public class Square implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}

Java

Circle.java

public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

Java

第3步

创建一个Colors接口,如下所示

Color.java

public interface Color {
   void fill();
}

Java

第4步

创建实现相同接口的具体类。

public class Red implements Color {

   @Override
   public void fill() {
      System.out.println("Inside Red::fill() method.");
   }
}

Java

Green.java

public class Green implements Color {

   @Override
   public void fill() {
      System.out.println("Inside Green::fill() method.");
   }
}

Java

Blue.java

public class Blue implements Color {

   @Override
   public void fill() {
      System.out.println("Inside Blue::fill() method.");
   }
}

Java

第5步

创建实现相同接口的具体类。

AbstractFactory.java

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

Java

第6步

创建实现相同接口的具体类。

创建工厂类,根据给定信息扩展AbstractFactory以生成具体类的对象。

ShapeFactory.java

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
   Color getColor(String color) {
      return null;
   }
}

Java

ColorFactory.java

public class ColorFactory extends AbstractFactory {

   @Override
   public Shape getShape(String shapeType){
      return null;
   }

   @Override
   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;
   }
}

Java

第7步

创建工厂生成器/生产器类,通过传递如ShapeColor等信息来获取工厂

FactoryProducer.java

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;
   }
}

Java

第8步

使用FactoryProducer来获取AbstractFactory,以便通过传递类型等信息来获取具体类的工厂。

AbstractFactoryPatternDemo.java

public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {

      //get shape factory
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");

      //get an object of Shape Circle
      Shape shape1 = shapeFactory.getShape("CIRCLE");

      //call draw method of Shape Circle
      shape1.draw();

      //get an object of Shape Rectangle
      Shape shape2 = shapeFactory.getShape("RECTANGLE");

      //call draw method of Shape Rectangle
      shape2.draw();

      //get an object of Shape Square 
      Shape shape3 = shapeFactory.getShape("SQUARE");

      //call draw method of Shape Square
      shape3.draw();

      //get color factory
      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");

      //get an object of Color Red
      Color color1 = colorFactory.getColor("RED");

      //call fill method of Red
      color1.fill();

      //get an object of Color Green
      Color color2 = colorFactory.getColor("Green");

      //call fill method of Green
      color2.fill();

      //get an object of Color Blue
      Color color3 = colorFactory.getColor("BLUE");

      //call fill method of Color Blue
      color3.fill();
   }
}

Java

第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.

单例模式

 

 

单例(Singleton)模式是Java中最简单的设计模式之一。这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方法之一。

这种模式涉及一个类,它负责创建一个对象,同时确保只创建一个对象。这个类提供了一种方法来访问它的唯一对象,可以直接访问,而不需要实例化类的对象。

实现实例

我们将创建一个单一对象类 - SingleObject。单个对象(SingleObject)类的构造函数是私有的,并且具有自身的静态实例。

SingleObject类提供了一个静态方法来获取其静态实例到外部世界。SingletonPatternDemo或示例类将使用SingleObject类来获取SingleObject对象。

第1步

创建一个Singleton类,

SingleObject.java

public class SingleObject {

   //create an object of SingleObject
   private static SingleObject instance = new SingleObject();

   //make the constructor private so that this class cannot be
   //instantiated
   private SingleObject(){}

   //Get the only object available
   public static SingleObject getInstance(){
      return instance;
   }

   public void showMessage(){
      System.out.println("Hello World!");
   }
}

Java

第2步

从单例类中获取唯一的对象。

SingletonPatternDemo.java

public class SingletonPatternDemo {
   public static void main(String[] args) {

      //illegal construct
      //Compile Time Error: The constructor SingleObject() is not visible
      //SingleObject object = new SingleObject();

      //Get the only object available
      SingleObject object = SingleObject.getInstance();

      //show the message
      object.showMessage();
   }
}

Java

第3步

验证输出,得到结果如下 -

Hello World!

建造者(Builder)模式

构建器(Builder)模式使用简单对象并使用逐步方法构建复杂对象。 这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方法之一。

构建器(Builder)模式构建器逐步构建最终对象,此构建器独立于其他对象。

实例实例

我们考虑了一家快餐店的商业案例,其中典型的餐点可能是汉堡和冷饮。 汉堡可以是一个素食汉堡或鸡肉汉堡,将被包装进行包装。 冷饮可以是一个可乐或百事将装放在一个瓶子中。

我们将创建一个Item接口,表示食品项目,如汉堡包和冷饮料以及实现Item接口的具体类。还有一个包装接口,表示食品包装和实现包装接口的具体类,因为汉堡包装在包装和冷饮将包装成瓶子。

然后创建一个具有ItemListListMealBuilderMeal类,通过组合Item来构建不同类型的Meal对象。 BuilderPatternDemo这是一个演示类将使用MealBuilder构建一个食品套餐。

第1步

创建两个接口分别代表食品和包装的项目(ItemPacking),如下所示 -

Item.java

public interface Item {
   public String name();
   public Packing packing();
   public float price();    
}

Java

Packing.java

public interface Packing {
   public String pack();
}

Java

第2步

创建实现Packing接口的具体类。如下代码所示 -

Wrapper.java

public class Wrapper implements Packing {

   @Override
   public String pack() {
      return "Wrapper";
   }
}

Java

Bottle.java

public class Bottle implements Packing {

   @Override
   public String pack() {
      return "Bottle";
   }
}

Java

第3步

创建抽象类实现Item接口提供默认功能。

Burger.java

public abstract class Burger implements Item {

   @Override
   public Packing packing() {
      return new Wrapper();
   }

   @Override
   public abstract float price();
}

Java

ColdDrink.java

public abstract class ColdDrink implements Item {

    @Override
    public Packing packing() {
       return new Bottle();
    }

    @Override
    public abstract float price();
}

Java

第4步

创建扩展汉堡(Burger)和冷饮(ColdDrink )类的具体类

VegBurger.java

public class VegBurger extends Burger {

   @Override
   public float price() {
      return 25.0f;
   }

   @Override
   public String name() {
      return "Veg Burger";
   }
}

Java

ChickenBurger.java

public class ChickenBurger extends Burger {

   @Override
   public float price() {
      return 50.5f;
   }

   @Override
   public String name() {
      return "Chicken Burger";
   }
}

Java

Coke.java

public class Coke extends ColdDrink {

   @Override
   public float price() {
      return 30.0f;
   }

   @Override
   public String name() {
      return "Coke";
   }
}

Java

Pepsi.java

public class Pepsi extends ColdDrink {

   @Override
   public float price() {
      return 35.0f;
   }

   @Override
   public String name() {
      return "Pepsi";
   }
}

Java

第5步

创建一个具有上面定义的Item对象的Meal类。

Meal.java

import java.util.ArrayList;
import java.util.List;

public class Meal {
   private List<Item> items = new ArrayList<Item>();    

   public void addItem(Item item){
      items.add(item);
   }

   public float getCost(){
      float cost = 0.0f;

      for (Item item : items) {
         cost += item.price();
      }        
      return cost;
   }

   public void showItems(){

      for (Item item : items) {
         System.out.print("Item : " + item.name());
         System.out.print(", Packing : " + item.packing().pack());
         System.out.println(", Price : " + item.price());
      }        
   }    
}

Java

第6步

创建一个MealBuilder类,这是一个实际的构建类负责创建Meal对象。

MealBuilder.java

public class MealBuilder {

   public Meal prepareVegMeal (){
      Meal meal = new Meal();
      meal.addItem(new VegBurger());
      meal.addItem(new Coke());
      return meal;
   }   

   public Meal prepareNonVegMeal (){
      Meal meal = new Meal();
      meal.addItem(new ChickenBurger());
      meal.addItem(new Pepsi());
      return meal;
   }
}

Java

第7步

BuiderPatternDemo类使用MealBuider对象来演示构建器模式。

BuilderPatternDemo.java

public class BuilderPatternDemo {
   public static void main(String[] args) {

      MealBuilder mealBuilder = new MealBuilder();

      Meal vegMeal = mealBuilder.prepareVegMeal();
      System.out.println("Veg Meal");
      vegMeal.showItems();
      System.out.println("Total Cost: " + vegMeal.getCost());

      Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
      System.out.println("\n\nNon-Veg Meal");
      nonVegMeal.showItems();
      System.out.println("Total Cost: " + nonVegMeal.getCost());
   }
}

Java

第8步

验证输出,执行上面代码得到如下结果 -

Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0


Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5


原型模式

原型模式指在创建重复对象的同时保持性能。 这种类型的设计模式属于创建模式,因为此模式提供了创建对象的最佳方法之一。

这个模式涉及实现一个原型接口,它只创建当前对象的克隆。有时直接创建对象时使用这种模式是昂贵的。例如,在昂贵的数据库操作之后创建对象。因此我们可以缓存对象,在下一个请求时返回其克隆,并在需要时更新数据库,从而减少数据库调用。

实现实例

我们将创建一个抽象类Shape和扩展Shape类的具体类。 在下一步中定义ShapeCache类,在Hashtable中存储形状(Shape)对象,并在请求时返回其克隆。

PrototypPatternDemo这是一个演示类,将使用ShapeCache类来获取一个Shape对象。实现结构图如下所示 -

第1步

创建一个实现Clonable接口的抽象类。

Shape.java

public abstract class Shape implements Cloneable {

   private String id;
   protected String type;

   abstract void draw();

   public String getType(){
      return type;
   }

   public String getId() {
      return id;
   }

   public void setId(String id) {
      this.id = id;
   }

   public Object clone() {
      Object clone = null;

      try {
         clone = super.clone();

      } catch (CloneNotSupportedException e) {
         e.printStackTrace();
      }

      return clone;
   }
}

Java

第2步

创建扩展上述类的具体类。

Rectangle.java

public class Rectangle extends Shape {

   public Rectangle(){
     type = "Rectangle";
   }

   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Java

Square.java

public class Square extends Shape {

   public Square(){
     type = "Square";
   }

   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}

Java

Circle.java

public class Circle extends Shape {

   public Circle(){
     type = "Circle";
   }

   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

Java

第3步

创建一个类来获取具体的类,并将它们存储在Hashtable中。

ShapeCache.java

import java.util.Hashtable;

public class ShapeCache {

   private static Hashtable<String, Shape> shapeMap  = new Hashtable<String, Shape>();

   public static Shape getShape(String shapeId) {
      Shape cachedShape = shapeMap.get(shapeId);
      return (Shape) cachedShape.clone();
   }

   // for each shape run database query and create shape
   // shapeMap.put(shapeKey, shape);
   // for example, we are adding three shapes

   public static void loadCache() {
      Circle circle = new Circle();
      circle.setId("1");
      shapeMap.put(circle.getId(),circle);

      Square square = new Square();
      square.setId("2");
      shapeMap.put(square.getId(),square);

      Rectangle rectangle = new Rectangle();
      rectangle.setId("3");
      shapeMap.put(rectangle.getId(), rectangle);
   }
}

Java

第4步

PrototypePatternDemo使用ShapeCache类来获取存储在Hashtable中的形状(shape)的克隆。

PrototypePatternDemo.java

public class PrototypePatternDemo {
   public static void main(String[] args) {
      ShapeCache.loadCache();

      Shape clonedShape = (Shape) ShapeCache.getShape("1");
      System.out.println("Shape : " + clonedShape.getType());        

      Shape clonedShape2 = (Shape) ShapeCache.getShape("2");
      System.out.println("Shape : " + clonedShape2.getType());        

      Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
      System.out.println("Shape : " + clonedShape3.getType());        
   }
}

Java

第5步

验证输出,执行上面的代码得到以下结果 -

Shape : Circle
Shape : Square
Shape : Rectangle

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值