设计模式(Design Patterns)是在软件开发中经过验证的最佳实践,用于解决常见的设计问题。它们提供了一种可复用的解决方案,可以帮助开发人员提高代码质量、可维护性和可重用性。设计模式的采用通常在以下情况下被考虑:
1.代码重用性:当您发现多个地方有相似的代码结构或逻辑时,可以考虑使用设计模式来提取这些共通的部分,以提高代码的重用性。
2.扩展性:当系统需要支持未来的扩展或修改时,设计模式可以帮助您构建灵活和可扩展的架构。
3.可维护性:设计模式通常使代码结构更清晰、易于理解,这有助于提高代码的可维护性。通过遵循设计模式的最佳实践,可以使代码更易于阅读、调试和修改。
4.解决复杂问题:当面对复杂的设计问题时,如对象间通信、资源管理、并发控制等,设计模式提供了一种经过验证的解决方案。
5.团队协作:在团队开发环境中,使用设计模式可以提高代码的一致性和可维护性,促进团队成员之间的沟通和协作。
6.适应变化:当软件需求经常发生变化时,设计模式可以帮助您构建更加灵活和适应变化的系统。
需要注意的是,虽然设计模式在软件开发中很有用,但过度使用或不当地使用它们也可能导致代码过度复杂化和难以理解。那怎样定义过度使用呢,遵循事不过三的原则即可,只有没有重复的代码或者方法有三个的时候就不用优化。
在之前的工作经历中我有过多次使用设计模式的经历,一次是使用工厂和策略两种设计模式统一接口完成多端多业务类型多类型页面资源,减少了接口数量和开发成本,完成了查询广告页面的组件化,当时面临的问题是有多种类型的app,app上有不同的页面,不同页面根据不同的业务或者标识去数据库里面查询配置的不同的页面,但是我们页面的数据逻辑又在其他系统,我们只能在自己系统内完成这样的筛选逻辑,在当时要么根据不同的客户端开放不同的接口,要么根据不同的业务类型开放不同的接口,那这样肯定会随着端的增多或者业务类型的增多会产生接口爆炸的情况,要么就是在一个接口内完成大量的判断来完成这样的逻辑,那有没有可能借助设计模式来解决呢?当时我就在寻找相关的案例,最后觉得工厂模式和策略模式的结合是很好的方式,简单工厂模式的作用是提供专门的工厂类用于创建对象,实现了对象创建和使用的职责分离,客户端不需知道所创建的具体产品类的类名以及创建过程,只需要知道具体产品类所对应的参数即可。
这样不正是拟合了根据上送和客户端参数创建多端工厂的场景吗?而策略模式是把具体的算法实现从业务逻辑中剥离出来,成为一系列独立算法类,使得它们可以相互替换。那也正好拟合了我们根据上送的业务类型和页面类型寻找不同处理类的场景
*
下面我来展示一个简化版本根据的demo,方便大家理解的。
客户端
@SpringBootTest
public class ApplicationTest {
@Autowired
ClientFactory clientFactory;
@Test
public void test() {
String result1 = clientFactory.getClient("wechat").getResult();
System.out.println("-----------------");
System.out.println(result1);
String result2 = clientFactory.getClient("alipay").getResult();
System.out.println("-----------------");
System.out.println(result2);
}
}
创建工厂
@Service
public class ClientFactory {
private final Map clientServiceMap = new ConcurrentHashMap<>();
public ClientService getClient(String appType) {
ClientService clientService = clientServiceMap.get(appType);
if (clientService == null) {
throw new RuntimeException("未找到客户端");
}
return clientService;
}
}
客户端接口
public interface ClientService {
String getResult();
}
支付宝实现
@Component(value = “alipay”)
public class AlipayServiceImpl implements ClientService {
@Override
public String getResult() {
return "我是支付宝";
}
}
微信实现
@Component(value = “wechat”)
public class WechatServiceImpl implements ClientService {
@Override
public String getResult() {
return "我是微信";
}
}
从上面可以看出,调用者仍然只需要传入自己的参数,在寻找具体处理类和方法的路径都被包装在工厂方法和springbean和具体类的映射关系处理中。以后增加了新的客户端百度,只需要新增一个BaiduService处理类即可。
还有一次经历是是使用模版方法完成业务逻辑的组件化,之前一个业务逻辑有很多个版本,我还需要再增加2个版本,全部流程大致有15步流程,在不同的版本可能会有缺少不同的步骤,所以之前的逻辑就有在不同步骤中有各自版本的判断导致很难清晰的看出每个版本自己的逻辑是什么,导致我很难加自己的逻辑,也很不利于排查问题。
那怎样解决这样一个问题呢?最后结合模版方法的模式来重构了一遍代码,我们先看下模版方法模式的定义,模板方法模式定义了一个算法
的步骤,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤。它主要优点包括:
客户端
public class Client {
public static void main(String[] args) {
AbstractClass instance1 = new ConcreteClass1();
instance1.templateMethod();
AbstractClass instance2 = new ConcreteClass2();
instance2.templateMethod();
}
}
// 定义抽象类
abstract class AbstractClass {
// 声明为final,避免子类重写模板方法
public final void templateMethod() {
// 调用基本方法
operation1();
abstractMethod1();
operation2();
abstractMethod2();
}
// 基本方法
public void operation1() {
System.out.println(“执行操作1”);
}
public void operation2() {
System.out.println("执行操作2");
}
// 抽象方法,需要子类实现
public abstract void abstractMethod1();
public abstract void abstractMethod2();
}
// 定义具体实现类1
class ConcreteClass1 extends AbstractClass {
@Override
public void abstractMethod1() {
System.out.println(“实现类1,重写抽象方法1”);
}
@Override
public void abstractMethod2() {
System.out.println("实现类1,重写抽象方法2");
}
}
// 定义具体实现类2
class ConcreteClass2 extends AbstractClass {
@Override
public void abstractMethod1() {
System.out.println(“实现类2,重写抽象方法1”);
}
@Override
public void abstractMethod2() {
System.out.println("实现类2,重写抽象方法2");
}
}
以上就是我用设计模式解决的两个工作问题,那么在在工作中,如何有效利用设计模式帮我们解决问题呢?我觉得主要有以下几点:
1.理解业务需求:在开始编码之前,深入了解业务需求是非常重要的。这将帮助我们确定哪些设计模式最适合当前的问题。
2.识别问题:在开发过程中,时刻关注代码中可能出现的重复、冗余或难以维护的部分。这些问题通常是需要应用设计模式的候选者。
3.选择适当的设计模式:根据识别到的问题,拟合设计模式的解决方式,在脑子中模拟改写后的业务代码,大致逻辑通顺后就可以尝试改写了。有的一直设计模式可能还不好解决,那就要先拆解一部分,分批解决,因为工程是有时间、成本要求的,不可能一直等我们苦思冥想和尝试。而且也不要试图一次性将所有代码都改造成使用设计模式。相反,应该逐步改进代码,逐步引入设计模式。这样可以确保代码始终保持在一个稳定且可维护的状态。
4.学习和研究:不断学习新的设计模式,研究它们是如何解决特定问题的。这可以通过阅读书籍、在线教程、博客文章和开源代码库来实现。这样可以让我们脑子里有个设计模式的概念,尽快的能拟合业务场景找到合适的设计模式,这样才保证能在工作中用起来。
5.注意事项:设计模式并不是银弹,我们应该根据具体情况和需求进行选择和调整。不要盲目追求使用设计模式,而是要在理解它们的优缺点的基础上做出决策。
下面我附一下常用设计模式的定义,方便根据定义来映射场景:
设计模式主要分为三类:创建型模式、结构型模式和行为型模式。
1.创建型模式(Creational Patterns)
上述的主要是在代码层面的设计模式,还有一些分类标准有一些设计模式也可以了解下,例如架构模式中的以下设计模式: