Android技术

Java 十一种设计模式深入理解

2019-11-25  本文已影响0人  阴天吃鱼
                                  `话不多说直奔主题。`
action.png

目录
一、工厂设计模式
二、抽象工厂模式
三、单例设计模式
四、建造者(Builder)模式
五、原型模式
六、适配器设计模式
七、桥接(Bridge)设计模式
八、责任链模式
九、迭代器设计模式
十、观察者模式
十一、策略设计模式


一、工厂设计模式

在工厂设计模式中,我们没有把创建对象暴露给客户端,而是通过接口的形式创建引入新的对象。接下来我将创建一个Product接口,写ABC三种产品类 实现接口,它们将会把信息传递给ProductFactory,通过ProductFactory来根据情况获取产品。

public interface Product {
    void product();
}
public class ProductImplA implements Product {
    @Override
    public void product() {
        System.out.println("this is ProductImplA");
    }
}
public class ProductFactory {
    public Product getProduct(String productType) {
        if (TextUtils.isEmpty(productType)) {
            return null;
        }
        if ("A".equals(productType)) {
            return new ProductImplA();
        } else if ("B".equals(productType)) {
            return new ProductImplB();
        } else if ("C".equals(productType)) {
            return new ProductImplC();
        }
        return null;
    }
}
private void FactoryDemo() {
        ProductFactory productFactory = new ProductFactory();
        productFactory.getProduct("A").product();
        productFactory.getProduct("B").product();
        productFactory.getProduct("C").product();
    }

-1.5 验证信息

I/System.out: this is ProductImplA
I/System.out: this is ProductImplB
I/System.out: this is ProductImplC

二、抽象工厂模式

抽象工厂是一个大厂,用来创建其他工厂,可以理解为工厂的工厂。

接下来我将创建两个小厂子Product与Color,与(一)工厂设计模式一样,接口并实现ABC。之后创建一个抽象工厂类AbstractFactory,将ProductFactory和ColorFactory定义成自扩展的AbstractFactory,之后在创建 工厂创建者FactoryProducer。

public interface Color {
    void color();
}
public class ColorImplA implements Color {
    @Override
    public void color() {
        System.out.println("class ColorImplA , method color");
    }
}
public abstract class AbstractFactory {
    public abstract Color getColor(String colorType);
    public abstract Product getProduct(String productType);
}

-2.4 创建ColorFactory工厂 注意继承类,Product同理,但需要注意抽象方法
ColorFactory.java

public class ProductFactory extends AbstractFactory {
    @Override
    public Color getColor(String colorType) {
        return null;
    }

    @Override
    public Product getProduct(String productType) {
        if (TextUtils.isEmpty(productType)) {
            return null;
        }
        if ("productA".equals(productType)) {
            return new ProductImplA();
        } else if ("productB".equals(productType)) {
            return new ProductImplB();
        } else if ("productC".equals(productType)) {
            return new ProductImplC();
        }
        return null;
    }
}

-2.5 创建 创建工厂者, 根据传递信息获取具体工厂
FactoryProducer.java

public class FactoryProducer {

    public static AbstractFactory getType(String choice) {
        if ("color".equals(choice)) {
            return new ColorFactory();
        } else if ("product".equals(choice)) {
            return new ProductFactory();
        }
        return null;
    }
}
private void AbstractFactory() {
        AbstractFactory colorProducer = FactoryProducer.getType("color");
        colorProducer.getColor("colorA").color();
        colorProducer.getColor("colorB").color();
        colorProducer.getColor("colorC").color();

        AbstractFactory productProducer = FactoryProducer.getType("product");
        productProducer.getProduct("productA").product();
        productProducer.getProduct("productB").product();
        productProducer.getProduct("productC").product();
    }
I/System.out: class ColorImplA , method color
I/System.out: class ColorImplB , method color
I/System.out: class ColorImplC , method color
I/System.out: class ProductImplA , method product
I/System.out: class ProductImplB , method product
I/System.out: class ProductImplC , method product

三、单例设计模式

Java中最简单的设计模式之一,这种模式只涉及一个类,它负责创建一个对象,同时保证只有一个对象,这个类提供一种方法来访问它的唯一对象,可以直接访问而不需要实例化对象,实例化对象也只有一次。

public class SingleClass {

    private static SingleClass singleClass = new SingleClass();

    public static SingleClass getInstance() {
        return singleClass;
    }
}
public class SingleClass {
    private static SingleClass singleClass;

    public static SingleClass getInstance() {
        if (null == singleClass) {
            singleClass = new SingleClass();
        }
        return singleClass;
    }
}

四、建造者(Builder)模式

public abstract class AbstractBuilder {

    abstract void InstallStudio();

    abstract void DownLoadSDK();

    abstract void BuildProject();

    public abstract Project getProject();
}
public class Project {

    private List<String> step = new ArrayList<>();

    public void add(String info) {
        step.add(info);
    }

    public void show() {
        for (int i = 0; i < step.size(); i++) {
            Log.e("step" + (i + 1), "show: " + step.get(i));
        }
        Log.e("step", "show: 安装完成!!!");
    }

}
public class Controller extends AbstractBuilder {

    private Project project;

    public Controller() {
        project = new Project();
    }

    @Override
    void InstallStudio() {
        project.add("安装Studio");
    }

    @Override
    void DownLoadSDK() {
        project.add("下载SDK");
    }

    @Override
    void BuildProject() {
        project.add("build项目");
    }


    @Override
    public Project getProject() {
        return project;
    }

    public static class Builder {

        private AbstractBuilder abstractBuilder;

        public Builder(AbstractBuilder abstractBuilder) {
            this.abstractBuilder = abstractBuilder;
        }

        public Builder create() {
            abstractBuilder.InstallStudio();
            abstractBuilder.DownLoadSDK();
            abstractBuilder.BuildProject();
            return this;
        }


        public Builder getProject() {
            abstractBuilder.getProject();
            return this;
        }

        public Builder show() {
            abstractBuilder.getProject().show();
            return this;
        }
    }
}
Controller.Builder builder = new Controller.Builder(new Controller());
        builder.create().getProject().show();
step1: show: 安装Studio
step2: show: 下载SDK
step3: show: build项目
step: show: 编译完成!!!

五、原型模式

核心思想:复制粘贴都用过,复制的文件跟原文件没有一点差别。
概念:用原型实例 指定创建对象的种类,并通过拷贝这些原型创建新的对象。

public class AttachType {
    **get,set,tostring方法隐藏,但实际有
    private String attach;
}
public class Student implements Cloneable {
    **get,set,tostring方法隐藏,但实际有
    private AttachType attachType;
    private String name;
  
    public Student clone() {
        Student student = null;
        try {
            student = (Student) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return student;
    }
}

private void catalog() {
        Student student1 = new Student();
        AttachType attachType = new AttachType("aaa");
        student1.setName("张三");
        student1.setAttachType(attachType);

        Student student2 = student1.clone();
        student2.setName("李四");
        student2.getAttachType().setAttach("bbb");

        System.out.println(">>>s1" + student1.toString());
        System.out.println(">>>s2" + student2.toString());
    }

-5.1.4 输出结果

I/System.out: >>>s1Student{attachType=AttachType{attach='bbb'}, name='张三'}
I/System.out: >>>s2Student{attachType=AttachType{attach='bbb'}, name='李四'}

可以看到只改动了name,AttachType对象,并没有分离出来。

public class AttachType_2 implements Cloneable {
    ** get,set,tostring方法隐藏,但实际有
    private String attach;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

-5.2.2定义抽象原型
Student_2.java

public class Student_2 implements Cloneable {
    ** get,set,tostring方法隐藏,但实际有
    private AttachType attachType;
    private String name;

    public Student_2 clone() {
        Student_2 student_2 = null;
        try {
            student_2 = (Student_2) super.clone();
            student_2.setAttachType((AttachType) student_2.getAttachType().clone());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return (Student_2) student_2;
    }
}
I/System.out: >>>s1Student{attachType=AttachType{attach='aaa'}, name='张三'}
I/System.out: >>>s2Student{attachType=AttachType{attach='bbb'}, name='李四'}

处理之后,AttachType_2也被拷贝了。
在某种情况下,合理使用可节省避免不必要的开支。


六、适配器设计模式

概念:负责连接独立或不兼容的接口。
可分为对象适配和类适配模式。
三个角色,目标接口或类、适配类或接口、适配器

public class ConvertEnglish {

    void convertToEnglish(String info) {
        System.out.println(">>>转换成英文 : " + info);
    }
}
public interface SpeakChinese {
    void speakChinese(String chinese);
}
public class TransformationAdapter implements SpeakChinese {

    private ConvertEnglish convertEnglish;

    public TransformationAdapter(ConvertEnglish convertEnglish) {
        this.convertEnglish = convertEnglish;
    }

    @Override
    public void speakChinese(String chinese) {
        convertEnglish.convertToEnglish(chinese);
    }
}
TransformationAdapter adapter = new TransformationAdapter(new ConvertEnglish());
        adapter.speakChinese("我需要转换成英文");

I/System.out: >>>转换成英文 : 我需要转换成英文

对象适配器可以传入多个不同的对象,用来帮忙处理。

public class TransformationAdapter extends ConvertEnglish implements SpeakChinese {
    @Override
    public void speakChinese(String chinese) {
        super.convertToEnglish(chinese);
    }
}

可以看到是通过extends的方式来获取目标类的属性,但是java中不支持多继承,所以在使用类适配的时候,每一个目标类需要单独写一个。


七、桥接模式

概念:使得具体实现类和接口实现类独立。

public interface Animation {
    void onDraw(int radius, int x, int y);
}
public class RotateImpl implements Animation {
    @Override
    public void onDraw(int radius, int x, int y) {
        System.out.println(">>>DrawingRotate:" + radius + "," + x + "," + y);
    }
}

public class TranslationImpl implements Animation {
    @Override
    public void onDraw(int radius, int x, int y) {
        System.out.println(">>>DrawingTranslation:" + radius + "," + x + "," + y);
    }
}
public abstract class AbstractShape {

    protected Animation animation;

    public AbstractShape(Animation animation) {
        this.animation = animation;
    }

    abstract void onDraw();
}
public class ShapeImpl extends AbstractShape {

    private int radius, x, y;

    public ShapeImpl(int radius, int x, int y, Animation animation) {
        super(animation);
        this.radius = radius;
        this.x = x;
        this.y = y;
    }

    @Override
    public void onDraw() {
        animation.onDraw(radius, x, y);
    }
}
ShapeImpl rotate = new ShapeImpl(9, 100, 100, new RotateImpl());
ShapeImpl translate = new ShapeImpl(15, 200, 300, new TranslationImpl());
rotate.onDraw();
translate.onDraw();

···
log
>>>DrawingRotate:9,100,100
>>>DrawingTranslation:15,200,300

使得具体实现类与接口实现类解耦,两种类都可以在结构上发生改变并且互不影响。


八、责任链模式

概念:将同一请求形成一条链,由链进行传递,能处理的处理,处理不了的继续传递。

public class RequestBean {
   ** 省略了get set
    //小于18岁   大约18岁小于30岁  大于30岁小于60岁的
    private String name;
    private int age;
    private String remark;
{
public abstract class AbstractHandler {

    protected String handlerName;//当前处理的是谁
    protected AbstractHandler nextMessage;//捆绑

    public AbstractHandler(String handlerName) {
        this.handlerName = handlerName;
    }

    public void setNextMessage(AbstractHandler nextMessage) {
        this.nextMessage = nextMessage;
    }

    public abstract void handlerRequest(RequestBean requestBean);//子类核心处理方法

}
public class StaffA extends AbstractHandler {

    public StaffA(String handlerName) {
        super(handlerName);
    }

    @Override
    public void handlerRequest(RequestBean requestBean) {
        if (requestBean.getAge() < 18) {
            System.out.println(">>>由" + this.handlerName + "处理了:" + requestBean.getAge() + "," + requestBean
                    .getName() + "," + requestBean.getRemark());
        } else {
            if (this.nextMessage != null) {
                this.nextMessage.handlerRequest(requestBean);
            }
        }
    }
}

-8.4 员工B
StaffB.java

public class StaffB extends AbstractHandler {

    public StaffB(String handlerName) {
        super(handlerName);
    }

    @Override
    public void handlerRequest(RequestBean requestBean) {
        if (18 < requestBean.getAge() && requestBean.getAge() < 30) {
            System.out.println(">>>由" + this.handlerName + "处理了:" + requestBean.getAge() + "," + requestBean
                    .getName() + "," + requestBean.getRemark());
        } else {
            if (this.nextMessage != null) {
                this.nextMessage.handlerRequest(requestBean);
            }
        }
    }
}

员工C同理,此处不写了。

private void startChain() {
        AbstractHandler a = new StaffA("张三");
        AbstractHandler b = new StaffB("李四");
        AbstractHandler c = new StaffC("王五");
        
        a.setNextMessage(b);
        b.setNextMessage(c);
        
        RequestBean request = new RequestBean();
        request.setAge(25);
        request.setName("赵二");
        request.setRemark("无");
        a.handlerRequest(request);
    }
I/System.out: >>>由李四处理了:25,赵二,无

九、迭代器设计模式

概念:不需要暴露内部结构的同时,可以让外部遍历数据。

public interface MyIterator {
    boolean hasNext();//判定是否有下一条

    Object next();
}

public interface Container {
    MyIterator getMyIterator();
}
public class ContainerImpl implements Container {

    private String[] strings = new String[]{"aa", "bb", "cc", "dd", "ee"};

    @Override
    public MyIterator getMyIterator() {
        return new Iterator();
    }

    class Iterator implements MyIterator {

        private int index;

        @Override
        public boolean hasNext() {
            if (index < strings.length) {
                return true;
            }
            return false;
        }

        @Override
        public Object next() {
            if (this.hasNext()) {
                return strings[index++];
            }
            return null;
        }
    }
}

hasNext处理我是否还有下一条数据,在有的前提下我才可以在next方法中return出去,至于为啥要++,next方法肯定在循环中呗。

ContainerImpl container = new ContainerImpl();
for (MyIterator myIterator = container.getMyIterator(); myIterator.hasNext(); ) {
            String next = (String) myIterator.next();
            System.out.println(">>>next" + next);
}
I/System.out: >>>nextaa
I/System.out: >>>nextbb
I/System.out: >>>nextcc
I/System.out: >>>nextdd
I/System.out: >>>nextee

十、观察者模式

概念:如果一个对象被修改,它的依赖对象将会被自动通知。
自动通知其实就是在 合理的时间调用通知接口,直接上代码。

public abstract class MyObserver {

    protected Subscriber subscriber;

    abstract void update();

}
public class Subscriber {

    private MyObserver myObserver;

    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        notifyAllObserver();
    }

    //绑定
    public void attach(MyObserver myObserver) {
        this.myObserver = myObserver;
    }

    //通知
    public void notifyAllObserver() {
        myObserver.update();
    }
}

可以看到,引入MyObserver抽象类,通过调用MyObserver.update来做通知,所以合理的地方调用notifyAllObserver很重要。

public class ObserverImpl extends MyObserver {

