正确的状态模式实施

时间:2020-07-03 19:21:14

标签: c# oop design-patterns

帮我弄清楚State模式。有一个任务-编写一个模拟打开和关闭PC的程序。系统提示我使用State模式。但是我不确定我是否正确使用它。 我的turn pc模型与真实模型有一些共同点,但肯定不能肯定。因此,我将引导过程分为几个阶段-开启计算机,引导加载程序1-3级别并加载内核os。 Program structure

在每个阶段,除了实现已实现接口的方法之外,还执行其动作。在实现接口方法时,我为pc的状态分配了一个新对象。我这样做是因为在示例中看到了类似的操作。但是我不知道以后如何使用。

接口:

    internal interface IPCState
    {
        bool TurnON(Computer computer);

        bool TurnOff(Computer computer);
    }

该方法在以下阶段之一中的示例实现:

// Level 1 bootloader.Master boot record
    internal class LoaderOfTheFirstLevel : IPCState
    {
        public bool TurnOff(Computer computer)
        {
            throw new NotImplementedException();
        }

        public bool TurnON(Computer computer)
        {
            // If the self-testing stage has been successfully completed, this means that the processes of the first stage are completed successfully we move on
            if (POST())
            {
                computer.State = new LoaderOfTheSecondLevel();
                return true;
            }
         
            return false;
        }

        // Self-test: we check hardware failures, one signal after POST signals that everything is in order.
        private bool POST() => true;
    }

在main方法中,我调用每个阶段的实例构造函数并将结果放入列表中。最后,如果所有阶段均正常进行,则PC将启动并可以使用。 预先感谢。

主要:

static void Main()
        {
            List<bool> operationRes = new List<bool>();

            PowerSocket.SetElectricityState(true);
            Computer computer = new Computer(new SystemStartup());
            operationRes.Add(computer.TurnOn());
            computer = new Computer(new LoaderOfTheFirstLevel());
            operationRes.Add(computer.TurnOn());
            computer = new Computer(new LoaderOfTheSecondLevel(operationRes.Last()));
            operationRes.Add(computer.TurnOn());
            computer = new Computer(new LoaderOfTheThirdLevel(operationRes.Last()));
            operationRes.Add(computer.TurnOn());
            computer = new Computer(new BootLoaderOSKernel(operationRes.Last()));
            operationRes.Add(computer.TurnOn());

            if (operationRes.All(r => r))
            {
                Console.WriteLine("OS is ready to work");
            }
            else
            {
                Console.WriteLine("Error");
            }

            Console.ReadLine();
        }

有人可以解释我做错了吗?

1 个答案:

答案 0 :(得分:3)

当前,您的IPCState方法接受计算机。而是,计算机应具有状态。而且,状态应返回状态;这就是状态机的工作:在输入某些内容的情况下获取状态,然后返回状态。

在这里,客户端要求计算机启动()。计算机通过POST开始启动,然后加载启动设备,转移到引导加载程序,然后再转移到内核。内核永不返回。如果是这样,就慌了。

pc_boot

using System;
    
public interface IComputerState
{
    IComputerState load();
}

public class PanicState : IComputerState {
    public IComputerState load() {
        Console.WriteLine("Kernel panic!");
        System.Threading.Thread.Sleep(500);
        return new PanicState();
    }
}

public class KERNEL : IComputerState {
    public IComputerState load() {
        Console.WriteLine("Kernel started...");
        return new PanicState();
    }
}

public class BOOTLOADER : IComputerState {
    public IComputerState load() {
        Console.WriteLine("Bootloader started...");
        Console.WriteLine("Changing memory model...");
        Console.WriteLine("In long-mode...");
        return new KERNEL();
    }
}

public class LOAD_MBR : IComputerState {
    public IComputerState load() {
        Console.WriteLine("Found boot device...");
        Console.WriteLine("Loading boot device...");
        return new BOOTLOADER();
    }
}

public class POST : IComputerState {
    public IComputerState load() {
        Console.WriteLine("POST...");
        return new LOAD_MBR();
    }
}

public class Computer
{
    IComputerState state;
    
    public Computer() {
        state = new POST();
    }
    
    public void boot()
    {
        Console.WriteLine("booting...");

        while (true) {
            state = state.load();
            System.Threading.Thread.Sleep(200);
        }
    }
}

public class Program
{
    public static void Main()
    {
        Computer c = new Computer();
        c.boot();
    }
}
booting...
POST...
Found boot device...
Loading boot device...
Bootloader started...
Changing memory model...
In long-mode...
Kernel started...
Kernel panic!
Kernel panic!
Kernel panic!