作为一名 java 开发人员,我发现设计模式是创建健壮且可维护的软件不可或缺的工具。它们为常见的编程挑战提供了经过验证的解决方案,并帮助我们编写更清晰、更高效的代码。在本文中,我将分享我对七种基本 java 设计模式的见解,这些模式显着提高了我的软件架构技能。
单例模式通常是开发人员遇到的第一个设计模式。它用于确保某个类在整个应用程序的生命周期中只有一个实例。在处理共享资源或跨系统协调操作时,此模式特别有用。这是一个基本的实现:
public class singleton { private static singleton instance; private singleton() {} public static synchronized singleton getinstance() { if (instance == null) { instance = new singleton(); } return instance; } }
在此示例中,构造函数是私有的,防止直接实例化。 getinstance() 方法负责创建并返回单个实例。 synchronized关键字保证了线程安全。
虽然 singleton 很有用,但明智地使用它也很重要。过度使用会导致紧密耦合并使测试变得更加困难。根据我的经验,它最好保留用于具有多个实例会出现问题或浪费的场景。
工厂方法模式是java设计的另一个基石。它提供了一个用于创建对象的接口,但允许子类决定实例化哪个类。这种模式促进了对象创建的松散耦合和灵活性。
立即学习“Java免费学习笔记(深入)”;
这是一个简单的实现:
public interface animal { void makesound(); } public class dog implements animal { @override public void makesound() { system.out.println("woof!"); } } public class cat implements animal { @override public void makesound() { system.out.println("meow!"); } } public abstract class animalfactory { public abstract animal createanimal(); } public class dogfactory extends animalfactory { @override public animal createanimal() { return new dog(); } } public class catfactory extends animalfactory { @override public animal createanimal() { return new cat(); } }
在此示例中,animalfactory 抽象类定义了工厂方法 createanimal()。像 dogfactory 和 catfactory 这样的具体工厂实现了这个方法来创建特定的 animal 对象。
工厂方法模式在我的项目中非常宝贵,我需要创建相关对象系列而不指定它们的具体类。当使用插件或直到运行时才知道所需对象的确切类型时,它特别有用。
观察者模式是实现事件处理系统的强大工具。它在对象之间建立一对多的依赖关系,确保当一个对象改变状态时,它的所有依赖对象都会自动收到通知。
这是一个基本实现:
import java.util.arraylist; import java.util.list; interface observer { void update(string message); } class subject { private list<observer> observers = new arraylist<>(); private string state; public void attach(observer observer) { observers.add(observer); } public void notifyallobservers() { for (observer observer : observers) { observer.update(state); } } public void setstate(string state) { this.state = state; notifyallobservers(); } } class concreteobserver implements observer { private string name; public concreteobserver(string name) { this.name = name; } @override public void update(string message) { system.out.println(name + " received message: " + message); } }
在此示例中,subject 类维护一个观察者列表,并在其状态发生变化时通知他们。 observer接口定义了具体观察者必须实现的更新方法。
我发现观察者模式在开发用户界面和事件驱动系统时特别有用。它允许组件之间的松散耦合,并且可以轻松添加新的观察者而不修改主题。
策略模式是 java 开发人员武器库中的另一个重要工具。它定义了一系列算法,封装了每个算法,并使它们可以互换。这种模式允许算法独立于使用它的客户端而变化。
这是一个示例实现:
interface paymentstrategy { void pay(int amount); } class creditcardpayment implements paymentstrategy { private string cardnumber; public creditcardpayment(string cardnumber) { this.cardnumber = cardnumber; } @override public void pay(int amount) { system.out.println("paid " + amount + " using credit card " + cardnumber); } } class paypalpayment implements paymentstrategy { private string email; public paypalpayment(string email) { this.email = email; } @override public void pay(int amount) { system.out.println("paid " + amount + " using paypal account " + email); } } class shoppingcart { private paymentstrategy paymentstrategy; public void setpaymentstrategy(paymentstrategy paymentstrategy) { this.paymentstrategy = paymentstrategy; } public void checkout(int amount) { paymentstrategy.pay(amount); } }
在此示例中,不同的支付策略实现了 paymentstrategy 接口。 shoppingcart 类可以互换使用这些策略中的任何一个。
我发现策略模式在处理需要在运行时选择算法的场景时非常有用。它促进代码重用,并可以轻松添加新策略而无需修改现有代码。
装饰器模式是用于扩展功能的子类化的灵活替代方案。它允许您通过将对象放置在包装对象内来动态地向对象添加新行为。
这是一个简单的实现:
interface coffee { string getdescription(); double getcost(); } class simplecoffee implements coffee { @override public string getdescription() { return "simple coffee"; } @override public double getcost() { return 1.0; } } abstract class coffeedecorator implements coffee { protected coffee decoratedcoffee; public coffeedecorator(coffee coffee) { this.decoratedcoffee = coffee; } public string getdescription() { return decoratedcoffee.getdescription(); } public double getcost() { return decoratedcoffee.getcost(); } } class milk extends coffeedecorator { public milk(coffee coffee) { super(coffee); } @override public string getdescription() { return decoratedcoffee.getdescription() + ", milk"; } @override public double getcost() { return decoratedcoffee.getcost() + 0.5; } } class sugar extends coffeedecorator { public sugar(coffee coffee) { super(coffee); } @override public string getdescription() { return decoratedcoffee.getdescription() + ", sugar"; } @override public double getcost() { return decoratedcoffee.getcost() + 0.2; } }
在此示例中,我们可以通过用 milk 和 sugar 装饰器包装 simplecoffee 对象来创建不同的咖啡组合。
当我需要向对象添加功能而不改变其结构时,装饰器模式在我的项目中特别有用。在处理无法直接修改的遗留代码或第三方库时,它的功能尤其强大。
builder 模式是一种创建模式,用于逐步构造复杂的对象。当处理具有许多可选参数的对象或当构造过程应该独立于对象表示时,它特别有用。
这是一个示例实现:
class computer { private string cpu; private string ram; private string storage; private string gpu; private computer(computerbuilder builder) { this.cpu = builder.cpu; this.ram = builder.ram; this.storage = builder.storage; this.gpu = builder.gpu; } public string tostring() { return "cpu: " + cpu + ", ram: " + ram + ", storage: " + storage + ", gpu: " + gpu; } public static class computerbuilder { private string cpu; private string ram; private string storage; private string gpu; public computerbuilder(string cpu, string ram) { this.cpu = cpu; this.ram = ram; } public computerbuilder setstorage(string storage) { this.storage = storage; return this; } public computerbuilder setgpu(string gpu) { this.gpu = gpu; return this; } public computer build() { return new computer(this); } } }
使用这种模式,我们可以创建像这样的 computer 对象:
computer computer = new computer.computerbuilder("intel i7", "16gb") .setstorage("1tb ssd") .setgpu("nvidia rtx 3080") .build();
builder 模式在我涉及复杂对象创建的项目中改变了游戏规则。它使代码更具可读性和可维护性,特别是在处理具有许多可选参数的对象时。
最后,依赖注入是一种实现控制反转(ioc)来解决依赖关系的设计模式。在这种模式中,我们不直接创建对象,而是描述应该如何创建它们。另一个类(通常是框架或容器)负责注入依赖项。
这是一个简单的例子:
interface MessageService { void sendMessage(String msg, String receiver); } class EmailService implements MessageService { @Override public void sendMessage(String msg, String receiver) { System.out.println("Email sent to " + receiver + " with Message=" + msg); } } class SMSService implements MessageService { @Override public void sendMessage(String msg, String receiver) { System.out.println("SMS sent to " + receiver + " with Message=" + msg); } } class MyApplication { private MessageService service; // Constructor injection public MyApplication(MessageService svc) { this.service = svc; } public void processMessages(String msg, String rec) { // Do some msg validation, manipulation logic etc this.service.sendMessage(msg, rec); } }
在此示例中,myapplication 不直接创建 messageservice 对象。相反,它是通过构造函数注入的。这使得代码更加模块化并且更容易测试。
依赖注入在我的大型项目中至关重要,尤其是在使用 spring 等框架时。它促进了类之间的松散耦合,并使得在不更改客户端代码的情况下更容易交换实现。
这七种设计模式是我的 java 开发之旅中必不可少的工具。他们帮助我创建了更灵活、可维护和可扩展的软件架构。然而,重要的是要记住,设计模式并不是灵丹妙药。仅当它们为设计提供明显的好处时,才应该明智地使用它们。
与软件开发中的任何工具一样,关键不仅是要了解如何实现这些模式,还要了解何时以及为何使用它们。每种模式都解决了特定的设计挑战,并促进了面向对象编程的最佳实践。通过掌握这些模式并了解其适当的用例,您可以显着提高 java 应用程序的质量。
根据我的经验,设计模式的真正力量在于它们能够在开发人员之间创建通用词汇。当团队熟悉这些模式时,快速有效地传达复杂的设计思想就会变得更加容易。这种共同的理解可以带来更高效的协作,并最终带来更好的软件。
当您继续 java 开发之旅时,我鼓励您进一步探索这些模式。在您的项目中实现它们,尝试不同的变体,最重要的是,反思它们如何影响代码的结构和可维护性。通过练习,您将对何时以及如何应用这些模式来优雅地解决复杂的设计问题产生直觉。
请记住,我们的目标不是在任何地方使用设计模式,而是在它们能增加价值的地方使用它们。随着经验的积累,您会发现这些模式的明智应用可以改变您的软件设计方法,从而产生更健壮、灵活且可维护的 java 应用程序。
我们的创作一定要看看我们的创作:
投资者中心 | 投资者中央西班牙语 | 智能生活 | 时代与回声 | 令人费解的谜团 | 印度教 | 精英开发 | js学校
我们在媒体上科技考拉洞察 | 时代与回响世界 | 投资者中央媒体 | 令人费解的谜团 | 科学与时代媒介 | 现代印度教
以上就是健壮软件架构的基本 Java 设计模式的详细内容,更多请关注图灵教育其它相关文章!