Bezestavové OOP

BoneFlute

  • *****
  • 2 047
    • Zobrazit profil
Re:Bezestavové OOP
« Odpověď #15 kdy: 30. 01. 2018, 21:56:34 »
Pokud není stav sdílený mezi vlákny tak stavovost objektů nikdy nevadila.

Mě jo.


Honza

Re:Bezestavové OOP
« Odpověď #16 kdy: 30. 01. 2018, 22:05:22 »
Smím se zeptat, kam ten stav v OOP ukládáte, když ne do objektu? ^^

balki

Re:Bezestavové OOP
« Odpověď #17 kdy: 30. 01. 2018, 22:14:27 »
OOP je stavove. Ak je to bezstavove, tak to nie je OOP, ale nieco ine.

Kit

Re:Bezestavové OOP
« Odpověď #18 kdy: 30. 01. 2018, 22:38:01 »
Smím se zeptat, kam ten stav v OOP ukládáte, když ne do objektu? ^^

Stav se do immutable objektu ukládá, ale jen v konstruktoru.

BoneFlute

  • *****
  • 2 047
    • Zobrazit profil
Re:Bezestavové OOP
« Odpověď #19 kdy: 30. 01. 2018, 22:53:14 »
OOP je stavove. Ak je to bezstavove, tak to nie je OOP, ale nieco ine.

S tím dokážu žít.


anonym

Re:Bezestavové OOP
« Odpověď #20 kdy: 30. 01. 2018, 22:54:19 »
OOP je stavove. Ak je to bezstavove, tak to nie je OOP, ale nieco ine.

OOP je přece hlavně o tom, když to porovnám s procedurálním strukturovaným programováním (třeba v C), že ti přímo umožňuje nad moduly (třídy) provádět polymorfismus. To je nejdůležitější vlastnost. Druhá vlastnost je, že máš přimou podporu pro zapouzřenost (pomocí přístupových modifikátorů), což by měl každý modul splňovat. Nejméně důležitá vlastnost je pak ta, že ti umožňuje vytvářet moduly, které rozšiřují nějaké moduly (dědičnost).

Jestli budeš dělat objekty stavové nebo bezestavové, to je pak už úplně podružné.

Kit

Re:Bezestavové OOP
« Odpověď #21 kdy: 30. 01. 2018, 23:07:53 »
Druhá vlastnost je, že máš přimou podporu pro zapouzřenost (pomocí přístupových modifikátorů), což by měl každý modul splňovat.

Přístupové modifikátory porušují zapouzdřenost, proto by se neměly používat. Atributy objektu mají být privátní, mají s nimi pracovat pouze metody objektu. Okolí by vůbec nemělo vědět, jaké má objekt atributy. Měly by být zcela skryty, tedy zapouzdřeny.

UF

Re:Bezestavové OOP
« Odpověď #22 kdy: 30. 01. 2018, 23:08:09 »
hasismarja

Kit

Re:Bezestavové OOP
« Odpověď #23 kdy: 30. 01. 2018, 23:15:52 »
hasismarja

To je nějaký nový typ bezstavového objektu? :D

anonym

Re:Bezestavové OOP
« Odpověď #24 kdy: 30. 01. 2018, 23:19:07 »
Druhá vlastnost je, že máš přimou podporu pro zapouzřenost (pomocí přístupových modifikátorů), což by měl každý modul splňovat.

Přístupové modifikátory porušují zapouzdřenost, proto by se neměly používat. Atributy objektu mají být privátní, mají s nimi pracovat pouze metody objektu. Okolí by vůbec nemělo vědět, jaké má objekt atributy. Měly by být zcela skryty, tedy zapouzdřeny.

A co metody? Navíc, jak budeš dělat mocky, když atributům nedáš gettery a settery? Můžeš je sice vytáhnou reflexí, ale potom zase ztratíš možnost refaktrorovat názvy atributů, aniž by jsi musel všechny unit testy upravit.

Kit

Re:Bezestavové OOP
« Odpověď #25 kdy: 30. 01. 2018, 23:27:08 »
Druhá vlastnost je, že máš přimou podporu pro zapouzřenost (pomocí přístupových modifikátorů), což by měl každý modul splňovat.

