设计模式 和面向对象设计原则 ~

一、设计模式概述

        设计模式(Design Pattern)是人们在长期的软件开发中对一些经验的总结,是对某些特定问题经过实践检验的特定解决方法。就像兵法中的36计~

       那么什么是设计模式?

         设计模式使我们可以更简单方便得复用成功的设计和体系结构。将已经证实的技术方案总结成设计模式,也会使其开发者更容易理解其中的设计思路。设计模式是可复用的面向对象软件的基础,可以提供多种选择,避免损害系统复用性的设计。简而言之,设计模式可以 帮助我们更快、更好的完成系统设计。

二、软件可复用问题和面向对象设计原则

1.单一职责

单一职责 要求          实现类时要职责单一

2.开闭原则

开闭原则 要求         对扩展开放、对修改关闭

3.里氏替换原则

里氏替换原则  要求         继承体系的合理性

4.依赖倒置原则

依赖倒置原则 要求         面相接口编程  

5.接口隔离原则

接口隔离原则 要求         接口设计精简单一

6.迪米特法则

迪米特法则 要求         减少不必要的中间过程依赖

7.合成复用原则

合成复用原则 要求         多用组合/聚合、少用继承

三、单例模式(Singleton Pattern)


单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

1、静态内类

特点:效果类似DCL,只适用于静态域

   private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton (){}
    public static final Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }


2、 枚举

特点:自动支持序列化机制,绝对防止多次实例化

public enum Singleton {
    INSTANCE;
}


 

3、反射

             // 通过反射加载 Person 的方法
            Class clz = Class.forName("com.bdqn.ch01.Sl.Person");

            // 根据方法名和参数列表获取 static final int getAge 方法
            Method getAge = clz.getDeclaredMethod("getAge",null);

            //  getAge  的方法 default(package) , 这里已经超出其访问范围 ,不能直接访问
            // 通过 setAccessible 方法 可以访问到
            getAge.setAccessible(true);
            Object returnAge = getAge.invoke(null,null);
            System.out.println("年龄是:" + returnAge);

            Object person = clz.getDeclaredMethod("silentMethod",null);

            Method silentMethod = clz.getDeclaredMethod("silentMethod",null);
            silentMethod.setAccessible(true);
            silentMethod.invoke(person,null);

            Method setName = clz.getDeclaredMethod("setName", String.class);
            setName.invoke(person,"new Person");
            Object returnName = clz.getDeclaredMethod("getName").invoke(person);
            System.out.println("刚才设定的name是:"+returnName);
   // 使用反射创建对象
    // 加一个static变为静态工厂
    public static Coffee create(Class<? extends Coffee> clazz) throws Exception {
        if (clazz != null) {
            return clazz.newInstance();
        }
        return null;
    }


4、优点:

在内存中只有一个实例,减少了内存开销。
可以避免对资源的多重占用。
设置全局访问点,严格控制访问。


5、缺点:

没有接口,扩展困难。
如果要扩展单例对象,只有修改代码,没有其它途径。

四、工厂方法模式(Factory Method)


2.1 简单工厂模式

简单工厂模式不是23种设计模式之一,他可以理解为工厂模式的一种简单的特殊实现。

2.2工厂模式

工厂方法模式是指定义一个创建对象的接口,让实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行

工厂方法模式主要有以下几种角色:

抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。


具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。


抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。


具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它和具体工厂之间一一对应。

 


/**
 * NewsDao
 * 首先定义新闻模块的DAO接口
 * @aurhor Administrator   
 * @since 2024/7/1
 */
public interface NewsDao {

    /**
     * 保存新闻信息的方法
     */
    public void save(News news);
}


/**
 * NewsDaoMySqlImpl
 * 然后写实现类
 * @aurhor Administrator   
 * @since 2024/7/1
 */
public class NewsDaoMySqlImpl implements NewsDao {
    private Logger logger = Logger.getLogger(NewsDaoMySqlImpl.class);
    /**
     * 保存新闻信息的方法
     *
     * @param news
     */
    @Override
    public void save(News news) {
        logger.debug("保存信息到数据库");

    }
}

/**
 * NewsServiceImplTest
 *
 * @aurhor Administrator   
 * @since 2024/7/1
 */
public class NewsServiceImplTest {

    public void addNews() throws Exception{
  
        News news = new News();
        news.setnTitle("测试标题2");
        news.setnContent("测试内容2");
        service.addNews(news);
    }
}


基础版是最基本的简单工厂的写法,传一个参数过来,判断是什么类型的产品,就返回对应的产品类型。但是这里有一个问题,就是参数是字符串的形式,这就很容易会写错,比如少写一个字母,或者小写写成了大写,就会无法得到自己想要的产品类了,同时如果新加了产品,还得在工厂类的创建方法中继续加if.

 

工厂类负责创建的对象较少。
客户端只需要传入工厂类的参数,对于如何创建的对象的逻辑不需要关心。


优点:

只需要传入一个正确的参数,就可以获取你所需要的对象,无须知道创建的细节。


缺点:

工厂类的职责相对过重,增加新的产品类型的时需要修改工厂类的判断逻辑,违背了开闭原则。
不易于扩展过于复杂的产品结构。

适用场景:

创建对象需要大量的重复代码。
客户端(应用层)不依赖于产品类实例如何被创建和实现等细节。
一个类通过其子类来指定创建哪个对象。

2.3 总结:

优点:

用户只需要关系所需产品对应的工厂,无须关心创建细节。
加入新产品符合开闭原则,提高了系统的可扩展性。


缺点:

类的数量容易过多,增加了代码结构的复杂度。
增加了系统的抽象性和理解难度。


3.抽象工厂模式(Abstract Factory)


抽象工厂模式是指提供一个创建一系列相关或相互依赖对象的接口,无须指定他们具体的类。

 工厂方法模式中考虑的是一类产品的生产,如电脑厂只生产电脑,电话厂只生产电话,这种工厂只生产同种类的产品,同种类产品称为同等级产品,也就是说,工厂方法模式只考虑生产同等级的产品,但是现实生活中许多工厂都是综合型工厂,能生产多等级(种类)的产品,如上面说的电脑和电话,本质上他们都属于电器,那么他们就能在电器厂里生产出来,而抽象工厂模式就将考虑多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族,如上图所示纵轴是产品等级,也就是同一类产品;横轴是产品族,也就是同一品牌的产品,同一品牌的产品产自同一个工厂。

抽象工厂模式的主要角色如下:

抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。


4.原型模式(Prototype)


原型模式是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。调用者不需要知道任何创建细节,不调用构造函数。

原型模式包含如下角色:

抽象原型类:规定了具体原型对象必须实现的的 clone() 方法。
具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
访问类:使用具体原型类中的 clone() 方法来复制新的对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值