# 设计模式

Posted MarlonBrando1998

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了# 设计模式相关的知识,希望对你有一定的参考价值。

设计模式

设计模式总览


单例模式

类图

定义

一个类只有一个实例,该类能自己创建该类的一个实例。

特点

  • 单例类只有一个实例对象。
  • 单例对象必须由该类自己创建。
  • 单例类对外提供一个访问该单例的全局访问点。

单例模式的实现方式

  • 懒汉模式:加载类的时候没有生成单例模式,调用生成实例对象的方法的时候创建单例。
public class LazySingleton 

    //保证lazySingleton在线程中同步
    private static volatile LazySingleton lazySingleton = null;
    //保证类不在别的地方被实例化
    private LazySingleton() 
    
    //synchronize保证线程安全
    public static synchronized LazySingleton getInstance() 
        if (lazySingleton == null) 
            lazySingleton = new LazySingleton();
        
        return lazySingleton;
    

  • 饿汉模式:类一旦加载就创建一个单例。创建的这个对象之后就不会再改变,所以是线程安全的。
public class HungrySingleton 
    private static final HungrySingleton hungrySingleton = new HungrySingleton();
    private HungrySingleton() 
    
    public static HungrySingleton getInstance() 
        return hungrySingleton;
    

工厂模式

类图

定义

对象的实际创建工作推迟到子类当中。

特点

  • 用户主需要知道工厂的名称,则可得到对应的产品,无需知道产品的创建过程。
  • 系统增加产品时只需添加具体产品类和对应的具体工厂类,无需对原工厂进行修改。
  • 每增加一个产品就得增加一个具体产品类和和一个对应的具体工厂类。

实现方式

  • 提供产品的接口
public interface Product 
    public void show();

  • 具体产品1实现产品接口
public class ProductImpl1 implements Product 
    @Override
    public void show() 
        System.out.println("我生产了1");
    

  • 具体产品2实现产品接口
public class ProductImpl2 implements Product 
    @Override
    public void show() 
        System.out.println("我生产了2");
    

  • 抽象工厂,提供生成产品的方法
public interface AbstractFactory 
    public Product getInstance();

  • 实现产品生成
public class FactoryTest 
    public static void main(String[] args) 
        CreateFactory1 createFactory1 = new CreateFactory1();
        createFactory1.getInstance();
        CreateFactory2 createFactory2 = new CreateFactory2();
        createFactory2.getInstance();
    
    static class CreateFactory1 implements AbstractFactory 
        @Override
        public Product getInstance() 
            System.out.println("工厂1生产产品");
            ProductImpl1 productImpl1 = new ProductImpl1();
            productImpl1.show();
            return productImpl1;
        
    
    static class CreateFactory2 implements AbstractFactory 
        @Override
        public Product getInstance() 
            System.out.println("工厂2生产产品");
            ProductImpl2 productImpl2 = new ProductImpl2();
            productImpl2.show();
            return productImpl2;
        
    

抽象工厂模式

类图

定义

是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。

特点

  • 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
  • 当增加一个新的产品族时不需要修改原代码。

实现方式

  • 形状类以及具体的图形
public interface Shape 
    /**
     * 画形状
     */
    void draw();

public class Rectangle implements Shape 

    private static final Logger logger = LoggerFactory.getLogger(Rectangle.class);

    public static final String SHAPE = "rectangle";

    @Override
    public void draw() 
        logger.info("我是长方形");
    

public class Square implements Shape 

    private static final Logger logger = LoggerFactory.getLogger(Square.class);

    public static final String SHAPE = "square";

    @Override
    public void draw() 
        logger.info("我是矩形");
    


  • 颜色以及具体的颜色
public interface Color 
    /**
     * 填充颜色
     */
    void fill();

public class Green implements Color 

    private static final Logger logger = LoggerFactory.getLogger(Green.class);


    public static final String COLOR = "green";

    @Override
    public void fill() 
        logger.info("填充绿色");
    

public class Red implements Color 

    private static final Logger logger = LoggerFactory.getLogger(Red.class);

    public static final String COLOR = "red";

    @Override
    public void fill() 
        logger.info("填充红色");
    

  • 得到颜色和形状的抽象工厂
public abstract class AbstractFactory 

    public abstract Color getColor(String color);
    public abstract Shape getShape(String shape);


  • 得到具体颜色、具体形状的方法
public class ColorFactory extends AbstractFactory 

    public static final String TYPE = "color";

    @Override
    public Color getColor(String color) 
        if (color == null) 
            return null;
         else if (Red.COLOR.equalsIgnoreCase(color)) 
            return new Red();
         else if (Green.COLOR.equalsIgnoreCase(color)) 
            return new Green();
        
        return null;
    

    @Override
    public Shape getShape(String shape) 
        return null;
    

public class ShapeFactory extends AbstractFactory 

    public static final String TYPE = "shape";

    @Override
    public Color getColor(String color) 
        return null;
    

    @Override
    public Shape getShape(String shape) 
        if (shape == null) 
            return null;
        
        if (Rectangle.SHAPE.equalsIgnoreCase(shape)) 
            return new Rectangle();
         else if (Square.SHAPE.equalsIgnoreCase(shape)) 
            return new Square();
        
        return null;
    

  • 得到颜色或者形状的工厂
public class FactoryProducer 

    /**
     * 获取工厂实例
     *
     * @param type 工厂类型
     * @return AbstractFactory
     */
    public static AbstractFactory getFactoryInstance(String type) 
        if (ShapeFactory.TYPE.equalsIgnoreCase(type)) 
            return new ShapeFactory();
         else if (ColorFactory.TYPE.equalsIgnoreCase(type)) 
            return new ColorFactory();
        
        return null;
    

  • 根据传入的东西判断得到具体的形状或者具体的颜色
public static void main(String[] args) 
    //获取形状工厂
    AbstractFactory shape = FactoryProducer.getFactoryInstance("shape");

    Shape rectangle = Objects.requireNonNull(shape).getShape("rectangle");
    rectangle.draw();

    Shape square = shape.getShape("square");
    square.draw();

    // 获取颜色工厂
    AbstractFactory colorFactory = FactoryProducer.getFactoryInstance("COLOR");
    Color color1 = Objects.requireNonNull(colorFactory).getColor("RED");
    color1.fill();


观察者模式

类图

简单理解

  • 观察者模式是一种行为性模式,定义对象之间的一对多的依赖关系,当一个对象状态改变时候依赖于它的对象的状态会相应的更新。

使用场景

  • 关联行为场景,关联行为是可拆分的,事件多级触发。
  • 消息队列、时间总线处理机制。
  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制

实例代码

  • 抽象类定义观察者共同的方法
public abstract class Observer 

    protected Subject subject;

    /**
     * 通知观察者状态
     */
    public abstract void update();



  • 定义具体的观察者
public class ObserverOne extends Observer 

    private static final Logger logger = LoggerFactory.getLogger(ObserverOne.class);

    public ObserverOne(Subject subject) 
        this.subject = subject;
        this.subject.attach(this);
    

    @Override
    public void update() 
        logger.info("ObserverOne 收到通知!");
    


public class ObserverTwo extends Observer

    private static final Logger logger = LoggerFactory.getLogger(ObserverTwo.class);

    public ObserverTwo(Subject subject) 
        this.subject = subject;
        this.subject.attach(this);
    

    @Override
    public void update() 
        logger.info("ObserverTwo 收到通知!");
    


  • 定义主题
public class Subject 

    /**
     * 定义观察者的集合 使用vector 线程安全
     */
    private final Vector<Observer> observerList = new Vector<>();

    private int state;

    /**
     * 注册观察者
     *
     * @param observer 观察者
     */
    public void registerObserver(Observer observer) 
        observerList.add(observer);
    

    /**
     * 通知所有的观察者
     */
    public void notifyAllObservers() 
        for (Observer observer : observerList) 
            observer.update();
        
    

    public int getState() 
        return state;
    

    public void setState(int state) 
        this.state = state;
        notifyAllObservers();
    

  • 测试代码
public class AppTest 

    private static final Logger logger = LoggerFactory.getLogger(AppTest.class);

    @Test
    public void test() 
        Subject subject = new Subject();

        new ObserverOne(subject);
        new ObserverTwo(subject);

        logger.info("第一次状态改变:12");
        subject.setState(12);

        logger.info("第二次状态改变:8");
        subject.setState(8);
    



策略模式

类图

简单理解

  • 在接口中定义方法,不同的实现类在重写的方法中做出不同的操作。

使用场景

  • 当符合场景时候可以替换if、else

实例代码

  • 策略接口
public interface Strategy 

    /**
     * 计算数值
     *
     * @param num1 num1
     * @param num2 num2
     * @return int
     */
    int calculate(int num1, int num2);


  • 策略实现类
public class CalculateAdd implements Strategy 

    @Override
    public int calculate(int num1, int num2) 
        return num1 + num2;
    


public class CalculateSub implements Strategy 

    @Override
    public int calculate(int num1, int num2) 
        return num1 - num2;
    


  • 控制类
public class Context 

    private Strategy strategy;

    public Context(Strategy strategy) 
        this.strategy = strategy;
    

    public int executeStrategy(int num1, int num2) 
        return strategy.calculate(num1, num2);
    


  • 测试类
public class AppTest 


    private static final Logger logger = LoggerFactory.getLogger(AppTest.class);

    @Test
    public void test()
        Context context = new Context(new CalculateAdd());
        int i = context.executeStrategy(1, 2);
        logger.info(String.valueOf(i));

        context = new Context(new CalculateSub());
        int i1 = context.executeStrategy(2, 3);
        logger.info(String.valueOf(i1));
    



模板方法模式

类图

简单理解

  • 在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

实例代码

  • 抽象父类
public abstract class AbstractCookMeal 

    // 去市场
    abstract void moveToMarket();

    // 购买蔬菜
    abstract void buyVegetables();

    // 回家
    abstract void goHome();

    // 做饭
    abstract void cookMeal();


    public void doCooking抽象工厂模式的优缺点和适用场景

PHP设计模式抽象工厂模式(Abstract Factory For PHP)

抽象工厂模式

抽象工厂模式

Java设计模式——抽象工厂模式

一天一个设计模式:抽象方法模式