Přístupové modifikátory porušují zapouzdřenost, proto by se neměly používat. Atributy objektu mají být privátní, mají s nimi pracovat pouze metody objektu. Okolí by vůbec nemělo vědět, jaké má objekt atributy. Měly by být zcela skryty, tedy zapouzdřeny.

A co metody? Navíc, jak budeš dělat mocky, když atributům nedáš gettery a settery? Můžeš je sice vytáhnou reflexí, ale potom zase ztratíš možnost refaktrorovat názvy atributů, aniž by jsi musel všechny unit testy upravit.

K čemu reflexe? Názvy atributů mohu měnit dle libosti, aniž by to mělo na unit testy i na zbytek aplikace sebemenší vliv, protože je prostě nevidí. Testy testují pouze rozhraní třídy, atributy se v něm nevyskytují. Mocky nastrkám do konstruktoru a jako parametry metod. Jinde je nepotřebuji.

anonym

Re:Bezestavové OOP
« Odpověď #26 kdy: 30. 01. 2018, 23:38:11 »
Druhá vlastnost je, že máš přimou podporu pro zapouzřenost (pomocí přístupových modifikátorů), což by měl každý modul splňovat.

Přístupové modifikátory porušují zapouzdřenost, proto by se neměly používat. Atributy objektu mají být privátní, mají s nimi pracovat pouze metody objektu. Okolí by vůbec nemělo vědět, jaké má objekt atributy. Měly by být zcela skryty, tedy zapouzdřeny.

A co metody? Navíc, jak budeš dělat mocky, když atributům nedáš gettery a settery? Můžeš je sice vytáhnou reflexí, ale potom zase ztratíš možnost refaktrorovat názvy atributů, aniž by jsi musel všechny unit testy upravit.

K čemu reflexe? Názvy atributů mohu měnit dle libosti, aniž by to mělo na unit testy i na zbytek aplikace sebemenší vliv, protože je prostě nevidí. Testy testují pouze rozhraní třídy, atributy se v něm nevyskytují. Mocky nastrkám do konstruktoru a jako parametry metod. Jinde je nepotřebuji.

Jak jako Mocky nastrkáš do konstruktoru. Co když se ve třídě vytváří objekty jiné třídy a ty je budeš musel v unit testu namockovat, jinak se ti zavolají. To jako uděláš jeden velký zbytečný konstruktor, který bude obsahovat všechny vytvářené instance ve třídě? Wtf. Pošli nějaký svůj kód na github, já bych to chtěl vidět.Nebo nějakou tvojí utilitu pro vim, jestli se nestydíš  :D

Kit

Re:Bezestavové OOP
« Odpověď #27 kdy: 31. 01. 2018, 00:04:00 »
K čemu reflexe? Názvy atributů mohu měnit dle libosti, aniž by to mělo na unit testy i na zbytek aplikace sebemenší vliv, protože je prostě nevidí. Testy testují pouze rozhraní třídy, atributy se v něm nevyskytují. Mocky nastrkám do konstruktoru a jako parametry metod. Jinde je nepotřebuji.

Jak jako Mocky nastrkáš do konstruktoru. Co když se ve třídě vytváří objekty jiné třídy a ty je budeš musel v unit testu namockovat, jinak se ti zavolají.

To se dělá tak, že se ty objekty jiné třídy injektují do konstruktoru nebo do parametru metody. Zjednoduší se tím design třídy a zlepší robustnost aplikace.

To jako uděláš jeden velký zbytečný konstruktor, který bude obsahovat všechny vytvářené instance ve třídě? Wtf.

Ne. Do konstruktoru injektuji již vytvořené a nakonfigurované vnější objekty. Konstruktor si je pouze uloží mezi atributy. Tím se rapidně zlepšuje znovupoužitelnost třídy a polymorfismus zde získává ty správné možnosti.

atarist

Re:Bezestavové OOP
« Odpověď #28 kdy: 31. 01. 2018, 00:08:22 »
trida zadnej stav nema a bezstavove OOP nato uz mi uplne dochazi fantazie - je neuveritelny co se da ze slov uvarit

Trida muze mit stav reprezentovany statickymi atributy ne? Tedy kdyz se bavime v kontextu Javy.

anonym

Re:Bezestavové OOP
« Odpověď #29 kdy: 31. 01. 2018, 00:17:37 »
K čemu reflexe? Názvy atributů mohu měnit dle libosti, aniž by to mělo na unit testy i na zbytek aplikace sebemenší vliv, protože je prostě nevidí. Testy testují pouze rozhraní třídy, atributy se v něm nevyskytují. Mocky nastrkám do konstruktoru a jako parametry metod. Jinde je nepotřebuji.

Jak jako Mocky nastrkáš do konstruktoru. Co když se ve třídě vytváří objekty jiné třídy a ty je budeš musel v unit testu namockovat, jinak se ti zavolají.

To se dělá tak, že se ty objekty jiné třídy injektují do konstruktoru nebo do parametru metody. Zjednoduší se tím design třídy a zlepší robustnost aplikace.

To jako uděláš jeden velký zbytečný konstruktor, který bude obsahovat všechny vytvářené instance ve třídě? Wtf.

Ne. Do konstruktoru injektuji již vytvořené a nakonfigurované vnější objekty. Konstruktor si je pouze uloží mezi atributy. Tím se rapidně zlepšuje znovupoužitelnost třídy a polymorfismus zde získává ty správné možnosti.

WTF! Tak tady máš frajere a ukaž se, jak otesteješ (a nebo upravíš) třídu Program a metodu Run().

Kód: [Vybrat]

public class Program
    {
        OptionSet o;

        // Console params
        public String FeedFilePath { get; set; }
        public String TargetLocation { get; set; }
        public int? TestFileCount { get; set; }
        public bool Help { get; set; } = false;
        public int? BatchSize { get; set; }

        public IProcessor TradeProcessor { get; set; }
        public Tester Tester { get; set; }

        public Program(params string[] args)
        {
            LoggerSetting.init();

            o = new OptionSet()
            {
                 { "f|filePath=",   "the input {FILE} path of Trade datafeed. Defaul is current dir + '/TradesList.xml'.", v => FeedFilePath = v },
                 { "t|targetPath=", "the {DESTINATION} path. Default is current dir.", v => TargetLocation = v },
                 { "g|testFile=",   "generate TradesList.xml of {COUNT} elements in current dir.", v => TestFileCount = Int32.Parse(v) },
                 { "b|batchSize=",  "Batch {SIZE}. Default is 1000.", v => BatchSize = Int32.Parse(v) },
                 { "h|help",        "Show this help.",  v => Help = v != null}
            };

            List<string> extra;
            try
            {
                extra = o.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("datafeeds: ");
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `--help' for more information.");
                return;
            }

            if (Help)
            {
                printHelp();
                return;
            }
            if (FeedFilePath == null)
            {
                FeedFilePath = AppDomain.CurrentDomain.BaseDirectory + "/TradesList.xml";
            }
            if (TargetLocation == null)
            {
                TargetLocation = AppDomain.CurrentDomain.BaseDirectory;
            }
            if (BatchSize == null)
            {
                BatchSize = 1000;
            }

            TradeProcessor = new TradeProcessor(this.FeedFilePath, this.TargetLocation, BatchSize.Value);
            Tester = new CTSTestApplication.Tester();
        }

        public void run()
        {
            if(TestFileCount.HasValue)
            {
                Tester.CreateTestFile(AppDomain.CurrentDomain.BaseDirectory, TestFileCount.Value);
            }
            if (TradeProcessor != null)
            {
                TradeProcessor.Process();
            }
        }

        private void printHelp()
        {
            Console.WriteLine("help");
            o.WriteOptionDescriptions(Console.Out);
        }
       
        public static void Main(string[] args)
        {
            Program program = new Program(args);
            program.run();
        }
    }


[TestClass()]
    public class ProgramTests
    {
        TradeProcessorMock tradeProcessorMock = new TradeProcessorMock();

        [TestMethod()]
        public void ProgramTest()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory;

            string s = "-filePath=" + path;
            string s2 = "-targetPath=" + path;
            string s3 = "-testFile=150";
            string s4 = "-batchSize=999";

            Program p = new Program(s, s2, s3, s4);

            Assert.AreEqual(p.FeedFilePath, path);
            Assert.AreEqual(p.TargetLocation, path);
            Assert.AreEqual(p.TestFileCount, 150);
            Assert.AreEqual(p.BatchSize, 999);

            p.TradeProcessor = tradeProcessorMock;
            p.TestFileCount = null; // Can't mock Tester

            p.run();
            Assert.AreEqual(tradeProcessorMock.ProcessRunCount, 1);
        }