Java的设计模式三大类
1.工厂方法模式(FactoryMethod Pattern)
一、普通工厂方法模式
就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。
举例:手机发短信或微信。
手机:
public interface Phone {
public void send();
}
老年机:
public class oldMachine implements Phone{
@Override
public void send() {
//老年机只能发短信
System.out.println("发短信");
}
}
智能机:
public class smartPhone implements Phone {
@Override
public void send() {
//智能机可以发微信
System.out.println("发微信");
}
}
工厂:
public class Factory {
public Phone send(String type){
if("oldMachine".equals(type)){
return new oldMachine();
}else if("smartPhone".equals(type)){
return new smartPhone();
}
return null;
}
}
测试:
public class Test {
public static void main(String[] args){
Factory factory=new Factory();
Phone phone=factory.send("oldMachine");
phone.send();
}
}
结果:
二、多个工厂方法模式
是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。
工厂:
public class Factory {
public Phone sendMail(){
return new oldMachine();
}
public Phone sendWechat(){
return new smartPhone();
}
}
测试:
public class Test {
public static void main(String[] args){
Factory factory=new Factory();
Phone phone=factory.sendMail();
phone.send();
}
}
结果:
三、静态工厂方法模式
将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。
工厂:
public class Factory {
public static Phone sendMail(){
return new oldMachine();
}
public static Phone sendWechat(){
return new smartPhone();
}
}
测试:
public class Test {
public static void main(String[] args){
Phone phone=Factory.sendMail();
phone.send();
}
}
结果:
类图如下:
2.抽象工厂方法模式(Abstract Factory)
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。
手机接口:
public interface Phone {
public void send();
}
老年机:
public class oldMachine implements Phone{
@Override
public void send() {
//老年机只能发短信
System.out.println("发短信");
}
}
智能机:
public class smartPhone implements Phone {
@Override
public void send() {
//智能机可以发微信
System.out.println("发微信");
}
}
工厂接口:
public interface Send {
public Phone send();
}
老年机工厂:
public class oldMachineFactory implements Send {
@Override
public Phone send() {
return new oldMachine();
}
}
智能机工厂:
public class smartPhoneFactory implements Send {
@Override
public Phone send() {
return new smartPhone();
}
}
测试:
public class Test {
public static void main(String[] args){
Send send= new smartPhoneFactory();
Phone phone=send.send();
phone.send();
}
}
结果:
其实这个模式的好处就是,如果你现在想增加一个功能:发及时信息,则只需做一个实现类,实现Phone接口,同时做一个工厂类,实现Send接口,就OK了,无需去改动现成的代码。这样做,拓展性较好!
类图如下:
3.外观模式(Facade Pattern)
比如说做饭,你得先买菜,然后洗菜,烹饪,吃;这几个过程顺序不能乱吧,而且缺一不可吧。你想想你上了一天班回来还得这么累,麻烦?麻烦!怎么解决?下馆子呗,告诉厨师你的需求,让他去干,你只需要吃就行。
做饭的过程:
//做饭的过程
public interface Cook {
//买菜(买哪些菜)
public void buyVegetables(String vegetables);
//洗菜
public void washVegetables();
//烹饪(什么口味)
public void cookVegetables(String flavour);
//吃
public void eat();
}
做饭的实现类:
//做饭的具体实现
public class cookImpl implements Cook{
@Override
public void buyVegetables(String vegetables) {
System.out.println("买菜。。。。");
}
@Override
public void washVegetables() {
System.out.println("洗菜。。。。");
}
@Override
public void cookVegetables(String flavour) {
System.out.println("烹饪。。。。");
}
@Override
public void eat() {
System.out.println("吃。。。。");
}
}
餐馆:
public class Restaurant {
private Cook cook=new cookImpl();
public void cook(String vegetables,String flavour){
cook.buyVegetables(vegetables);
cook.washVegetables();
cook.cookVegetables(flavour);
cook.eat();
}
}
你去下馆子:
public class Client {
public static void main(String[] args){
Restaurant rs=new Restaurant();
//想吃鱼
String vegetables="fish";
//酸辣味
String flavour="sour and hot";
rs.cook(vegetables,flavour);
}
}
结果:
如果厨师做饭的过程中,卫生局来检查了,刚好抽中了你这盘菜呢?
卫生局:
public class healthDepartment {
public void check(Cook cook){};
}
修改餐厅类:
public class Restaurant {
private Cook cook=new cookImpl();
private healthDepartment hd=new healthDepartment();
public void cook(String vegetables,String flavour){
cook.buyVegetables(vegetables);
cook.washVegetables();
cook.cookVegetables(flavour);
hd.check(cook);
cook.eat();
}
}
结果:
食材健康?健康,但是你看不到检查这个过程。
什么时候用呢?开发过程中,遇到水平比较渣的程序员,尽量安排他负责独立模块,然后封装成一个门面模式,让其他团队成员不至于看到这些烂代码糟心。
类图如下:
4.适配器模式(Adapter Pattern)
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题。主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。
类的适配器模式:
Source类:
public class Source {
public void method1(){
System.out.println("Source的method方法");
}
}
Target接口:
public interface Target {
//source类的方法
public void method1();
//新的方法
public void method2();
}
适配器:
public class Adapter extends Source implements Target {
@Override
public void method2() {
System.out.println("Target的method方法");
}
}
测试:
public class Test {
public static void main(String[] args){
Target target=new Adapter();
target.method1();
target.method2();
}
}
结果:
这样Target接口的实现类就具有了Source类的功能。
对象的适配器模式:
基本思路和类的适配器模式相同,只是将Adapter类作修改,这次不继承Source类,而是持有Source类的实例,以达到解决兼容性的问题。
修改Adapter类:
public class Adapter implements Target {
private Source source;
public Adapter(Source source) {
this.source = source;
}
@Override
public void method1() {
}
@Override
public void method2() {
System.out.println("Target的method方法");
}
}
测试:
public class Test {
public static void main(String[] args){
Source source=new Source();
Target target=new Adapter(source);
target.method1();
target.method2();
}
}
结果:
接口的适配器模式:
有时我们一个接口中有多个抽象方法,当我们写该接口的实现类时,必须实现该接口的所有方法,这明显有时比较浪费,因为并不是所有的方法都是我们需要的,有时只需要某一些,此处为了解决这个问题,我们引入了接口的适配器模式,借助于一个抽象类,该抽象类实现了该接口,实现了所有的方法,而我们不和原始的接口打交道,只和该抽象类取得联系,所以我们写一个类,继承该抽象类,重写我们需要的方法就行。
接口:
public interface Target {
//source类的方法
public void method1();
//新的方法
public void method2();
}
抽象类:
public abstract class Wraaper implements Target {
@Override
public void method1() {
}
@Override
public void method2() {
}
}
S1:
public class S1 extends Wraaper {
@Override
public void method1() {
System.out.println("S1");
}
}
S2:
public class S2 extends Wraaper {
@Override
public void method2() {
System.out.println("S2");
}
}
测试:
public class Test {
public static void main(String[] args){
S1 ss=new S1();
S2 sm=new S2();
ss.method1();
ss.method2();
sm.method1();
sm.method2();
}
}
结果:
类图如下:
全部评论