美文网首页
23种设计模式之享元模式

23种设计模式之享元模式

作者: 阿跳爱学习 | 来源:发表于2019-01-12 00:16 被阅读0次

    优点:减少内存中对象的数量,相同或相似对象在内存中只存在一个,节省内存,提高系统性能。
    缺点:运行时间变长,用时间换取内存。

    模式图: image.png
    享元模式能做到共享的关键是区分了内部状态和外部状态。
    内部状态:可以共享,不会随着环境变化而改变。

    外部状态:不可用共享,会随着环境变化而改变。

    主要分为四个角色:

    • Flyweight: 抽象享元类。一个接口或者抽象类,声明公共方法,这些方法可以向外部提供对象内部状态和设置对象的外部状态。
    • ConcreteFlyweight: 具体享元类。为内部状态提供成员变量进行存储。
    • UnsharedConcreteFlyweight: 非共享享元类。不能被共享的子类,可以设计为非共享享元类。
    • FlyweightFactory: 享元工厂类。创建并管理享元对象,享元池一般设置成键值对。

    例子:比如五子棋中的黑棋或白棋,它们颜色形状都是一样的,可以共享,不会随着环境的变化而改变,这就是内部状态。唯一不一样的就是它们的坐标,不可共享,因为每块棋子的坐标都是不一样的,这就是外部状态。

    把外部状态独立出来(UnsharedConcreteFlyweight):

    /**
     * 这是一个坐标类。
     * UnsharedConcreteFlyweight: 非共享享元类。不能被共享的子类,可以设计为非共享享元类。
     */
    
    public class CoordinateUnshared {
    
        private int x, y;
    
        public CoordinateUnshared(int x, int y) {
            this.x = x;
            this.y = y;
        }
    
        public int getX() {
            return x;
        }
    
        public void setX(int x) {
            this.x = x;
        }
    
        public int getY() {
            return y;
        }
    
        public void setY(int y) {
            this.y = y;
        }
    }
    

    Flyweight: 抽象享元类。一个接口或者抽象类,声明公共方法,这些方法可以向外部提供对象内部状态和设置对象的外部状态:

    /**
     * 这是一个棋子抽象享元类
     * Flyweight: 抽象享元类。一个接口或者抽象类,声明公共方法,这些方法可以向外部提供对象内部状态和设置对象的外部状态。
     */
    
    public interface ChessFlyweight {
        void setColor(String color);
    
        String getColor();
    
        void displayPosition(CoordinateUnshared c);
    }
    

    ConcreteFlyweight: 具体享元类。为内部状态提供成员变量进行存储:

    /**
     * 这是一个具体享元类
     * ConcreteFlyweight: 具体享元类。为内部状态提供成员变量进行存储。
     */
    
    public class ChessConcrete implements ChessFlyweight {
    
        private String color;
    
        public ChessConcrete(String color) {
            this.color = color;
        }
    
        @Override
        public void setColor(String color) {
            this.color = color;
        }
    
        @Override
        public String getColor() {
            return color;
        }
    
        @Override
        public void displayPosition(CoordinateUnshared c) {
            Log.d("TAG", "对象:" + this + "\n颜色:" + color + "\n棋子位置:" + "x = " + c.getX() + " y = " + c.getY());
        }
    }
    

    FlyweightFactory: 享元工厂类:

    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * FlyweightFactory: 享元工厂类。创建并管理享元对象,享元池一般设置成键值对。
     */
    
    public class ChessFlyweightFactory {
    
        private static Map<String, ChessFlyweight> map = new HashMap<String, ChessFlyweight>();
    
        public static ChessFlyweight getChess(String color) {
            if (map.get(color) != null) {
                return map.get(color);
            } else {
                ChessFlyweight chessFlyweight = new ChessConcrete(color);
                map.put(color, chessFlyweight);
                return chessFlyweight;
            }
        }
    }
    

    调用:

    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v4.app.FragmentActivity;
    import android.util.Log;
    
    /**
     * 这是调用者
     */
    
    public class MainActivity extends FragmentActivity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ChessFlyweight chessFlyweight1 = ChessFlyweightFactory.getChess("黑色");
            ChessFlyweight chessFlyweight2 = ChessFlyweightFactory.getChess("黑色");
            ChessFlyweight chessFlyweight3 = ChessFlyweightFactory.getChess("白色");
    
            Log.d("TAG", "添加外部处理-----------------------");
            chessFlyweight1.displayPosition(new CoordinateUnshared(10, 10));
            chessFlyweight2.displayPosition(new CoordinateUnshared(20, 20));
            chessFlyweight3.displayPosition(new CoordinateUnshared(30, 30));
        }
    }
    
    结果: image.png

    创建了两次黑色棋子,但是并没有生成新对象,而是同一个对象,只是添加的外部处理不一样(坐标),白色棋子为新对象,因为系统中还不存在白色对象,所以无论创建多少黑色对象和白色对象,黑色和白色也都各只存在一个。
    已完成测试!有不对的地方欢迎指出,感恩。

    相关文章

      网友评论

          本文标题:23种设计模式之享元模式

          本文链接:https://www.haomeiwen.com/subject/saygrqtx.html