    public ObserverImpl(Subscriber subscriber) {
        this.subscriber = subscriber;
        this.subscriber.attach(this);
    }

    @Override
    public void update() {
        System.out.println(">>>this update now");
    }
}
private Subscriber subscriber;//成员变量,点击的时候做通知

subscriber = new Subscriber();
        new ObserverImpl(subscriber);

btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                subscriber.setState(1);
            }
        });

subscriber 写成了成员变量,在click view的时候,做了setState值更新。更新就是通知该 调用update接口了。
-10.5 验证信息

 I/System.out: >>>this update now

十一、策略设计模式

概念:针对一组算法,将每一种算法都封装到具有共同接口的独立的类中,从而是它们可以相互替换。策略模式的最大特点是使得算法可以在不影响客户端的情况下发生变化,从而改变不同的功能。

public interface IStrategy {
    void strategyType(int a, int b);
}
public class StrategyA implements IStrategy {

    @Override
    public void strategyType(int a, int b) {
        //处理算法。
        int sum = a + b;
        System.out.println(">>>sum" + sum);
    }
}
public class StrategyB implements IStrategy {

    @Override
    public void strategyType(int a, int b) {
        //处理算法。
        int sum = a * b;
        System.out.println(">>>sum" + sum);
    }
}

还写了个减法,同步上面都一样。主要是为了表现策略之一。

public class StrategyImpl {

    private IStrategy iStrategy;

    public StrategyImpl(IStrategy iStrategy) {
        this.iStrategy = iStrategy;
    }

    public void strategyType(int a, int b) {
        iStrategy.strategyType(a, b);
    }

}
private void strategy() {
        int a = 10;
        int b = 5;
        StrategyImpl strategy = new StrategyImpl(new StrategyA());
        strategy.strategyType(a, b);

        StrategyImpl strategy2 = new StrategyImpl(new StrategyB());
        strategy2.strategyType(a, b);

        StrategyImpl strategy3 = new StrategyImpl(new StrategyC());
        strategy3.strategyType(a, b);
    }
 I/System.out: >>>sum15
 I/System.out: >>>sum50
 I/System.out: >>>sum5

策略模式的好处是 实现可以自由切换,扩展性也比较好,阅读代码很直观。

结语
设计模式 真的是可以规范代码,并且提高对源码的理解。

上一篇下一篇

猜你喜欢

热点阅读