Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions PetProjectDog.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36202.13 d17.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PetProjectDog", "PetProjectDog\PetProjectDog.csproj", "{5528D01A-B792-4076-B8D0-D8F8D812FCAC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5528D01A-B792-4076-B8D0-D8F8D812FCAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5528D01A-B792-4076-B8D0-D8F8D812FCAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5528D01A-B792-4076-B8D0-D8F8D812FCAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5528D01A-B792-4076-B8D0-D8F8D812FCAC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B520792F-6A33-4531-BC98-82FCA29ED32E}
EndGlobalSection
EndGlobal
72 changes: 72 additions & 0 deletions PetProjectDog/AddNoteForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 47 additions & 0 deletions PetProjectDog/AddNoteForm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PetProjectDog
{
public partial class AddNoteForm : Form
{

public string NoteText { get; private set; }

public AddNoteForm()
{
InitializeComponent();
}

private void AddNoteForm_Load(object sender, EventArgs e)
{

}

private void textBox1_TextChanged(object sender, EventArgs e)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше стараться избегать пустых методов, да, случайно кликаются, понимаю)

{

}

private void btnSave_Click(object sender, EventArgs e)
{
if(!string.IsNullOrWhiteSpace(txtNote.Text))
{
NoteText = txtNote.Text.Trim();
DialogResult = DialogResult.OK;
Close();
}
else
{
MessageBox.Show("Введите текст примечания.", "Внимание", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
}
120 changes: 120 additions & 0 deletions PetProjectDog/AddNoteForm.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema

Version 2.0

The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.

Example:

... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>

There are any number of "resheader" rows that contain simple
name/value pairs.

Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.

The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:

Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.

mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
47 changes: 47 additions & 0 deletions PetProjectDog/DataStorage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace PetProjectDog
{
public static class DataStorage
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше конечно это все переписать на структуру классов, не хорошо делать статические классы-хранилки.

А также хорошо бы разные коллекции разбивать по разным классам, условно
DogStorage
OwnersStorage.

Если всё что происходит, это запись и чтение из файла, то можно сделать базовый класс
JsonStorage, например, и в нем уже реализовать запись в файл.

Также напрягает логика с тем, что нужно знать, что нужно модифицировать коллекцию, а потом вызвать записывающий метод.

Лучше всего тут бы подошло -

  1. Если не менять логику, то ReadDogs(), WriteDogs(List dogs) - чтобы при получении вычитывались собаки, при записи - записывались
  2. Если менять логику, то минимальная реализация CRUD операций - AddDog() ReadAllDogs() GetDogById() DeleteDog(), а под капотом уже хранить собак в массиве, и при изменении массива вызывать сохранение в файл. (Но тут нужно понимать, что тогда нужно аккуратно подходить к методу ReadAllDogs, чтобы его модификация не меняла состояние внутреннего массива)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А по поводу статики дополнение - в винформах конечно вполне нормально, когда форма взаимодействует через какой-то статический контекст.

Но условно без DI, как самое простое и относительно чистое решение можно сделать так

public static StaticContextProvider {
   // Тут хранятся инстансы всех сервисов
   public DogsStorage DogsStorage { get; set; }
}

public void Main() {
   // Тут создаем всю необходимую цепочку классов
   StaticContextProvider.DogsStorage = new DogsStorage();
}

{
public static List<Dog> Dogs { get; private set; } = new List<Dog>();
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Стандартный принятый порядок
приватные-публичные

Поля
Конструкторы
Свойства
Методы.

Ну либо другой другой, но отступы между строками лучше соблюдать, и избегать пустых строк как в конце.

public static List<Owner> Owners { get; private set; } = new List<Owner>();
private static string FilePath => "dogs.json";
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут лучше бы подошла константа private const string ...

public static void SaveDogsToFile()
{
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dogs.json");

var options = new JsonSerializerOptions { WriteIndented = true };
string json = JsonSerializer.Serialize(Dogs, options);

File.WriteAllText(path, json);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ещё пустая строка :)

}

public static void LoadDogsFromFile()
{
if (!File.Exists(FilePath)) return;

string json = File.ReadAllText(FilePath);
try
{
Dogs = JsonSerializer.Deserialize<List<Dog>>(json) ?? new List<Dog>();
}
catch
{
Dogs = new List<Dog>();
}
}






}
}
78 changes: 78 additions & 0 deletions PetProjectDog/Dog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PetProjectDog
{
public class Dog
{
public string Name { get; set; } // имя пса
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Бесмыссленные комментарии лучше избегать. А если хочется красивые подсказки, то такое можно выносить в

/// <summary>Имя пса</summary>
public string Name { get; set; } 

Тогда они в подсказках появляются, вроде студия тоже умеет сама их генерировать.

public string Age { get; set; } // возраст
public double Weight { get; set; } // вес

public string Colour { get; set; } // Цвет
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В коде принят американский английский, т.е. Color


public bool IsFriendly { get; set; } // дружелюбна?

public string Breed { get; set; } // порода
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если хочется подумать над моделью данных, то стоит сразу нормализовывать данные -
Порода - это отдельный справочник, т.е. какая-то другая коллекция пород, а собака относится к одному из этого множества.
Точно также вакцины и прогулки - это отдельные коллекции, из которых уже можно даты прогулок вычислять.


public string SpecialFeatures { get; set; } // особые приметы

public List<string> Notes { get; set; } = new List<string>(); // список примечаний

public bool IsVaccinated { get; set; }
public DateTime LastVaccination { get; set; } // дата последней вакцины

public DateTime NextVaccination { get; set; } // дата следуюущей вакцины

public DateTime LastWalk { get; set; } //
public DateTime NextWalk { get; set; } //
public DateTime DateLastUpdate { get; set; } // Дата последнего обновления карточки

public string PhotoPath { get; set; } // Путь к фотографии

public Owner Owner { get; set; } = new Owner(); // поле для владельца

public Dog(string name, string age, double weight, string color, string breed, bool isFriendly, bool isVaccinated)
{
Name = name;
Age = age;
Weight = weight;
Colour = color;
Breed = breed;
IsFriendly = isFriendly;
IsVaccinated = isVaccinated;
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тоже отступы

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Больше про них писать не буду, но надо привыкнуть следить за ними :)

public Dog()
{
}


public void ShowMainInfo()
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Выглядит как дебажный метод. +можно ещё и над использованием логгеров подумать :)

{
Console.WriteLine($"Имя: {Name}\nВозраст: {Age}\nПорода: {Breed}\n" +
$"Дружелюбна: {IsFriendly}\nВакцинирована: {IsVaccinated}");
}
public override string ToString()
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Использование ToString() полезно, только когда это используется где-то в логгерах. Для выведения на экран лучше заводить отдельные методы GetFormattedMainInfo(), как выше у тебя было.

{
return $"Имя питомца: {Name}, Порода: {Breed},Возраст: {Age} лет, Дата регистрации: {DateTime.Now.ToString("yyyy-MM-dd")}";
}

public void AddNote(string note)
{
Notes.Add(note);
}
public void MarkAsWalked()
{
LastWalk = DateTime.Now;
}





}
}
Loading