精华内容
下载资源
问答
  • Android状态栏微技巧,带你真正理解沉浸式模式

    万次阅读 多人点赞 2016-08-23 07:32:55
    记得之前有朋友在留言里我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解。 其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先...

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/51763825

    本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每天都有文章更新。

    记得之前有朋友在留言里让我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解。

    其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发起的。因为Android官方从来没有给出过沉浸式状态栏这样的命名,只有沉浸式模式(Immersive Mode)这种说法。而有些人在没有完全了解清楚沉浸模式到底是什么东西的情况下,就张冠李戴地认为一些系统提供的状态栏操作就是沉浸式的,并且还起了一个沉浸式状态栏的名字。

    比如之前就有一个QQ群友问过我,像饿了么这样的沉浸式状态栏效果该如何实现?

    这个效果其实就是让背景图片可以利用系统状态栏的空间,从而能够让背景图和状态栏融为一体。

    本篇文章当中我会教大家如何实现这样的效果,但这个真的不叫沉浸式状态栏。因此,这算是一篇技术+普及的文章吧,讲技术的同时也纠正一下大家之前错误的叫法。

    什么是沉浸式?

    先来分析一下叫错的原因吧,之所以很多人会叫错,是因为根本就不了解沉浸式是什么意思,然后就人云亦云跟着叫了。那么沉浸式到底是什么意思呢?

    根据百度百科上的定义,沉浸式就是要给用户提供完全沉浸的体验,使用户有一种置身于虚拟世界之中的感觉。

    比如说现在大热的VR就是主打的沉浸式体验。

    那么对应到Android操作系统上面,怎样才算是沉浸式体验呢?这个可能在大多数情况下都是用不到的,不过在玩游戏或者看电影的时候就非常重要了。因为游戏或者影视类的应用都希望能让用户完全沉浸在其中,享受它们提供的娱乐内容,但如果这个时候在屏幕的上方还显示一个系统状态栏的话,可能就会让用户分分钟产生跳戏的感觉。

    那么我们来看一下比较好的游戏都是怎么实现的,比如说海岛奇兵:

    海岛奇兵的这种模式就是典型的沉浸式模式,它的整个屏幕中显示都是游戏的内容,没有状态栏也没有导航栏,用户玩游戏的时候就可以完全沉浸在游戏当中,而不会被一些系统的界面元素所打扰。

    然后我们再来看一下爱奇艺的实现:

    同样也是类似的,爱奇艺将整个屏幕作为影视的展示区,用户在看电影的时候眼中就只会有电影的内容,这样就不会被其他一些无关的东西所分心。

    这才是沉浸式模式的真正含义,而所谓的什么沉浸式状态栏纯粹就是在瞎叫,完全都没搞懂“沉浸式” 这三个字是什么意思。

    不过虽然听上去好像是很高大上的沉浸式效果,实际看上去貌似就是将内容全屏化了而已嘛。没错,Android沉浸式模式的本质就是全屏化,不过我们今天的内容并不仅限于此,因为还要实现饿了么那样的状态栏效果。那么下面我们就开始来一步步学习吧。

    隐藏状态栏

    一个Android应用程序的界面上其实是有很多系统元素的,观察下图:

    可以看到,有状态栏、ActionBar、导航栏等。而打造沉浸式模式的用户体验,就是要将这些系统元素全部隐藏,只留下主体内容部分。

    比如说我现在新建了一个空项目,然后修改布局文件中的代码,在里面加入一个ImageView,如下所示:

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/bg"
            android:scaleType="centerCrop" />
    
    </RelativeLayout>

    这里将ImageView的宽和高都设置成match_parent,让图片充满屏幕。现在运行一下程序,效果如下图所示。

    如果你将图片理解成游戏或者电影界面的话,那这个体验离沉浸式就差得太远了,至少状态栏和ActionBar得要隐藏起来了吧?没关系,我们一步步进行优化,并且在优化中学习。

    隐藏状态栏和ActionBar的方式在4.1系统之上和4.1系统之下还是不一样的,这里我就不准备考虑4.1系统之下的兼容性了,因为过于老的系统根本就没有提供沉浸式体验的支持。

    修改MainActivity中的代码,如下所示:

    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            View decorView = getWindow().getDecorView();
            int option = View.SYSTEM_UI_FLAG_FULLSCREEN;
            decorView.setSystemUiVisibility(option);
            ActionBar actionBar = getSupportActionBar();
            actionBar.hide();
        }
    }

    这里先调用getWindow().getDecorView()方法获取到了当前界面的DecorView,然后调用它的setSystemUiVisibility()方法来设置系统UI元素的可见性。其中,SYSTEM_UI_FLAG_FULLSCREEN表示全屏的意思,也就是会将状态栏隐藏。另外,根据Android的设计建议,ActionBar是不应该独立于状态栏而单独显示的,因此状态栏如果隐藏了,我们同时也需要调用ActionBar的hide()方法将ActionBar也进行隐藏。

    现在重新运行一下程序,效果如下图所示。

    这样看上去就有点沉浸式效果的模样了。

    虽说这才是正统的沉浸式含义,但有些朋友可能想实现的就是饿了么那样的状态栏效果,而不是直接把整个系统状态栏给隐藏掉,那么又该如何实现呢?

    其实也很简单,只需要借助另外一种UI Flag就可以了,如下所示:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (Build.VERSION.SDK_INT >= 21) {
        View decorView = getWindow().getDecorView();
        int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(option);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
    }
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();

    首先需要注意,饿了么这样的效果是只有5.0及以上系统才支持,因此这里先进行了一层if判断,只有系统版本大于或等于5.0的时候才会执行下面的代码。

    接下来我们使用了SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN和SYSTEM_UI_FLAG_LAYOUT_STABLE,注意两个Flag必须要结合在一起使用,表示会让应用的主体内容占用系统状态栏的空间,最后再调用Window的setStatusBarColor()方法将状态栏设置成透明色就可以了。

    现在重新运行一下代码,效果如下图所示。

    可以看到,类似于饿了么的状态栏效果就成功实现了。

    再声明一次,这种效果不叫沉浸式状态栏,也完全没有沉浸式状态栏这种说法,我们估且可以把它叫做透明状态栏效果吧。

    隐藏导航栏

    现在我们已经成功实现隐藏状态栏的效果了,不过屏幕下方的导航栏还比较刺眼,接下来我们就学习一下如何将导航栏也进行隐藏。

    其实实现的原理都是一样的,隐藏导航栏也就是使用了不同的UI Flag而已,修改MainActivity中的代码,如下所示:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    View decorView = getWindow().getDecorView();
    int option = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_FULLSCREEN;
    decorView.setSystemUiVisibility(option);
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();

    这里我们同时使用了SYSTEM_UI_FLAG_HIDE_NAVIGATION和SYSTEM_UI_FLAG_FULLSCREEN,这样就可以将状态栏和导航栏同时隐藏了。现在重新运行一下程序,效果如图所示。

    这次看上去好像终于是完全全屏化了,但其实上这离真正的沉浸式模式还差得比较远,因为在这种模式下,我们触摸屏幕的任意位置都会退出全屏。

    这显然不是我们想要的效果,因此这种模式的使用场景比较有限。

    除了隐藏导航栏之外,我们同样也可以实现和刚才透明状态栏类似的效果,制作一个透明导航栏:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (Build.VERSION.SDK_INT >= 21) {
        View decorView = getWindow().getDecorView();
        int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
        decorView.setSystemUiVisibility(option);
        getWindow().setNavigationBarColor(Color.TRANSPARENT);
        getWindow().setStatusBarColor(Color.TRANSPARENT);
    }
    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();

    这里使用了SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,表示会让应用的主体内容占用系统导航栏的空间,然后又调用了setNavigationBarColor()方法将导航栏设置成透明色。现在重新运行一下程序,效果如下图所示。

    真正的沉浸式模式

    虽说沉浸式导航栏这个东西是被很多人误叫的一种称呼,但沉浸式模式的确是存在的。那么我们如何才能实现像海岛奇兵以及爱奇艺那样的沉浸式模式呢?

    首先你应该确定自己是否真的需要这个功能,因为除了像游戏或者视频软件这类特殊的应用,大多数的应用程序都是用不到沉浸式模式的。

    当你确定要使用沉浸式模式,那么只需要重写Activity的onWindowFocusChanged()方法,然后加入如下逻辑即可:

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        @Override
        public void onWindowFocusChanged(boolean hasFocus) {
            super.onWindowFocusChanged(hasFocus);
            if (hasFocus && Build.VERSION.SDK_INT >= 19) {
                View decorView = getWindow().getDecorView();
                decorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
            }
        }
    
    }

    沉浸式模式的UI Flag就这些,也没什么好解释的,如果你需要实现沉浸式模式,直接将上面的代码复制过去就行了。需要注意的是,只有在Android 4.4及以上系统才支持沉浸式模式,因此这里也是加入了if判断。

    另外,为了让我们的界面看上去更像是游戏,这里我将MainActivity设置成了横屏模式:

    <activity android:name=".MainActivity" 
              android:screenOrientation="landscape">
        ...
    </activity>

    这样我们就实现类似于海岛奇兵和爱奇艺的沉浸式模式效果了,如下图所示。

    可以看到,界面默认情况下是全屏的,状态栏和导航栏都不会显示。而当我们需要用到状态栏或导航栏时,只需要在屏幕顶部向下拉,或者在屏幕右侧向左拉,状态栏和导航栏就会显示出来,此时界面上任何元素的显示或大小都不会受影响。过一段时间后如果没有任何操作,状态栏和导航栏又会自动隐藏起来,重新回到全屏状态。

    这就是最标准的沉浸式模式。


    关注我的技术公众号,每天都有优质技术文章推送。关注我的娱乐公众号,工作、学习累了的时候放松一下自己。

    微信扫一扫下方二维码即可关注:

    20160507110203928         20161011100137978

    展开全文
  • 状态模式

    千次阅读 2018-05-30 10:05:43
    定义: 允许一个对象在其内部...状态模式是通过状态对象来改变动作行为,而不同的状态对象里不同的动作行为表现会不一样,这使得它看起来就像在改变它的类一样。 设计类图: 状态模式中的角色: Context...

    定义:

    允许一个对象在其内部状态改变时改变它的行为,这个对象看起来就像改变了它的类一样。

      状态模式的含义是将对象的状态封装成一个独立的类,并将动作行为委托到代表当前状态的对象,行为会随着内部的状态而改变。状态模式是通过状态对象来改变动作行为,而不同的状态对象里不同的动作行为表现会不一样,这使得它看起来就像在改变它的类一样。

    设计类图:

    状态模式中的角色:

    • Context上下文环境角色,负责状态的切换,持有一个内部状态对象,代表着环境当前所处的状态。
    • State抽象状态角色, 可以是一个接口或者抽象类,定义了所有具体状态的共同接口或者是说动作行为,任何具体状态都要实现这些接口。
    • ConcreteState具体状态角色,处理来自Context的请求,每一个ConcreteState都提供了它自己对请求的实现,它要完成两个任务,一个是本状态下的行为管理,另一个是如何过渡到下一个状态。并且持有环境角色以实现状态的切换。
    public interface State {
        //行为1
        public void handle1();
        //行为2
        public void handle2();
    }
    public class ConcreteStateA implements State {
        private Context context;
    
        public ConcreteStateA(Context context) {
            this.context = context;
        }
    
        @Override
        public void handle1() {
            //当前状态下handle1行为的处理
            //...
        }
    
        @Override
        public void handle2() {
            //当前状态下handle2行为的处理
            //...
            this.context.setCurrentSate(Context.STATE_B);
        }
    }
    
    public class ConcreteStateB implements State {
        private Context context;
    
        public ConcreteStateB(Context context) {
            this.context = context;
        }
    
        @Override
        public void handle1() {
            //当前状态下handle1行为的处理
            //...
        }
    
        @Override
        public void handle2() {
            //当前状态下handle2行为的处理
            //...
            this.context.setCurrentSate(Context.STATE_A);
        }
    }
    public class Context {
        public static State STATE_A;
        public static State STATE_B;
        private State currentSate;
    
        public Context() {
            STATE_A = new ConcreteStateA(this);
            STATE_B = new ConcreteStateB(this);
        }
    
        public void setCurrentSate(State currentSate) {
            this.currentSate = currentSate;
        }
    
        public void handle1(){
            this.currentSate.handle1();
        }
    
        public void handle2(){
            this.currentSate.handle2();
        }
    
    }
    public class Client {
    
        public static void main(String[] args) {
            //创建环境对象
            Context context = new Context();
            //初始化状态
            context.setCurrentSate(new ConcreteStateA(context));
            //执行动作
            context.handle1();
            context.handle2();
        }
    }
    

    巴士公交车的例子

      如果经常乘坐巴士或公交车的朋友可能比较熟悉,公交车有几个状态,开门、关门、行驶、停车,对应状态下的行为是有一些规则的,比如公交车在行驶过程中是不允许开门不能上人的,只有在停止状态下并且开门状态下才能上人,并且必须是关门状态下才能够启动开始行驶。
      下面的表格中,我列举了巴士的所有状态和行为:

    状态 开门 关门 启动 停止 上人 下人
    开门停止状态 N Y N N Y Y
    开门运行状态 N Y N Y N N
    关门停止状态 Y N Y N N N
    关门运行状态 N N N Y N N

      先来看一下,不用状态模式的情况下,也就是我们通常的做法,是如何写代码来处理这些情况的:

    //巴士类
    public class Bus {
    
        /**
         * 开车门
         */
        public void openDoor() {
    
        }
    
        /**
         * 关车门
         */
        public void closeDoor() {
    
        }
    
        /**
         * 巴士开始行驶
         */
        public void run() {
    
        }
    
        /**
         * 停止巴士
         */
        public void stop() {
    
        }
    
        /**
         * 乘客上车
         */
        public void pickUpPassenger() {
    
        }
    
        /**
         * 乘客下车
         */
        public void dropOffPassenger() {
    
        }
    }
    public class Client {
        static String state;
        public static void main(String[] args) {
            Bus bus = new Bus();
            if (state.equals("开门停止")) {
                bus.pickUpPassenger();
                bus.dropOffPassenger();
                bus.closeDoor();
            } else if (state.equals("开门运行")) {
                bus.closeDoor();
                bus.stop();
            } else if (state.equals("关门停止")) {
                bus.openDoor();
                bus.run();
            } else if (state.equals("关门运行")) {
                bus.stop();
            }
        }
    }

      没错,你可能看到了熟悉的代码:很多的if-else条件判断语句,不管这里的state变量是字符串还是整型的常量,相信你平时写代码时一定写过类似的代码,而且有的时候判断的情况非常之多,或者是你是用switch-case来处理,都是类似的情况。
      下面来看一下如何用状态模式来处理这些情况,我们前面讲状态模式是将动作行为委托到状态类,因此我们的思路就转变为首先去建立相关的状态类。

    实现代码:

    /**
     * 巴士抽象状态类
     */
    public abstract class BusState {
        /**持有Bus的引用*/
        protected Bus bus;
    
        public BusState(Bus bus) {
            this.bus = bus;
        }
    
        /**
         * 开车门
         */
        public abstract void openDoor();
    
        /**
         * 关车门
         */
        public abstract void closeDoor();
    
        /**
         * 巴士开始行驶
         */
        public abstract void run();
    
        /**
         * 停止巴士
         */
        public abstract void stop();
    
        /**
         * 乘客上车
         */
        public abstract void pickUpPassenger();
    
        /**
         * 乘客下车
         */
        public abstract void dropOffPassenger();
    }
    
    /**
     * 开门停止状态
     */
    public class OpenedStoppedState extends BusState {
    
        public OpenedStoppedState(Bus bus) {
            super(bus);
        }
    
        @Override
        public void openDoor() {
            //啥都不做,因为已经是开门状态下了不用再开门了
        }
    
        @Override
        public void closeDoor() {
            System.out.println("巴士关门了");
            //关门之后,巴士应该变成关门停止状态
            this.bus.setCurrentState(Bus.CLOSED_STOPPED_STATE);
        }
    
        @Override
        public void run() {
            throw new UnsupportedOperationException("开门停止状态下禁止行驶");
        }
    
        @Override
        public void stop() {
            //啥都不做,因为已经是停止状态下了不用再停止了
        }
    
        @Override
        public void pickUpPassenger() {
            System.out.println("乘客上车");
        }
    
        @Override
        public void dropOffPassenger() {
            System.out.println("乘客下车");
        }
    }
    
    /**
     * 开门运行状态
     */
    public class OpenedRunningState extends BusState {
    
        public OpenedRunningState(Bus bus) {
            super(bus);
        }
    
        @Override
        public void openDoor() {
            //do nothing 已经是开门状态了,实际上这也是一个非法行为你也可以抛出异常
        }
    
        @Override
        public void closeDoor() {
            System.out.println("巴士关门了");
            //关门后,巴士变成关门行驶状态
            this.bus.setCurrentState(Bus.CLOSED_RUNNING_STATE);
        }
    
        @Override
        public void run() {
            //do nothing 已经是运行状态了
        }
    
        @Override
        public void stop() {
            System.out.println("巴士停车了");
            //停车后,巴士变成开门停车状态
            this.bus.setCurrentState(Bus.OPENED_STOPPED_STATE);
        }
    
        @Override
        public void pickUpPassenger() {
            throw new UnsupportedOperationException("开门运行状态下禁止乘客上车");
        }
    
        @Override
        public void dropOffPassenger() {
            throw new UnsupportedOperationException("开门运行状态下禁止乘客下车");
        }
    }
    /**
     * 关门停止状态
     */
    public class ClosedStoppedState extends BusState {
    
        public ClosedStoppedState(Bus bus) {
            super(bus);
        }
    
        @Override
        public void openDoor() {
            System.out.println("巴士开门了");
            //开门后,巴士变成开门停止状态
            this.bus.setCurrentState(Bus.OPENED_STOPPED_STATE);
        }
    
        @Override
        public void closeDoor() {
            //do nothing 已经是关门状态了
        }
    
        @Override
        public void run() {
            System.out.println("巴士开始行驶");
            //行驶后,巴士变成关门运行状态
            this.bus.setCurrentState(Bus.CLOSED_RUNNING_STATE);
        }
    
        @Override
        public void stop() {
            //do nothing 已经是停止状态了
        }
    
        @Override
        public void pickUpPassenger() {
            throw new UnsupportedOperationException("关门停止状态禁止乘客上车");
        }
    
        @Override
        public void dropOffPassenger() {
            throw new UnsupportedOperationException("关门停止状态禁止乘客下车");
        }
    }
    /**
     * 关门运行状态
     */
    public class ClosedRunningState extends BusState {
    
        public ClosedRunningState(Bus bus) {
            super(bus);
        }
    
        @Override
        public void openDoor() {
            throw new UnsupportedOperationException("关门运行状态禁止开门");
        }
    
        @Override
        public void closeDoor() {
            //do nothing 已经是关门状态了
        }
    
        @Override
        public void run() {
            //do nothing 已经是运行状态了
        }
    
        @Override
        public void stop() {
            System.out.println("巴士停车了");
            //停车后,巴士变成关门停止状态
            this.bus.setCurrentState(Bus.CLOSED_STOPPED_STATE);
        }
    
        @Override
        public void pickUpPassenger() {
            throw new UnsupportedOperationException("关门运行状态禁止乘客上车");
        }
    
        @Override
        public void dropOffPassenger() {
            throw new UnsupportedOperationException("关门运行状态禁止乘客下车");
        }
    }
    public class Bus {
        /**分别代表四种状态*/
        public static BusState OPENED_STOPPED_STATE;
        public static BusState OPENED_RUNNING_STATE;
        public static BusState CLOSED_STOPPED_STATE;
        public static BusState CLOSED_RUNNING_STATE;
        /**当前状态*/
        private BusState mCurrentState;
    
        public Bus() {
            OPENED_STOPPED_STATE = new OpenedStoppedState(this);
            OPENED_RUNNING_STATE = new OpenedRunningState(this);
            CLOSED_STOPPED_STATE = new ClosedStoppedState(this);
            CLOSED_RUNNING_STATE = new ClosedRunningState(this);
        }
    
        /**
         * 设置当前的状态
         */
        public void setCurrentState(BusState state) {
            mCurrentState = state;
        }
    
        /**
         * 开车门
         */
        public void openDoor() {
            mCurrentState.openDoor();
        }
    
        /**
         * 关车门
         */
        public void closeDoor() {
            mCurrentState.closeDoor();
        }
    
        /**
         * 巴士开始行驶
         */
        public void run() {
            mCurrentState.run();
        }
    
        /**
         * 停止巴士
         */
        public void stop() {
            mCurrentState.stop();
        }
    
        /**
         * 乘客上车
         */
        public void pickUpPassenger() {
            mCurrentState.pickUpPassenger();
        }
    
        /**
         * 乘客下车
         */
        public void dropOffPassenger() {
            mCurrentState.dropOffPassenger();
        }
    }
    public class Client {
    
        public static void main(String[] args) {
            Bus bus = new Bus();
            //设置初始状态为关门运行状态
            BusState initState = new ClosedRunningState(bus);
            bus.setCurrentState(initState);
    
            //测试正常情况:停车->开门->下车->上车->关门->行驶
            bus.stop();
            bus.openDoor();
            bus.dropOffPassenger();
            bus.pickUpPassenger();
            bus.closeDoor();
            bus.run();
    
            //测试非正常情况1:关门行驶的时候去开门
            bus.setCurrentState(initState);
            bus.openDoor();
    
            //测试非正常情况2:门未关上就开始行驶
            bus.setCurrentState(new OpenedStoppedState(bus));
            bus.run();
        }
    }

    测试正常情况输出:
    这里写图片描述
    测试非正常情况1输出:
    这里写图片描述
    测试非正常情况2输出:
    这里写图片描述
      可以看到在状态模式实现的代码中,将以往的if-else条件判断转换为了四个相关的状态类来处理,客户端在使用的时候,无需关心当前是哪个状态,它只要执行具体的行为就可以,至于这些行为是否可以在当前状态下得到正确的响应完全由当前的状态类内部去处理。每一个状态类都拥有Context的所有的行为接口方法。在某一个状态类的内部实现中,我们看到,如果一个行为可以执行,那么就实现该行为的代码,如果一个行为在这个状态下是非法的或者禁止的,那么就抛出异常或者你什么也不做。

    理解状态和行为

      状态就是当前环境所处的情况或者是场景,在不同场景下当前环境对于不同行为要给出不同的响应,具体在代码中的体现可以理解为就是你的if-else判断。而行为就是你要执行的动作,你要做的事情,你要给出的响应。例如人冷了要加衣服,热了要脱衣服,冷热就是状态,而加衣脱衣就是行为。

      如图,状态模式下做的事情就是,由以往的Context上下文环境自己来挑选判断执行哪种行为,变成了由对应的状态类去挑选和执行哪种行为。状态类会对每一种行为都做出响应,这些响应可以是执行动作的响应,也可以是一种非法提醒的反馈响应,也可以什么都不做,这些要根据你的具体的业务来判断。对于环境来说,它的动作执行流程从表面上看是流畅的不被打断的(不被if-else的结构所破坏)。

    状态模式的优点

    • 结构清晰,避免了过多的 switch- case 或者 if- else 语句的使用,避免了程序的复杂性,提高系统的可维护性。
    • 封装性强,遵循设计原则,很好地体现了开闭原则和单一职责原则,每个状态都有一个子类负责,你要增加状态就要增加子类,你要修改状态,你只修改一个子类就可以了。另外也体现了迪米特法则,状态变换完全放到类的内部来实现,屏蔽了客户端调用的时候对状态处理的感知。

    状态模式的缺点
      缺点很明显,那就是子类会太多,因为每一个状态都对应一个子类,所以当你的状态非常多的时候就会发生类膨胀。

    状态模式和策略模式的区别

      状态模式和策略模式有着相同的类图, 但是它们的意图不同。策略模式更加侧重于行为或算法的替换,并且可以在运行时动态的任意替换,侧重点是使用不同算法族来解决问题。而状态模式更加侧重于状态的改变影响改变行为,而行为的执行结果又会导致状态发生变化,是一个状态和行为的变化过程。策略模式需要客户端必须完全知晓所有的策略方法,才能够知道究竟哪一个策略是当前需要的。而状态模式客户端在使用的时候,可以不必关心有哪些状态,他只需要去调用环境的行为就可以了,在环境的内部维护了这些状态。

    状态模式的使用场景

    • 行为随着状态的改变而改变的时候,这也是状态模式的根本出发点,例如权限设计,人员的状态不同即使执行相同的行为结果也会不同,在这种情况下需要考虑使用状态模式。
    • 条件、分支判断语句的替代者,在程序中大量使用 switch 语句或者if-else判断语句会导致程序结构不清晰,逻辑混乱,使用状态模式可以很好地避免这一问题。

      虽然状态模式可以很好的处理行为受状态约束的情况,但相应的对象的状态也会增加,所以在实际项目中使用的时候,要权衡利弊,考虑它对你的设计带来的后果影响是否可以接受。如果状态太多比如十几个或者几十个,还是建议不要使用了。


    参考:

    展开全文
  • 程序员请照顾好自己,周末病魔差点一套带走我。

    万次阅读 多人点赞 2019-12-22 21:18:37
    程序员在一个周末的时间,得了重病,差点当场去世,还及时挽救回来了。

    你知道的越多,你不知道的越多

    点赞再看,养成习惯

    本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试点思维导图,也整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。

    12月21日 早上9:00,一如既往的跟三歪走到了去公司的路上,不过今天感觉脑袋沉沉的,不知道是不是生病了,不过倒也无伤大雅,或许是起早了还没睡醒吧。

    其实我很怕死的,所以一点点症状都会马上吃药,所以一到公司我就喝了感冒冲剂,还吃了点感冒胶囊。

    如图,我还是很机智的喝了感冒冲剂的,当时天真的自己并不知道,是没有用的。

    开始冲冲冲(一般我和三歪管写文章叫冲冲冲),写了粉丝的百度+京东的面试过程,但是没写多少就发现很不在状态,于是我加大量喝热水。

    没多久,我发现自己出现了腰酸,膝盖酸的迹象,这感觉要凉的节奏呀。

    于是我和小伙伴们说我们去有药店的茶餐厅吃饭吧,这样吃饭完了可以直接去买药,因为我知道我自己吃的那些药基本上都没啥用,估计是发烧了,不是普通的感冒。

    跟医生说明了情况,给我开了退烧和止咳糖浆,这个时候我还很开心,应该吃完了就好了,殊不知一个十分煎熬的晚上正在等着我。

    晚上到家烧了一壶开水,洗了热水澡,早早的躺在了床上,看了一眼时间,20:16,眼皮开始打架了,应该睡一觉就万事大吉了,嗯肯定是这样,于是我睡着了。

    我梦见自己浑身发热,全身都在流汗,仿佛在富士山下的温泉中肆意遨游,我被热醒了。

    而且确实是满身大汗,想来看着自己湿哒哒的头发,我心想,这应该已经是第二天了吧,而且我出这么多汗应该是好了吧。

    下意识的拿起手机,什么?看着手机上的22:00,居然才过去两个小时,而且我发现为啥腰和膝盖这么酸疼?

    一定是错觉,我继续洗个热水澡应该就好了,于是我又洗了个澡,浑身冒汗那种。

    继续躺下,准备再次入睡。

    噩梦就这样开始了,11点、12点、1点、2点、3点………

    我不知道在床上翻来覆去多少次,因为腰酸疼、膝盖、手腕关节的酸疼,根本无法忍受,满脑子都是✨。

    我住的地方的天花板上还有个亮光,我也不知道看了多久,胡想了多久。

    你说你割我一刀,那种疼我都能忍,但是这种酸疼是真的难以忍受!

    我不断的换着睡姿,时而趴着,时而蜷缩着,时而…….

    然而一点*用都没有,中间还有一个我记忆很深的梦,就是我只是治好了自己的膝盖疼我就可以拿到什么什么。

    我现在回想起来,才知道,高烧,已经开始侵蚀我的脑神经了,中间,各种情绪都铺天盖地的袭来,想家了,想自己健康活蹦乱跳的种种了,想起我们村的村花了。

    终于天亮了,我的噩梦结束了,但是病状已经是我无法控制的了,我下楼去了买药的药店,主动要求医生给我量体温,以及说明了自己的情况。

    38°3是的,药店阿姨发现我高烧不退,推测我可能得了病毒性流感,推荐我去医院,加上自己也知道现在的情况无法通过一点药物缓解症状了。

    38°9是的这是医院医生给我量的体温,我打车到挂号就诊也才过去半个多小时,体温直接上升了0.6°。

    我挂的是内科的门诊,医生发现我的症状比较严重,推荐我去发热门诊,挂急诊。

    甲型流感”,听到这个的时候我懵逼了,我以为我要没了,不过医生并未表现得多惊讶,并且告诉了我情况。

    这难道就是格局?不知道医生是见多了见怪不怪,还是觉得我没救了。

    11管血,CT,胸透,心电图…….一套流程丝毫不拖泥带水。

    是的不知道抽了几次血,抽一次还要抽几管那种,不过为了确保病情这一切都是值得的。

    感触最大的就是做心电图的时候,躺在病床上,医生把冰冷的仪器放在你的身上,当时我就多想了,把那想成一个手术台了,就是那种人为刀俎,我为鱼肉的感觉,再也不要生病了。

    确诊了,就是流感,还跟别的有点不一样,医生说:你叫家里准备一下吧。

    呸呸呸,开玩笑的,小姐姐和医生全程都呵护着我,吃药,体检,抽血化验。

    我还吃了他们的试验药,其实我想好快点,所以想富贵险中求,实在是太难受了。

    我也不多BB了,化验结果应该马上就要出了,准备就要打车回去了。

    看到这里你应该知道了,这两天我文章一篇没写,下周注定是不平凡的一周,我得请假经常去医院,吃饭还得跟小伙伴隔离了。

    而且因为部门调动,下周我跟三歪也分开了,他去业务中台,我去数据中台,只有周末冲冲冲才可以见面了。

    回来的路线看着窗边飞驰的景色,我感觉这就像是一场梦,我多希望这真的就是一场梦呀,昂因为太困了路上我睡着了。

    因为感觉舒服了很多,就还是来到了公司准备把稿子排版发出去,希望给大家一个反面教材。

    总结

    通过这个故事我想你也知道了,照顾好自己,以及第一时间去医院多么重要,特别是我们程序员经常加班免疫力下降,很容易被病毒侵蚀,你永远不知道病原体会携带什么病毒。

    出来打工本来就不容易了,我们一定要照顾好自己,老妈跟我打电话的时候,我能听到她的哽咽,生病了最心疼你的肯定是家人。

    生活不易且行且珍惜。

    絮叨

    另外,敖丙把自己的面试文章整理成了一本电子书,共 1630页!目录如下

    现在免费送给大家,在我的公众号三太子敖丙回复 【888】 即可获取。

    我是敖丙,一个在互联网苟且偷生的程序员。

    你知道的越多,你不知道的越多人才们的 【三连】 就是丙丙创作的最大动力,我们下期见!

    注:如果本篇博客有任何错误和建议,欢迎人才们留言!


    文章持续更新,可以微信搜索「 三太子敖丙 」第一时间阅读,回复【资料】有我准备的一线大厂面试资料和简历模板,本文 GitHub https://github.com/JavaFamily 已经收录,有大厂面试完整考点,欢迎Star。

    展开全文
  • 如果你不熟悉 App 定制型状态通道的话,先读本系列 Part-2,它能给你提供一个很的概览。 什么是广义状态通道? 广义状态通道的意思是,用户可以用同一个通道做多种不同的事情。 广义状态通道有何意义...

    Part-1:支付通道
    Part-2:App 定制型状态通道
    Part-3:多跳交易/中心辐射通道
    Part-4:账本通道和虚拟通道


    注意阅读本文需要一些 App 定制型状态通道的背景知识。如果你不熟悉 App 定制型状态通道的话,先读本系列 Part-2,它能给你提供一个很好的概览。

    什么是广义状态通道?

    广义状态通道的意思是,用户可以用同一个通道做多种不同的事情。

    广义状态通道有何意义?

    没有状态通道,任何以太坊上的 App 都必须承担高额手续费,忍受延迟,因为 App 高度依赖于链上交易。使用 App 定制型状态通道,我们可以创建更经济更高效的 App ,用户只要在启动和关闭 App 时支付就可以了。广义状态通道更进一步地改善了这种情况,用户只需要在关闭 App 时支付。

    注意当我说“支付”的时候,我的意思是向链上提交交易

    广义状态通道

    在技术上,要开启广义状态通道,所需要求与 App 定制型状态通道一般无二:一个足够强大的多签钱包就足够了,参与者用于锁住状态。区别在于,用户无需为每一个应用都“安装”链上组件——即便要使用多个应用,该多签钱包也将是用户所需的唯一链上组件

    App 定制型状态通道(回顾)

    鉴于在部署链上组件这一点上差别极大,我们先回顾一下我们在前面的文章中讲到的内容。在前文中,我们遵循下列步骤在多方间打开一个 App 定制型状态通道:

    1. 与相关方一起,部署一个多签钱包,把规则集(用来解析发送给钱包的交易)加到链上。
    2. 在他们进行不同的操作时,在参与者之间广播已签名的消息。
    3. 当参与者准备好开启或退出通道时,他们会把所有参与者签名的最新状态提交到多签钱包,多签钱包根据内置的规则集,决定如何在参与者之间分钱。

    这种配置看起来就是下图的样子:

    -在任何时候,Bob 和 Alice 都可以把双方都签过名最新状态提交到多签钱包,来配置通道。-

    注意,上述过程所用的多签钱包只支持符合其内置规则集的 App 。再次强调,广义状态通道通过“反事实实例化(Counterfactual Instantiation)”扩展了 App 定制型状态通道的功能:允许新的 App 安装在现有的状态通道中。

    反事实实例化

    反事实实例化是一个通道内成员同意接受链下智能合约约束过程。这是一个比较奇怪的概念,因为它意味着“链下代码即法律”(给 Liam Horne 点小费吧,这是他提出的),一下是一个简单的例子:

    - So Easy (作者你是认真的吗?)-

    要创建广义状态通道,我们唯一需要的就是一个多签钱包。我跟阿剑各往钱包了存了 5ETH,并且决定要在我们之间创建一个支付通道。所以,我们在链下创建了一个支付通道,并且都对合约代码签过了名,同意在关闭通道时部署它。我们同样也对基于已部署的支付通道的最终状态、发往多签钱包的条件支付请求签了名。

    那么,使用同样的方式——所有参与者都签名,我们不仅能保证状态的可信,也能保证代码的可信。所以,只要我们都签署了代码,我们就可以像该代码已在链上部署的那样,放心地签署相关的状态。两种方式最主要的不同就是,我们只需要在想要结算状态通道时部署代码

    那么,当我们想结算时的时候,我们需要:

    1. 部署支付通道合约
    2. 向该合约提交所有参与者签名的最新状态
    3. (基于支付通道的余额)将条件支付请求提交给多签钱包
    4. 多签钱包给各参与方支付

    那么,反事实实例化使我们可以假设链下代码已经被部署到了链上,并据此行动;因为我们可以在任何时候部署上链并提交最新状态。但是,这就有个问题——我们如何在没有链上地址的情况下签署状态转换?这就是注册合约的用武之地!

    注册

    从比较抽象的层面上讲,注册器智能合约允许我们做以下操作:

    • 基于合约字节码,创建一个链下地址(cfAddress)
    • 部署智能合约,并把 cfAddress 和链上地址进行映射
    • 通过 cfAddress 执行链上合约代理调用

    注册合约伪代码:

    contract Registry {
      mapping(bytes32 => address) resolver;
      function cfAddress(bytes code) returns (bytes32) { ... }
      function deploy(bytes code) { ... }
      function proxyCall(Registry r, bytes32 addr, bytes data) { ... }
    }

    所以,如果你想部署一个合约,你需要用交易调用 deploy 函数,并以合约的 initcode(初始码)作为参数(一般来说,它是与 ABI 编码的构造函数参数连接的合约构造函数字节码)。这个函数把智能合约部署到链上,并且把合约地址加到注册映射表中。

    以这种方式,你可以通过注册表中的解析器创建相互引用并互相依赖的链下合约。那么,要是想让我们上述例子中的通道运行起来,我们就得通过注册合约来部署支付通道,在多签钱包的条件支付中解析出支付通道的地址。

    依赖

    注册合约允许我们做的就是可以建立互相依赖的链下合约,就像合约 A 依赖于合约 B,只有在 B 最终确定之后,A 才能确定(条件层级确定性)。

    -以上我们可以看到,除非 Nonce 合约确定了,否则 PC 合约无法确定。-

    你看,上面是一个比较基础的例子,我们要求当前合约基于另一个合约的布尔条件值。我们可以扩展这个条件,允许所谓的“原子状态转换”。

    原子状态转换

    根据这种层级的依赖结构,我们可以进行原子状态转换,转换的同时,伴随着一些合约生效,一些合约失效。下面例子表明,一个 10 ETH 的支付通道,基于 nonce 值,转换为一个 8 ETH 的支付通道,加一个 2 ETH 的扑克游戏。

    -合约的有效性基于 nonce 值-

    如果支付通道的双方都同意用支付通道里的 2 ETH 来创建一个扑克游戏,他们可以签署支付通道的余额更新变化,从(5,5)到(4,4),同时签署一个内置 2 ETH 的扑克合约,nonce 合约的 nonce 值是 4 的时候,这两个合约才会生效。

    -基于新 nonce 值的原子状态转换-

    当支付通道的双方都签署了支付通道和扑克合约的条件更新之后,他们可以签署 nonce 合约,使得 nonce 值加 1。一旦 nonce 值更新为 4,旧的支付通道状态就会失效,同时扑克合约和新的支付通道状态就会生效。

    有原子状态转换,代码升级就会变得容易。如果之前支付通道的参与双方想修复代码中的 bug,他们可以在更新余额的时候修复代码。当更新 nonce 值后,之前有 bug 的代码就失效了。

    下面有个例子,这就是基于“根 nonce”合约的一系列反事实合约:

    根据这种架构,我们可以通过一个“根 nonce”合约有条件地更新所有链下合约的有效性。这允许我们可以根据参与方的需求,迭代地从状态通道中添加和删除链下合约。

    配置通道

    假设我和阿剑想玩四子连珠的游戏。我们将会这样做:

    1. 部署根 nonce 合约、ETH 支付通道(PC)、ETH 条件支付通道(CPC)和四子连珠智能合约
    2. 向四子连珠游戏提交最新的签过名的状态
    3. 基于四子连珠的游戏规则确定 CPC
    4. 基于 CPC 确定 PC
    5. 向多签钱包提交已签名的条件支付(基于 PC 的最终确定状态进行支付)

    因此,我们可以一直开启其他状态通道,甚至允许我们重用已经部署在链上的四子连珠游戏的代码。下一次我们想要玩游戏的时候,我们只需要对游戏状态进行签名,然后提交到已经部署好的智能合约上。唯一需要实现的是取消现有链上代码的确定性,这是一个实现细节。

    注意你不需要像我展示的四子连珠、CPC 和 PC一样,为你的合约加上这么多的依赖。无论你希望怎么做,这都取决于你和你状态通道中的伙伴

    现在,假设阿剑的朋友 Hunter 想跟阿剑玩四子连珠游戏,但是他只跟我开了一个状态通道,这时候 Metachannels 就可以派上用场啦。

    Metachannels

    Metachannels 是状态通道上的虚拟通道(参见本系列 Part-4)。要创建一个 Metachannels,你需要两个想交互的参与者,他们各自有一个状态通道,并且通道的另一方是同一个人。两个参与者同意创建一个新的合约,通道另一方(即共同的中心)会与他们一起创建一个代理合约,指向两个参与者的新合约。看起来就像下面这张图:

    -广义虚拟状态通道 = Metachannels !-

    我们可以无限地扩展这个模型,让我们想跟谁玩四子连珠,就能跟谁玩。

    广义状态通道的优点

    • 引导——因为我们所需要的只有一个多签钱包,我们可以很容易在链上现有的多签钱包中选择一个开始开发。
    • 隐私——除了参与者之外,没有人知道状态通道内发生了什么,对于外部世界来讲,参与者之间只有一个多签钱包。
    • 可升级——如果链下代码中有 bug,所有参与者可以通过链下的操作修复 bug,不需要进行任何链上操作。
    • 可重用——这种方法有效地鼓励了通用链上库的形成,让所有状态通道都可以引用。

    谁在开发广义状态通道?

    这篇博文是 Liam Horne 在 7月的 Binary District 的 “Off the Chain” 研讨会上的演讲总结。Liam 是 Counterfactual 团队的一员,致力于“开发有实践意义的工程,让状态通道在实际应用中发挥作用”。如果你有兴趣了解更多他们的研究,或是使用他们的架构/设计模式,我在下面列出了他们的网站和 GitHub 连接。

    Part-6:反讹诈

    在我下一篇博文中,我将会深入讲解状态通道中的反讹诈。讹诈即是说参与者向通道提交一个对自己更有利的较早状态。博文的焦点是 Pisa.

    深度阅读

    我非常鼓励大家看完 Binary Distric 的研讨会,他们是我目前找到的这方面的最好的资源。


    链接: https://medium.com/blockchannel/state-channels-for-dummies-part-5-6238f83f8da3

    展开全文
  • android状态栏一体化(沉浸式状态栏)

    万次阅读 多人点赞 2014-12-01 09:56:22
    在android kitkat 有一个新的特性可以设置手机状态栏的背景,手机整个界面的风格保持一致,看起来非常清爽,在今年的google i/o上的android l默认就是这种风格。来现在看我们怎么加上这个酷黑狂拽掉渣天的功能怎么...
  • android 变色状态

    千次阅读 2016-05-10 17:04:10
    最近想着让自己做的app看起来好看点。。所以给自己的app添加了可以变色的状态栏。。我没有做向下的兼容。。。只能手机版本是4.4及以上的手机使用。网上有人叫沉浸式,我觉着这边博主的解释是正确的: Android 实现...
  • TCP连接的状态详解以及故障排查

    万次阅读 多人点赞 2014-08-20 07:06:38
    我们通过了解TCP各个状态,可以排除和定位网络或系统故障时大有帮助。(总结网络上的内容) 1、TCP状态 了解TCP之前,先了解几个命令: linux查看tcp的状态命令: 1)、netstat -nat 查看TCP各个状态的数量 2)...
  • 说起状态模式游戏开发者们第一个想到的一定是AI的有限状态机FSMs,状态模式确实是实现有限状态机的一种方法。在有限状态机中,一般都是观察者模式与状态模式连用,状态模式把每个状态封装成类,来对每个输入消息...
  • 游戏开发过程中,各种游戏状态的切换无处不在。但很多时候,简单粗暴的if else加标志位的方式并不能很地道地解决问题,这时,就可以运用到状态模式以及状态机来高效地完成任务。状态模式与状态机,因为他们关联紧密...
  • 我个人初学对于自己管理比较理解,对于父控件管理理解起来有点困难,所以只能多看多学。这里写一下两种状态管理的方式和代码,加深自己的印象,尤其是父控件管理方式。 项目说明:两种方式实现一个容器盒子,点击...
  • 详解以太坊世界状态

    万次阅读 2019-05-12 09:21:15
    以太坊是由多个组成部分构成的。这篇文章旨在解构以太坊,使你能...本文同时和一篇手把手学习指引相关联,它能指导你安装并配置好自己的以太坊私有网络(包括挖矿)。学习之后你将能够执行交易,并且探索以太坊的“...
  • 状态机设计

    千次阅读 2014-03-22 09:18:47
    参考了网上的一些前辈blog和自己搜集到的资料,整理了一下读书笔记,虽然内容基本上都是别人写的,但是整理起来也好累 = = 1. 有限状态机FSM(Finite State Machine) 组成元素:输入、状态、...
  • 我想车跑得更怎么办?
  • 状态机 精讲

    千次阅读 2014-11-03 10:06:57
    参考了网上的一些前辈blog和自己搜集到的资料,整理了一下读书笔记,虽然内容基本上都是别人写的,但是整理起来也好累 = =       1. 有限状态机FSM(Finite State Machine)   组成元素:输入...
  • Tomcat学习--tomcat运行状态监控

    千次阅读 2018-05-02 20:43:42
    上一篇博客Tomcat学习--war服务相关状态信息监控中我们已经了解了一下对war包的... 目前tomcat将运行的过程中的一些状态信息通过JMX的MBeanServer机制保存起来,所以目前的实现就是通过MBeanServer来获取数据就...
  • Git笔记(5) 状态记录

    万次阅读 2020-02-10 20:24:32
    文件的状态变化周期、检查当前文件状态、跟踪新文件、暂存已修改文件、状态简览、忽略文件、查看已暂存和未暂存的修改、提交更新、跳过使用暂存区域、移除文件、移动文件
  • 设计模式-状态模式State-电梯状态

    千次阅读 2015-04-07 17:08:25
    1.概述 ...但是对复杂状态的判断就显得“力不从心了”。随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱。
  • StateMachine状态机初识

    千次阅读 2017-11-14 16:08:44
    http://www.cnblogs.com/bastard/archive/2012/06/05/2536258.html为了更加方便的理解,个人简单的画了一张时序图:具体的使用:要实现自己的StateMachine并它跑起来,需要做以下几个工作: 一 . 实现自己的State...
  • 一,系统设计:有状态、无状态惯例,先看栗子网站登录校验,很普通的一个功能 对于这个功能我们要如何实现?先分析一下登录校验是个啥意思 举个栗子,比如我们在登陆页输入用户名密码,登录了社交网站 这时候想去...
  • Android状态栏微技巧,动态控制状态栏显示和隐藏

    万次阅读 多人点赞 2017-04-18 15:31:29
    记得之前有朋友在留言里我写一篇关于沉浸式状态栏的文章,正巧我确实有这个打算,那么本篇就给大家带来一次沉浸式状态栏的微技巧讲解。其实说到沉浸式状态栏这个名字我也是感到很无奈,真不知道这种叫法是谁先发起...
  • 【C++】状态模式

    千次阅读 2015-10-15 19:24:21
    状态模式也是设计模式的一种,这种设计模式思想不复杂,就是实现起来的代码有点复杂。主要出现在类传递参数上,尤其是C++这种不能直接类间互相调用都语言,实现状态模式更难,当然,一切设计模式都是为了更简短的...
  • JavaScript状态模式及状态机模型这是一篇,我自己都看不完的文章…文章大体就两部分: 状态模式的介绍 状态机模型的函数库javascript-state-machine的用法和源码解析 场景及问题背景:我们平时开发时本质上就是对...
  • TCP状态详解-状态

    千次阅读 2015-07-29 15:16:43
    tcp状态: LISTEN:侦听来自远方的TCP端口的连接请求 SYN-SENT:再发送连接请求后等待匹配的连接请求 SYN-RECEIVED:再收到和发送一个连接请求后等待对方对连接请求的确认 ESTABLISHED:代表一个打开...
  • 帧同步和状态同步(二)案例分析

    千次阅读 2017-11-01 09:29:52
    转自:http://www.gameres.com/489361.html腾讯...自从去年了解到即时游戏帧同步这门技术,我就一直关注使用这个技术的游戏,一直没有发现,虽然我们自己的游戏也是采用的帧同步,毕竟还没有上线,现在线上有帧同步的
  • TCP状态

    千次阅读 2018-06-13 21:42:16
    运维工作中,和TCP打交道的时间还是比较多,抓抓包,看看连接,排查一下服务器性能等。...来一张经典的图来镇楼要直接记住这幅图不容易,因为涉及的状态很多,要一个一个的去理解,然后再串联起来,融会贯通...
  • 单片机的状态机介绍

    万次阅读 多人点赞 2016-05-24 11:50:24
    单片机的葵花宝典 霍宏鹏著 目录 第1章 单片机初试牛刀 1 ...第2章 状态机的通俗解释 3 2.2 状态机具体化 4 第3章 状态机在单片机上的应用 5 3.1 代码实现步骤 5 3.2 应用代码详解 5 第4章 简单的举例 8...
  • 游戏后台状态同步与帧同步

    千次阅读 2017-11-11 23:19:12
    一般的流程是客户端上传操作到服务器,服务器收到后计算游戏行为的结果,即技能逻辑,战斗计算都由服务器运算,然后以广播的方式下发游戏中各种状态,客户端收到状态后,更新自己本地的动作状态、Buff状态,位置等就...
  • 简单层次状态机的C语言实现

    千次阅读 2018-02-09 17:35:29
    简单层次状态机的C语言实现 一年前同学推荐开个博客,还确实有写博客的想法,当时正在过年,可能吃的太了吧,反正后来这事就不了了之。临近年关,突然又想起来这事。工作两年多来也积累了不少东西,不过一直苦于...
  • iOS应用程序状态切换相关

    万次阅读 热门讨论 2011-12-25 22:34:06
    一、iOS应用程序状态机一共有五种状态: 1. Not running:应用还没有启动,或者应用正在运行但是途中被系统停止。 2. Inactive:当前应用正在前台运行,但是并不接收事件(当前或许正在执行其它代码)。一般每当应用...
  • Android 沉浸式状态栏的几种实现方式

    千次阅读 2016-10-20 17:04:59
    Android 沉浸式状态栏的几种实现方式沉浸式状态栏,说通俗一点,就是使状态栏的背景颜色与我们的 App 标题栏看起来一致,或者就是将状态栏隐藏,打造全屏的 App 。 方法1: 状态栏设置为透明原理是将状态栏透明化,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 682,758
精华内容 273,103
关键字:

如何让自己状态好起来