Результати пошуку за запитом: mvc4 5*
Створення Super Meat Boy на Unity
Автор: Антон Даніелян
Введение
Данная статья ориентирована на тех, у кого уже есть небольшой опыт работы с Unity. В первую очередь мы рассмотрим воссоздание механики управления главного героя игры Super Meat Boy. Также узнаем, как построить сцену, имея скриншот уровня оригинальной игры. Все материалы, использованные в данном примере, принадлежат разработчикам оригинальной игры.
Для начала стоит сказать пару слов о фоновых картинках для уровней. Чтоб не создавать весь уровень из отдельных элементов, редактируем найденные на просторах интернета скриншоты, на которых вырезаем главного героя, таймер с левой части экрана и следы крови. Теперь у нас есть подготовленный фон.
Элементы Уровня
Поверхности, по которым можно двигаться, задаем с помощью компонента Polygon Collider 2D. Места, где игрок может умереть (выпасть из поля зрения камеры или попасть на режущую пилу) обозначаем тегом killzone. К ним крепим данный скрипт:
void OnTriggerEnter2D(Collider2D other)
{
if (coll.tag =="killzone")
{
Application.LoadLevel(Application.loadedLevelName);
}
}
При прикосновении коллайдер игрока вызывает срабатывание скрипта и подгружает этот же уровень, то есть происходит рестарт. Аналогично работает и загрузка следующего уровня, единственным отличием является передаваемое методу Application.LoadLevel() текстовое значение с названием уровня. Этот скрипт прикрепляем к объекту endTarget.
Следы крови размещаем на все потенциально доступные игроку поверхности (кроме уровня песочницы, где они находятся на каждой из 4 сторон блока). Они состоят из отключенного по умолчанию компонента Sprite Renderer, компонента Box Collider 2D с активированным значением IsTrigger и скрипта, который собственно и включает Sprite Renderer при коллизии с игроком.
SpriteRenderer sR;
void Start()
{
sR = transform.GetComponent<SpriteRenderer>();
}
void OnTriggerEnter2D(Collider2D coll)
{
if (coll.tag =="Player")
{
sR.enabled = true;
}
}
Получаем компонент Sprite Renderer во время выполнения при помощи метода GetComponent(), вызываемого на данном объекте. Если тег прикасающегося коллайдера равен "Player", то включаем Sprite Renderer, который отображает картинку крови на уровне.
Создание персонажа
Внешний вид персонажа
В оригинальной игре мит-бой тщательно анимирован и имеет большое количество визуальных эффектов, большинство из которых мы воссоздавать не будем по причине нецелесообразности. Вместо анимации будем использовать простую подмену спрайтов при смене состояния игрока. Для главного персонажа нам понадобятся компоненты Rigid Body 2D, Sprite Renderer, Box Collier 2D, Circle Collider 2D и скрипт управления, который мы рассмотрим чуть ниже.
В инспекторе на компоненте Rigid Body 2D ставим галочку на Fixed Angle, в Circle Collider 2D на IsTrigger. Этим мы зафиксировали персонажа в одном положении и указали, что Circle Collider 2D выполняет функцию триггера. Радиус окружности коллайдера должен быть таким, что немного выходит за рамки квадратного коллайдера. Он является триггером появления следов крови на уровне.
Объявление переменных
Для корректной имитации поведения нам понадобятся переменные для скорости ходьбы, бега, прыжка, а также ускорения в воздухе и на земле.
public float jumpForce = 50f;
public float speed = 10;
public float speedMultiplier = 4f;
public float acceleration = 5f;
public float airAcceleration = 2f;
Для данных переменных экспериментальным путем были подобраны значения, которые больше всего напоминают поведение оригинала.
Также нам понадобятся переменные для контроля вида персонажа и собственно его физика. Они позже будут инициализированы уже знакомым нам способом во время выполнения.
SpriteRenderer spriteRender;
Rigidbody2D rBody;
Для правильного отображения разных состояний мит-боя будем использовать несколько картинок, поэтому берем переменные типа Sprite.
//спрайты разных состояний
public Sprite jumpSprite;
public Sprite RunSprite;
public Sprite IdleSprite;
public Sprite SlidingOnAWallSprite;
Данные спрайты будем инициализировать не в рантайме, а в редакторе, где проводим им ссылку на картинку для каждого состояния.
И напоследок еще понадобятся данные о высоте, толщине персонажа и состояние прыжка.
float playerWidth;
float playerHeight;
//флаг состояния прыжка
bool ableToJump = true;
Управление главным героем
После объявления всех нужных нам переменных, переходим к реализации. Зарезервированный метод Awake() отработает сразу поле загрузки уровня, поэтому в нем и инициализируем переменные толщины, высоты и другие.
void Awake()
{
//инициализация этих переменных произойдет сразу после запуска сцены
playerWidth = GetComponent<BoxCollider2D>().bounds.extents.x + 0.05f;
playerHeight = GetComponent<BoxCollider2D>().bounds.extents.y + 0.05f;
rBody = transform.GetComponent<Rigidbody2D>();
spriteRender = transform.GetComponent<SpriteRenderer>();
}
Переменные playerHeigth и palyerWidth будут полезны при определении, находится ли игрок на земле. К ним прибавляем небольшой зазор, который не даст лучу от персонажа заметить его же коллайдер.
Метод IsOnGround() возвращает true в случае, если хотя бы один из созданных лучей касается коллайдера. Для удобства создаем два луча – с левой нижней части коллайдера персонажа и правой соответственно. При создании отнимаем высоту, учитывая вертикальный и горизонтальный зазоры. Этот способ позволит уйти от многих проблем при прыжках возле стен.
public bool IsOnGround()
{
//создаем луч длинной 0.01 справа с направлением вниз
bool rightBottom = Physics2D.Raycast(
new Vector2(transform.position.x + playerWidth - 0.055f,
transform.position.y -playerHeight), -Vector2.up, 0.01f);
//аналогичный луч слева
bool leftBottom = Physics2D.Raycast(
new Vector2(transform.position.x - playerWidth + 0.055f,
transform.position.y - playerHeight),-Vector2.up, 0.01f);
return (rightBottom || leftBottom) ? true : false;
}
Метод Run() отвечает за движение игрока по горизонтали. Параметр int directionX отвечает за направление, если число позитивное, то двигаемся вправо, негативное – влево соответственно. Если нажат LShift, то учитывается умножитель ускорения. Если игрок находится в воздухе, то множим на переменную ускорения в воздухе.
private void Run(bool onGround, int directionX)
{
rBody.AddForce(new Vector2((directionX * speed - rBody.velocity.x) *
(Input.GetKey(KeyCode.LeftShift) ? speedMultiplier : 1f) *
(onGround ? acceleration : airAcceleration), 0));
}
Метод JumpNearWall() отвечает за прыжок персонажа возле стены. Аналогично методу Run(), он принимает параметр int directionX.
private void JumpNearWall(int directionX)
{
//убираем инерцию
rBody.velocity = Vector2.zero;
rBody.AddForce(new Vector2(directionX *
jumpForce * airAcceleration * 3,
jumpForce * airAcceleration * 5));
StartCoroutine(JumpCoolDown());
}
В конце тела этого метода вызываем корутин, который будет убирать возможность прыгать суммарно на 0.1 секунд.
IEnumerator JumpCoolDown()
{
yield return new WaitForSeconds(0.05f);
ableToJump = false;
yield return new WaitForSeconds(0.05f);
ableToJump = true;
}
Метод FlipPlayer() меняет направление используемого спрайта игрока.
void FlipPlayer(bool toLeft)
{
//если повернут направо, а нужно налево
if ((transform.localScale.x < 0 && toLeft) ||
//если повернут налево, а нужно направо
(transform.localScale.x > 0 && !toLeft))
{
transform.localScale = new Vector3(transform.localScale.x * -1f,
transform.localScale.y, transform.localScale.z);
}
}
Метод FixedUpdate() является зарезервированным и вызывается независимо от количества отработанных кадров. Для начала получаем значение, касается ли персонаж пола и стен слева и справа.
bool onGround = IsOnGround();
bool nearLwall = Physics2D.Raycast(
new Vector2(transform.position.x - playerWidth, transform.position.y),
-Vector2.right, 0.01f);
bool nearRwall = Physics2D.Raycast(
new Vector2(transform.position.x + playerWidth, transform.position.y),
Vector2.right, 0.01f);
Присваиваем спрайт по умолчанию – спрайт безделья.
spriteRender.sprite = IdleSprite;
Теперь считываем нажатие кнопок управления.
if (Input.GetKey(KeyCode.RightArrow))
{
//двигаем персонажа в позитивном направлении по оси Х
if (!nearRwall) Run(onGround, 1);
//присваиваем новый спрайт и меняем его направление
spriteRender.sprite = RunSprite;
FlipPlayer(false);
}
else if (Input.GetKey(KeyCode.LeftArrow))
{
//двигаем персонажа в негативном направлении по оси Х
if (!nearLwall) Run(onGround, -1);
spriteRender.sprite = RunSprite;
FlipPlayer(true);
}
Если персонаж находится на поверхности и нажат пробел, то выполняем прыжок и активируем таймер до следующего прыжка.
if (Input.GetKeyDown(KeyCode.Space) && onGround && ableToJump)
{
//выполняем "прыжок с земли"
rBody.AddForce(new Vector2(0, jumpForce * acceleration* 1.7f));
spriteRender.sprite = jumpSprite;
//таймер до следующего прыжка
StartCoroutine(JumpCoolDown());
}
В противном случае разделяем поведение для прыжка возле левой и правой стенки.
if (Input.GetKeyDown(KeyCode.Space) && nearLwall && ableToJump)
{
//прыжок от стены вправо
JumpNearWall(1);
}
if (Input.GetKeyDown(KeyCode.Space) && nearRwall && ableToJump)
{
//прыжок от стены влево
JumpNearWall(-1);
}
Если игрок возле стенки, меняем спрайт и уменьшим скорость вертикального движения при прикосновении к стене после прыжка. Поворачиваем спрайт в нужном направлении и скрипт управления готов.
spriteRender.sprite = SlidingOnAWallSprite;
rBody.velocity = new Vector2(rBody.velocity.x,
(rBody.velocity.y > 9.0f) ? rBody.velocity.y * 0.6f : rBody.velocity.y);
if (nearLwall) FlipPlayer(true);
else FlipPlayer(false);
Теперь осталось опробовать все на практике. К данной статье прикреплен проект с уровнем «песочница», который можно изменить, как угодно добавив или убрав элементы.
Об'єктно-орієнтоване програмування C# у деталях
Автор: Редакция ITVDN
Введение
Большое количество статей посвящены C # OOП, но в данной C # OOП объясняется на понятных примерах.
1. Класс
Класс - это макет. Что такое макет?
Макет – это схематический чертеж плана будущего проекта. Например, если Вы планируете строить новый дом, инженер объяснит план его конструирования, демонстрируя макет, как на рисунке ниже. После этого инженер на основе макета начнет строительство дома.
Как и макет, у класса есть чертеж программы. Используя класс, можно создать собственный метод, указать значения переменных, а через объекты получить доступ к методам классов и их переменным значениям. Класс должен иметь значения переменных, методы и объекты.
ООП проще объяснить на примерах из жизни. Представьте дом в качестве примера для класса. В доме есть комнаты: гостиная, спальня, кухня - и техника, например, телевизор и холодильник. Владелец дома может пользоваться всеми комнатами и приспособлениями своего дома. То же можно сказать и о классе с группой методов и значений переменных. Комнаты с техникой – пример методов и значений переменных. Чтобы использовать класс, методы или значения переменных, используются объекты. Объекты являются примерами класса.
Дом без комнат и техники будет пустым и никто не будет в нем жить, пока комнаты и техника не появятся. Пустой дом - класс. Так что же такое использование класса без методов и значений переменных?
Для этого рассмотрим пример целостного дома. Аналогично, класс будет идти вместе с группой значений переменных, методов и объектов.
Классы и объекты – фундаментальные понятия объектно-ориентированного программирования (ООП).
Класс запускается введением ключевого слова «класс» и рядом указывается название Вашего класса. Вы можете дать любое название для класса. Далее нужно открыть и закрыть скобки, как показано на примере.
class ShanuHouseClass1
{
}
2. Объект
Владелец дома может получить доступ и использовать все комнаты дома и технику. Аналогично, для доступа к классовому методу и значениям переменных нужно использовать объекты. Можно создать один или несколько объектов для того же класса. Например, можно сказать, что бывает один или много владельцев дома.
Ниже Вы увидите пример объекта, где "objHouseOwner" - это объект класса, который будет использоваться для доступа ко всем переменным параметрам и методам класса.
ShanuHouseClass1 objHouseOwner = new ShanuHouseClass1();
3. Значение переменной
Значения переменных используются для хранения наших характеристик. Наша характеристика может быть представлена в числовом виде или в виде текста. Например, чтобы сохранить номер телефона, можно использовать тип переменной "int", а чтобы сохранить имя, можно использовать измененный тип строки с именем для каждой переменной.
Переменные могут быть локальными или глобальными. Например, если Вы покупаете новый телевизор, к Вам придет специалист, чтобы настроить телевидение. Он даст Вам свой контактный номер на будущее. Скорее всего, Вы запишите его номер на бумажке и положите ее туда, где сможете быстро найди, когда она понадобится. Если Вы будете хранить этот листок на видном месте, то все Ваши гости смогут увидеть его. Глобальные или общие переменные похожи на этот пример. Если определить значение переменной как глобальное, то все методы внутри класса смогут получить доступ к значению переменной. Если Вы храните бумажку с номером в известном только Вам месте, то только Вы и видите контактный номер. Локальные частные переменные с этим схожи.
Синтаксис значений переменных:
Модификаторы доступа-тип данных-имя переменной
По умолчанию доступ к модификаторам скрыт. Вы можете использовать общий доступ для переменных.
Пример переменной:
int noOfTV = 0;
public String yourTVName;
private Boolean doYouHaveTV = true;
class ShanuHouseClass
{
int noOfTV = 2;
public String yourTVName = "SAMSUNG";
static void Main(string[] args)
{
ShanuHouseClass objHouseOwner = new ShanuHouseClass();
Console.WriteLine("You Have total " + objHouseOwner.noOfTV + " no of TV :");
Console.WriteLine("Your TV Name is :" + objHouseOwner.yourTVName);
}
}
В предыдущем примере программ Вы определили два значения переменных внутри класса. При применении основного метода создается объект класса. Можно получить доступ к значению переменной класса и вывести изображение.
Основным методом является метод по умолчанию в C#, где каждый консоль и приложение для Windows начнет выполнять программу. В основном методе можно определить объект для класса и использовать его, можно получить доступ ко всем значениям переменных параметров и методов класса.
Допустим, что каждый дом имеет въездные ворота. Используя ворота, Вы попадаете в свой дом. Аналогично, чтобы запустить программу, должен быть метод по умолчанию, который будет запускать программу. Основной метод полезен при запуске программы. Каждый раз, когда Вы будете запускать C# Console или приложение Windows, основной метод будет выполняться первым. Из основного метода можно создать объект для других классов и использовать их методы.
4. Метод или функции (метод функционирования)
Метод – это группа из операторов кода. Вот предыдущий пример программы с методом функционирования.
class ShanuHouseClass
{
int noOfTV = 2;
public String yourTVName = "SAMSUNG";
public void myFirstMethod()
{
Console.WriteLine("You Have total " + noOfTV + "no of TV :");
Console.WriteLine("Your TV Name is :" + yourTVName);
Console.ReadLine();
}
static void Main(string[] args)
{
ShanuHouseClass objHouseOwner = new ShanuHouseClass();
objHouseOwner.myFirstMethod();
}
}
Примечание: Большинство разработчиков интересовались разницей между методами и функциями. В этой статье понятие метода используется вместо понятия функции. Тем не менее, есть одно отличие между методами и функциями. В ООП языках, таких как C #, Java и т.д. используется термин метод, а для не-ООП программирования, таких как "C" и других – функция.
Использование методов.
Предположим, что у Вас есть мобильный телефон и Вы храните на нем много песен. Тем не менее, Вы всегда любите слушать определенные песни. Очень сложно каждый раз выискивать из сотен песен на телефоне любимую и проигрывать ее. Вместо того, чтобы проделывать одну и ту же работу много раз, Вы можете использовать плейлисты. Щёлкните на плейлист и слушайте любимую музыку. Это облегчит Вашу работу, и Вам не придется повторять одни и те же действия постоянно. Методы используются как плейлист. Можно писать повторные коды для одного метода, а затем при необходимости использовать его.
В доме может быть одна большая комната или несколько комнат, и в каждой есть какое-то оборудование. Точно так же в классе можно увидеть один или несколько методов. В доме может быть две или три спальни, но кажая спальня отличается по размеру, цвету и так далее. Это означает, что одни и те же комнаты все равно разного типа. Так и в классе можно создать более одного метода с тем же именем, но с другим параметром. В ООП это называется "полиморфизм".
Синтаксис функций.
Модификаторы доступа, тип возвращения, название метода (список параметров):
Модификаторы доступа: о них будет сказано далее в статье.
Тип возвращения: Если Ваш метод возвращает значение, тогда Вам следует использовать тип возвращения с любым типом данных, такие как string, int и так далее. Если метод не возвращает значение, используйте тип "Void".
Название метода: Здесь Вы задаете имя каждому методу.
Список параметров: список параметров или аргументов, которые Вы передаете функции.
Ниже приведен пример способа.
• Метод с типом Void: Void - ключевое слово, благодаря которому данные из методов не возвращаются.
public void veranda()
{
Console.WriteLine("Welcome to Veranda");
Console.WriteLine("How Many Chairs Do you have in your Veranda");
NoofChair = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("I have total " + NoofChair + " Chairs in my Veranda");
}
• Метод с типом возврата: метод обернется в какой-то результат, который может использоваться в программе. Например, возьмем метод TVNAME с типом возврата "String". Можно сказать, что у Вас в доме есть телевизор в гостиной, родительской спальне и детской. В каждой комнате стоит телевизор разных фирм. Предположим, Вы хотите узнать название бренда телевизора. Вам нужно ввести один и тот же код трижды. Вместо повторного написания одинакового кода, Вы можете воспользоваться методом с типом возврата.
public string TVNAME()
{
Console.WriteLine("Enter Your TV Brand NAME");
YOURTVName = Console.ReadLine();
return YOURTVName;
}
• Метод со списком параметров: До сих пор Вы видели методы без параметров. Параметры используются для передачи некоторых данных методу, чтобы осуществить Ваш процесс как нельзя лучше. Например, Вы хотите перекрасить спальни. Вам нужно посоветоваться со всеми членами семьи, которые проживают с Вами в доме, по поводу цвета стен в спальнях. Вы можете задать имя пользователя и их любимый цвет в качестве параметра метода.
public void BedRoom(String nameandColor)
{
Console.WriteLine(nameandColor);
}
Тот же самый метод с другими параметрами называется методом перегрузки. Пример метода Вы найдете ниже. Оба метода называются одинаково, но имеют разные параметры.
public void BedRoom(String MemberName,String Color)
{
Console.WriteLine(MemberName + " Like " + Color + "Color");
}
Пример законченного класса с основным методом:
class ShanuHouseClass1
{
int NoofChair = 0;
public String YOURTVName;
private Boolean DoyouHaveTV = true;
public void veranda()
{
Console.WriteLine("Welcome to Veranda");
Console.WriteLine("How Many Chairs Do you have in your Veranda");
NoofChair = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("I have total " + NoofChair + " Chairs in my Veranda");
}
public string TVNAME()
{
Console.WriteLine("Enter Your TV Brand NAME");
YOURTVName = Console.ReadLine();
return YOURTVName;
}
public void BedRoom(String nameandColor)
{
Console.WriteLine(nameandColor);
}
public void BedRoom(String MemberName,String Color)
{
Console.WriteLine(MemberName + " Like " + Color + "Color");
}
static void Main(string[] args)
{
ShanuHouseClass1 objHouseOwner = new ShanuHouseClass1();
objHouseOwner.veranda();
String returnvalue = objHouseOwner.TVNAME();
Console.WriteLine("Your TV BRAND NAME IS: "+returnvalue);
objHouseOwner.BedRoom("My Name is Shanu I like Lavender color");
objHouseOwner.BedRoom("My Name is Afraz I like Light Blue color");
objHouseOwner.BedRoom("SHANU", "Lavender");
Console.ReadLine();
}
}
5. Модификаторы доступа
Модификаторы доступа не что иное, как использование и ограничение типа значений переменных, методов и класса. Это можно назвать пределом безопасности.
Шесть основных модификаторов доступа:
частный
публичный
внутренний
защищенный
внутренний защищенный
Частный модификатор доступа.
Вернемся к примеру с домом. Охранник может охранять Ваш дом. Его обязанность - охранять вход в дом. Он не может зайти в дом и получить доступ ко всем вещам. Вы создаете SecurityGuardClass и называете переменную и метод для Security частным.
Общественный модификатор доступа.
Владельцы дома считаются общественными по отношению к классу. Они могут получить доступ ко всем классам, связанным с домом. Нет никаких ограничений на доступ к дому.
Защищенный модификатор доступа.
Только основной класс и производные классы могут иметь доступ к защищенным значениям переменных и методам. Например, служащие и гости – пример защищенного доступа. Служащие могут войти в любую комнату, прибраться там. Тем не менее, они имеют ограниченный доступ к дому, так как они не могут отдохнуть в постели хозяина дома.
Внутренний модификатор доступа.
Предел значения переменной или метода доступа существует в рамках проекта. Предположим, что в Вашем проекте существует более одного класса, и Вы объявили переменную в качестве внутреннего доступа в один класс. Посмотрите пример программы для внутренней переменной.
public class sampleInternalClass
{
internal String myInternal = "Iam Internal Variable";
}
class ShanuHouseClass
{
int noOfTV = 2;
public String yourTVName = "SAMSUNG";
public void myFirstMethod()
{
Console.WriteLine("You Have total " + noOfTV + "no of TV :");
Console.WriteLine("Your TV Name is :" + yourTVName);
}
static void Main(string[] args)
{
ShanuHouseClass objHouseOwner = new ShanuHouseClass();
objHouseOwner.myFirstMethod();
sampleInternalClass intObj = new sampleInternalClass();
Console.WriteLine("Internal Variable Example :" + intObj.myInternal);
Console.ReadLine();
}
}
Внутренний модификатор защиты.
Внутреннее защищенное значение переменной или метод имеет свои ограничения в рамках проекта класса или производного класса. Вот пример программы для внутренней защищенной переменной. В этом примере использован механизм наследования.
public class sampleProtectedInternalClass
{
protected internal String myprotectedInternal = "Iam Protected Internal Variable";
public void protectedInternalMethod()
{
Console.WriteLine("Protected Internal Variable Example :" + myprotectedInternal);
}
}
public class derivedClass : sampleProtectedInternalClass
{
public void derivedprotectedInternal()
{
Console.WriteLine("Derived Protected Internal Variable Example :" + myprotectedInternal);
}
}
class ShanuHouseClass
{
int noOfTV = 2;
public String yourTVName = "SAMSUNG";
public void myFirstMethod()
{
Console.WriteLine("You Have total " + noOfTV + "no of TV :");
Console.WriteLine("Your TV Name is :" + yourTVName);
}
static void Main(string[] args)
{
ShanuHouseClass objHouseOwner = new ShanuHouseClass();
objHouseOwner.myFirstMethod();
sampleProtectedInternalClass intObj = new sampleProtectedInternalClass();
intObj.protectedInternalMethod();
derivedClass proIntObj = new derivedClass();
proIntObj.derivedprotectedInternal();
Console.ReadLine();
}
}
6. Инкапсуляция
Инкапсуляция скрывает элементы или значения переменных за пределами класса. Вы помните, что охранник не имеет права заходить в дом, он не должен быть в курсе того, что происходит в доме. Таким образом, для большей безопасности владелец дома скроет все, что происходит внутри, от охранника. Скрытие и ограничение называют инкапсуляцией.
Например, у Вас есть два класса: первый называется "Houseclass" и другой – "houseSecurityClass".
Вы видите значения переменных, спрятанных в классе, где "houseSecurityClass" – общественный, а "Houseclass" может получить доступ, но "Houseclass" имеет как общественные, так и частные значения переменной, в которой частное значение переменной класса не может быть доступным за пределами класса.
public class houseSecurityClass
{
public int noofSecurity;
public String SecurityName = String.Empty;
}
public class Houseclass
{
private int noofLockerinHosue = 2;
public string OwnerName = String.Empty;
}
7. Абстракция
Абстракция показывает и делит общие данные с пользователем. Прислуга в доме может заходить во все комнаты и убираться там. Владелец дома может предоставить полные и частичные права слуге для доступа к его дому. Ниже приведен пример программы, в которой частные значения переменных и методов не согласуются со слугой, но общественная переменная и методы согласовываются.
public class HouseServerntClass
{
private int SaftyLoackerKeyNo = 10001;
public String roomCleanInstructions = "Clean All rooms";
private void saftyNos()
{
Console.WriteLine("My SaftyLoackerKeyNo is" + SaftyLoackerKeyNo);
}
public void roomCleanInstruction()
{
Console.WriteLine(roomCleanInstructions);
}
}
8. Наследование
Наследование (подражание) используется для повторного использования кода. В защищенном внутреннем модификаторе доступа Вы уже видели пример программы наследования. Подражание - это не что иное, как доступ и использование всех базовых классовых значений переменных и методов в производном классе. Подражание может быть любым из следующих.
Single level Inheritance: пример с одним базовым классом и одним производным
public class baseClass
{
private void privateMethod()
{
Console.WriteLine("private Method");
}
public void publicMethod()
{
Console.WriteLine("This Method Shared");
}
}
public class DerivedClass : baseClass
{
static void Main(string[] args)
{
DerivedClass obj = new DerivedClass();
obj.publicMethod();
Примечание: Базовый класс - высший класс, а производный класс - это класс (ы), который наследует базовый.
Наследование, где базовый класс - "GuestVist", а производный класс - "HouseOwnerClass".
В даном случае класс HouseOwnerClass наследует базовый класс GuestVist:
class GuestVist
{
public void Guestwelcomemessage()
{
Console.WriteLine("Welcome to our Home");
}
public void GuestName()
{
Console.WriteLine("Guest name is: Shanu");
}
}
class HouseOwnerClass : GuestVist
{
static void Main(string[] args)
{
HouseOwnerClass obj = new HouseOwnerClass();
obj.Guestwelcomemessage();
obj.GuestName();
Console.ReadLine();
}
}
Многозначное Наследование: рассмотрим пример с более чем одним производным классом. Первый базовый класс происходит с DerivedClass1, а затем DerivedClass1 возникает с DerivedClass2. Теперь с DerivedClass2 Вы можете получить доступ и к BaseClass, и DerivedClass1.
public class baseClass
{
private void privateMethod()
{
Console.WriteLine("private Method");
}
public void publicMethod()
{
Console.WriteLine("This Method Shared");
}
}
public class DerivedClass1 : baseClass
{
public void DerivedClass1()
{
Console.WriteLine("Derived Class 1");
}
}
public class DerivedClass2 : DerivedClass1
{
static void Main(string[] args)
{
DerivedClass2 obj = new DerivedClass2();
obj.publicMethod();
obj.DerivedClass1();
}
}
Множественное наследование:
Поддерживает ли .Net множественное наследование?
Ответ на этот вопрос - нет. В C # невозможно использовать множественное наследование класса.
Что такое множественное наследование?
Множественное наследование имеет только один класс, и Вы можете наследовать оба класса в производном классе.
Что произойдет, если ввести множественное наследование класса, используя C #?
Вернемся к примеру с домом. Производный класс "HouseOwnerClass" с двумя дополнительными классами "GuestVist" и "FriendsandRelationsClass".
Теперь предположим, что в Ваш дом пришел гость и друг. Для этого Вы вводите предыдущие три класса и наследуете два класса из Вашего производного класса.
Если ввести множественное наследование в C #, на экране отразится предупреждение "Ожидание интерфейса" во время процесса кодирования и выполнения программы.
9. Полиморфизм
Приставка «поли» означает больше, чем одна форма. В начале статьи в разделе выбор метода Вы уже видели пример полиморфизма. То же имя метода с другим параметром и есть примером полиморфизма.
В полиморфизме используетс метод перегрузки и замещения. Полиморфизм имеет два способа выполнения программы: полиморфизм времени компиляции (Compile Time Polymorphism) и времени работы полиморфизма (Run time Polymorphism).
Метод перегрузки.
Метод перегрузки – тот же метод, используемый для более чем одного метода с другими аргументами.
На примере ниже Вы видите, что имя метода «BedRoom» использовалось для двух методов, но параметры для каждого из них разные.
class HouseOwnerClass
{
public void BedRoom(String nameandColor)
{
Console.WriteLine(nameandColor);
}
public void BedRoom(String MemberName, String Color)
{
Console.WriteLine(MemberName + " Like " + Color + "Color");
}
static void Main(string[] args)
{
HouseOwnerClass objHouseOwner = new HouseOwnerClass();
objHouseOwner.BedRoom("My Name is Shanu I like Lavender color");
objHouseOwner.BedRoom("My Name is Afraz I like Light Blue color");
objHouseOwner.BedRoom("SHANU", "Lavender");
Console.ReadLine();
}
}
Метод замещения.
Разница между методом перезагрузки и замещения заключается в том, что при использовании метода перезагрузки Вы получите то же имя метода с другим аргументом.
В методе замещения Вы получите то же имя метода, его параметры и тип, но метод замещения применим только к производным классам. Метод замещения не используется в одном и том же классе.
Обратите внимание, как метод замещения можно использовать в абстрактном, виртуальном и недоступном методах.
10. Абстрактный класс/метод
Абстрактный класс: у абстрактного класса ключевое слово abstract.
abstract class GuestVist
{
}
Абстрактный класс – наивысший класс для всех классов. Объект не может получить доступ к абстрактному классу. Вы не сможете создать объект для абстрактного класса.
Что произойдет, если попробовать создать объект для абстрактного класса?
Пытаясь создать объект для абстрактного класса, на экране появится предупреждение об ошибке "экземпляр абстрактного класса не может быть создан".
Что произойдет, если создать абстрактный метод, который не будет замещен в производном классе?
На примере ниже показан абстрактный метод, который не замещен в производном классе. На экране высветилось предупреждение, которое гласит, что класс должен быть внедрен в абстрактный класс.
Вы видите абстрактный класс, который имеет обычный метод и абстрактный метод. У абстрактных методов нет содержания в абстрактном классе, поэтому Вы можете только объявить абстрактный метод в абстрактном классе. Должен быть как минимум один абстрактный метод в абстрактном классе.
abstract class GuestVist
{
public void Guestwelcomemessage()
{
Console.WriteLine("Welcome to our AbstractHome");
}
public void GuestName()
{
Console.WriteLine("Guest name is: Abstract");
}
public abstract void purposeofVisit();
}
public class Houseclass : GuestVist
{
static void Main(string[] args)
{
Houseclass objHouse = new Houseclass();
objHouse.Guestwelcomemessage();
}
public override void purposeofVisit()
{
Console.WriteLine("Abstract just came for a Meetup and spend some time ");
}
}
11. Виртуальный класс/метод
Виртуальный метод полезен для современного программирования.
Что такое виртуальный метод и какая от него польза?
Например, гость говорит, что сегодня еще 5 человек посетят Ваш дом. Для этого Вы пишете функцию для отображения сообщения, поскольку пять гостей посетят Ваш дом. После визита, Вы видите, что в общей сложности Ваш дом посетило 20 человек. Цифра может быть больше или меньше заявленной.
В таком случае, у гостей будет свой отдельный класс, и дом станет этим отдельным классом.
Разница между абстрактным и виртуальным методами
Оба метода используют ключевое слово override. Абстрактный метод может использоваться только в абстрактном классе. Это значит, что в абстрактном методе абстрактного класса нет основы. А в виртуальном методе есть.
На примере ниже показан абстрактный и виртуальный метод. В абстрактном классе, виртуальный метод отмечает пять гостей, но в программе производного класса количество было изменено на 20 гостей. Какой же будет результат в виртуальном методе? 5 или 20 гостей?
abstract class GuestVist
{
public abstract void purposeofVisit(); // Abstract Method
public virtual void NoofGuestwillvisit() // Virtual Method
{
Console.WriteLine("Total 5 Guest will Visit your Home");
}
}
class AbstractHouseClass : GuestVist
{
public override void purposeofVisit() // Abstract method Override
{
Console.WriteLine("Abstract just for a Meetup and spend some time ");
}
public override void NoofGuestwillvisit() // Virtual method override
{
Console.WriteLine("Total 20 Guest Visited our Home");
}
static void Main(string[] args)
{
AbstractHouseClass objHouse = new AbstractHouseClass();
objHouse.purposeofVisit();
objHouse.NoofGuestwillvisit();
Console.ReadLine();
}
}
Завершенная программа
abstract class GuestVist
{
public void Guestwelcomemessage()
{
Console.WriteLine("Welcome to our AbstractHome");
}
public void GuestName()
{
Console.WriteLine("Guest name is: Abstract");
}
public abstract void purposeofVisit(); // Abstract Method
public virtual void NoofGuestwillvisit() // Virtual Method
{
Console.WriteLine("Total 5 Guest will Visit your Home");
}
}
class AbstractHouseClass : GuestVist
{
public override void purposeofVisit() // Abstract method Override
{
Console.WriteLine("Abstract just for a Meetup and spend some time ");
}
public override void NoofGuestwillvisit() // Virtual method override
{
Console.WriteLine("Total 20 Guest Visited our Home");
}
static void Main(string[] args)
{
AbstractHouseClass objHouse = new AbstractHouseClass();
objHouse.Guestwelcomemessage();
objHouse.purposeofVisit();
objHouse.NoofGuestwillvisit();
Console.ReadLine();
}
}
12. Недоступный класс/метод
Недоступный класс: этот класс не может быть унаследован другими классами. Например, у владельца дома есть потайная комната, возможно, кабинет. Владелец не хочет, чтобы посторонние имели доступ к его кабинету. В таких случаях будет полезен недоступный класс. Недоступный класс вводится с помощью ключевого слова Sealed. Если класс объявлен Sealed, он не может быть унаследован другими производными классами.
Что произойдет, если Вы унаследуете надоступный класс в производном классе?
Рассмотрим пример ниже. Вы видите пример программы недоступного класса.
public sealed class OwnerofficialRoom
{
public void AllMyPersonalItems()
{
Console.WriteLine("All Items in this rooms are personal to me no one else can access or inherit me");
}
}
class HouseSealedClass
{
static void Main(string[] args)
{
OwnerofficialRoom obj = new OwnerofficialRoom();
obj.AllMyPersonalItems();
Console.ReadLine();
}
}
Недоступный метод: Если Вы объявили метод недоступным, то нельзя заместить определенный метод в производном классе. Давайте посмотрим Ваш класс дома, где есть базовый класс с виртуальным методом и виртуальным недоступным методом. Виртуальный метод может быть замещен в производном классе. Но виртуальный недоступный метод нельзя заместить в недоступном классе.
public class OwnerOfficialroomwithrestriction
{
public virtual void message()
{
Console.WriteLine("Every one belongs to this house can access my items in my room except my sealed Item");
}
public virtual sealed void myAccountsLoocker()
{
Console.WriteLine("This Loocker can not be inherited by other classes");
}
}
class HouseSealedClass : OwnerOfficialroomwithrestriction
{
public override void message()
{
Console.WriteLine("overrided in the derived class");
}
public override void myAccountsLoocker()
{
Console.WriteLine("The sealed method Overrides");
}
}
13. Статический класс/метод
Статический класс и недоступный класс нельзя унаследовать.
Разница между статическим и недоступным классами
Можно создать объект (пример) недоступного класса. В секции недоступного класса создать образец недоступного класса, а в главном методе создать объект для доступа к недоступному классу. В недоступном классе можно прописать статические и нестатические методы.
А для статического класса создать объект нельзя. В статическом классе допускаются только статические члены. То есть, в статическом классе нельзя прописать нестатические методы.
В принципе, основной метод – пример статического метода. Когда Вы создадите консольное приложение в C #, увидите, что каждый класс имеет основной метод по умолчанию. Когда консоль или приложение Windows начинают выполняться, первым выполняется основной метод. Нет необходимости создавать объект основного метода, так как он был объявлен, как статический метод.
В статическом классе память выделяется для всех статических переменных и методов во время выполнения, но для нестатических значений переменных и методов память выделяется только тогда, когда создается объект класса.
Что произойдет, если ввести нестатических метод в статический класс?
Вы увидите сообщение об ошибке: "Не удается создать экземпляр статического класса".
Как вызвать статический класс метода и значение переменной, не создавая объект.
Очень просто. Можно использовать "ClassName.Variable или Method Name", например, "OwnerofficialRoom.AllMyPersonalItems ();"
Смотрите следующий пример со статическим классом:
public static class OwnerofficialRoom
{
public static void AllMyPersonalItems()
{
Console.WriteLine("All Items in this rooms are personal to me no one else can access or inherit me");
}
}
class HouseStaticClass
{
static void Main(string[] args)
{
OwnerofficialRoom.AllMyPersonalItems();
Console.ReadLine();
}
}
Результат предыдущей программы показан ниже:
Можно ли создать статический метод в нестатическом классе?
Да, можно создать статический метод в нестатическом классе. Нет необходимости создавать объект для доступа статического метода (ов) в нестатическом классе. Можно непосредственно использовать имя класса для доступа к статическому методу.
Пример статического метода в нестатическом классе.
public class OwnerofficialRoom
{
public static void AllMyPersonalItems()
{
Console.WriteLine("No need to create object for me just use my class name to access me :)");
}
public void non_staticMethod()
{
Console.WriteLine("You need to create an Object to Access Me :(");
}
}
class StaticmethodClass
{
static void Main(string[] args)
{
OwnerofficialRoom.AllMyPersonalItems();
OwnerofficialRoom obj = new OwnerofficialRoom();
obj.non_staticMethod();
Console.ReadLine();
}
}
14. Интерфейс
Интерфейс похож на абстрактный класс, но в интерфейсе существует только имя метода. Однако, в абстрактном классе можно иметь метод объявления и определения. Методы интерфейса должны быть реализованы в примененном классе.
Смотрите следующий пример программы для интерфейса. Все методы интерфейса были реализованы в классе. Как уже было отмечено, С # не поддерживает множественное наследование. Чтобы получить множественное наследование, можно использовать интерфейс. Следующая программа – пример множественного наследования с использованием интерфейса.
interface GuestInterface
{
void GuestWelcomeMessage();
void NoofGuestes();
}
interface FriendsandRelationsInterface
{
void friendwelcomemessage();
void FriendName();
}
class HouseOwnerClass : GuestInterface, FriendsandRelationsInterface
{
public void GuestWelcomeMessage()
{
Console.WriteLine("All guests are well come to our home");
}
public void NoofGuestes()
{
Console.WriteLine("Total 15 Guestes has visited");
}
public void friendwelcomemessage()
{
Console.WriteLine("Welcome to our Home");
}
public void FriendName()
{
Console.WriteLine("Friend name is: Afraz");
}
static void Main(string[] args)
{
HouseOwnerClass obj = new HouseOwnerClass();
obj.GuestWelcomeMessage();
obj.NoofGuestes();
obj.friendwelcomemessage();
obj.FriendName();
Console.ReadLine();
}
}
Иногда необходимо иметь определенные методы, которые будут использоваться во многих производных классах. Каждый производный класс может выполнять различные функции для этих методов. В таких случаях можно использовать интерфейс.
Проведем аналогию с гостями, которые посещают Ваш дом. Предположим, для гостей разослали два типа сообщений: "Добро пожаловать" и "Вход для гостей запрещен". Функции являются общими, но разнятся для каждого владельца в одном и том же доме. Гость может быть гостем отца, матери, детей или всей семьи. У каждого гостя свое сообщение-приглашение, но функции те же, что в сообщении. Отец – это класс, мать – класс и дети – один класс. Оба сообщения для гостей «Добро пожаловать» и «Вход для гостей запрещен" – одинаковы для всех. В этом случае, можно создать интерфейс и объявить оба метода в интерфейсе. Классы отца, матери и детей могут наследовать интерфейс и вводить собственные детали метода.
Интерфейс похож на абстрактный класс, но главное отличие между абстрактным классом и интерфейсом в том, что в абстрактном классе есть абстрактный и неабстрактный методы. Но по умолчанию в интерфейсе все методы являются абстрактными. Поэтому в интерфейсе нет неабстрактного метода. Все методы, объявленные в интерфейсе, должны быть замещены в производном классе.
Что произойдет, если объявить неабстрактные методы в интерфейсе?
Вы увидете предупреждение "неожиданный модификатор" в модификаторе доступа и "неожиданное содержание метода" в тексте сообщения.
Пример программы для интерфейса:
interface GuestInterface
{
void GuestWelcomeMessage();
void NoofGuestes();
}
class HouseOwnerClass: GuestInterface
{
public void GuestWelcomeMessage()
{
Console.WriteLine("All guests are well come to our home");
}
public void NoofGuestes()
{
Console.WriteLine("Total 15 Guestes has visited");
}
static void Main(string[] args)
{
HouseOwnerClass obj = new HouseOwnerClass();
obj.GuestWelcomeMessage();
obj.NoofGuestes();
Console.ReadLine();
}
}
Источник: http://www.c-sharpcorner.com/UploadFile/asmabegam/basic-concept-of-oop-in-C-Sharp/
Процедури та таймінг у відділі SEO
Автор: Андрій Афанасьєв
Введение
Всем привет! У меня давно созрела навязчивая мысль написать о том, какой является структура работы в техническом отделе SEO. “Почему именно такая тематика?” - спросите Вы. Это наболевшее. Иногда клиенты, да и просто люди, которые не занимаются всерьез данным продуктом, смотрят на весь процесс со стороны и думают: “Да это же просто дело. Взял проектик, денек-два оптимизировал сайт, ссылочек подкупил, всего делов. Может мне и самому SEO заняться?” Забавляет и интернет-пространство, например, рекламой с лозунгами наподобие: “Хватит платить сеошникам. Продвинь свой сайт самостоятельно!”. Это не может не веселить, если, конечно, не учитывать, что часть пользователей все-таки ведутся на подобные вещи.
Ну а если всерьез, то я скажу банальную вещь, что любая стоящая работа требует не менее качественного подхода. Любое интернет-агентство маленького, среднего или большого размаха разрабатывает и выстраивает свой процесс отработки клиентских проектов. В данной статье мы рассмотрим только работу технического отдела, потому что существует еще и аккаунтинг, и топ-менеджмент, которые тоже важны во взаимодействии компании и клиента. Но там “своя кухня” и она несколько отличается от технической.
Идем дальше…
Как известно, для того, чтобы построить качественный и надежный дом, нужно начать с фундамента. Так вот, в отделе SEO таковым является регламент процедур и тайминга. Это путеводитель как для руководителя отдела, так и для остальных членов команды. Зачем он нужен?
Отвечаю. У каждой компании в отработке находится много текущих + еженедельный поток новых клиентов, которые требуют в разы больше внимания, чем текущие. Когда я приведу пример технологии Abweb, Вы поймете критическую важность этого регламента. Если одновременно ведется работа по десяткам проектов, просто физически невозможно держать все в голове. Необходимо иметь универсальный план действий, который разбит на множество подзадач и переносить его в проекцию каждого проекта.
Ну, теперь конкретно о процессах
Для того, чтобы всю информацию было проще воспринять, я четко структурирую все процессы в виде двух таблиц. Как правило, процесс продвижения можно условно поделить на 2 глобальных этапа: внутренняя и внешняя оптимизация. Поэтому и процедуры для них разные.
Внутренняя оптимизация (1-й месяц)
Процедура
Старт выполнения
Тайминг
Проверка доступов от клиента (админка, FTP, хостинг)
1-й день работ
5 рабочих дней
Создание папки проекта и файла проекта в CRM с семантикой и основными доступами
1-й день работ
Анализ проекта, составление технического задания по внутренней оптимизации для программиста и техническое задание для копирайтера
2-й день работ
Отправка сформированных технических заданий аккаунт-менеджеру, который ведет проект.
В тот же день, когда составлено ТЗ, но не позднее 5-ого рабочего дня со старта проекта
Внедрение правок на тестовом домене.
В день, когда аккаунт-менеджер дал сигнал, что ТЗ на оптимизацию утверждено клиентом.
5 рабочих дней (4 дня реализация + 1 день на исправление багов по программной части)
Написание текстов для целевых страниц.
В день, когда аккаунт-менеджер дал сигнал, что ТЗ на тексты утверждено клиентом.
Отправка выполненного ТЗ по оптимизации на тестовом домене аккаунт-менеджеру.
В день, когда ТЗ было полностью внедрено и проверено.
1 рабочий день
Отправка написанных текстов аккаунт-менеджеру.
В день, когда тексты были полностью написаны и проверены.
Перенос выполненных правок на основной домен.
В день, когда аккаунт-менеджер дал сигнал, что ТЗ на тестовом утверждено клиентом.
2 рабочих дня
Размещение текстов.
В день, когда аккаунт-менеджер дал сигнал, что клиент утвердил тексты.
3 рабочих дня
Тестирование основной функциональности сайта после внесенных правок (форм заказа, авторизация, регистрация, добавление контента и его сохранение и т.д.) + исправление багов, если они есть
В день, когда все правки по внутренней оптимизации были перенесены на основной домен.
2 рабочих дня
Отправка сайта и целевых страниц на принудительную переиндексацию поисковыми системами для скорейшего индексирования ПС
В день, когда все правки по внутренней оптимизации были перенесены на основной домен + протестирован основной функционал
1 рабочий день
Добавление сайта в систему мониторинга для отслеживания позиций.
Когда все внедрено, отправлено на переиндексацию.
Итого примерно
19 рабочих дней
Ситуация выглядит таким образом, что за 16 рабочих дней (условно 3 рабочих недели) вся оптимизация должна быть внесена на основной версии сайта. 1 рабочая неделя отводится на тестирование выполненных правок, переиндексацию сайта, мониторинг динамики по позициям и составления отчета по всей проделанной работе.
Обращаю внимание, что тут предлагается такой подход, в котором сначала все внедряется на тестовой копии (которую обязательно нужно закрыть от индексации), демонстрируется и согласовывается с клиентом и, если все OK, переносится на основной домен. Я склонен считать, что это процесс затратный по времени, но зато безопасный!
Переходим ко второму и последующим месяцам.
Второй и дальнейшие месяцы плюс-минус похожи в плане выполняемых процессов.
Внешняя оптимизация (2-й и последующие месяцы)
Процедура
Старт выполнения
Тайминг
Планирование и составление ссылочной стратегии в виде ТЗ со списком закупаемых анкоров.
После получения оплаты
3 рабочих дня
Регистрация аккаунтов для закупки ссылок по проекту
1 этап закупки ссылок
На 4-й рабочий день
2 рабочих дня
Пополнение ссылочного аккаунта для 1 этапа
Плановая проверка сайта на предмет внутренней оптимизации/составление ТЗ по дооптимизации/отправка аккаунт-менеджеру на утверждение
12-й рабочий день
2 рабочих дня
Внедрение правок по дооптимизации на основании предыдущего пункта
В день, когда аккаунт-менеджер дал сигнал, что ТЗ на дооптимизацию утверждено клиентом.
4 рабочих дня
Пополнение ссылочного аккаунта для 2 этапа
14-й рабочий день
2 рабочих дня
2 этап закупки ссылок
Модерация ссылочных бирж
1 раз в 2 рабочих дня
11 рабочих дней
Наполнение ТЗ на ссылки списком доноров, откуда куплены ссылки
За день до составления и отправления отчета аккаунт-менеджером.
1 рабочий день
Итого примерно
22 рабочих дня
Выше приведена таблица со всеми процедурами и ориентировочными дедлайнами по каждому из них.
Хочу сделать акцент на том, что весь этот грандиозный план действий должен быть ориентиром, но всегда бывают исключения. Сроки реализации задач часто зависят от сложности и объема работ по проекту, оперативности клиента по согласованиям технических заданий, текстов и внесенных правок. Могут также вклиниваться и форс-мажорные задачи, которых мы, как правило, не ожидаем. К таким нюансам нужно быть морально готовым и все равно максимально выстроить процессы под нужные дедлайны.
Достаточно ли этого?
Буду честен. Конечно, нет. Недостаточно лишь прописать процедуры. Чтобы все было “в ажуре”, Вам и нам нужны:
Квалифицированные и перспективные ребята, которые будут закрывать все вопросы и задачи, которые расписаны выше (SEO-специалисты, копирайтеры, программисты и т.д.);
Календарные планы по процессам. Например, календарный план по закупке ссылочной массы на каждый месяц, который позволит не запутаться в большом потоке, когда что закупать;
Правильная постановка задач друг другу в худшем случае с помощью блокнота, а в лучшем - CRM-систем или других программ для фиксирования задач и планирования;
Высокая степень самоорганизованности и четко выстроенный тайм-менеджмент у каждого сотрудника;
Регулярное проведение планерок.
Я с удовольствием поделился с Вами прототипом своего видения по выстраиванию процессов в отделе производства SEO. Буду рад услышать замечания и положительные отзывы. На сегодня пока все;)
SQL. Нормальні стосунки
Автор: Станіслав Зуйко
Введение
В данной статье речь пойдет о такой части теории проектирования реляционных баз данных, как нормализация. Но для начала уделим немного внимания основным понятиям и самой сути реляционной теории, и вот почему:
в представлении многих термин «реляционная» в контексте баз данных означает то их свойство, что таблицы существуют не сами по себе, а связаны (от англ. «relation» – связь, соотношение) между собой (с помощью ключей).
На самом деле это не так, данный термин происходит от математического термина «relation» (отношение) и означает представление множества́ в теории множеств. В реляционной модели отношение – это множество связанных между собой данных, которые в базе данных реализуются в виде таблицы.
Мы отождествляем понятия отношения и таблицы, кортежи называем строками, атрибуты – столбцами. Кристофер Дейт (один из ведущих специалистов в области реляционной модели данных) называет эти понятия «дружественными», но отнюдь не равными и приводит пример с картиной художника Рене Магритта «Вероломство образов».
Надпись на картине гласит – «Это не трубка». И действительно, картина с изображением трубки – это не сама трубка, а её образ.
Точно так же таблица SQL – это не отношение, а лишь удачное изображение отношения. SQL (с null типами, которым не место в теории множеств и пр.) – это не реляционная модель в чистом виде, а лишь ее реализация. Поэтому из всех определений термина «нормализация» более всего мне нравится следующее – это использование SQL в реляционном духе.
В классической теории множеств по определению любое множество состоит из различных элементов. Отношение состоит из множества кортежей (кортеж (строка) – множество пар «атрибут : значение»; атрибут (поле, столбец) – свойство некой сущности; домен – множество допустимых значений атрибута). Таким образом, в отношении нет одинаковых кортежей, порядок следования кортежей и атрибутов не определен. Из этого следует, что отношения (не таблицы) всегда нормализованы (точнее, находятся в первой нормальной форме).
Первая нормальная форма (1НФ)
Каждый кортеж отношения содержит единственное значение соответствующего типа (домена) в позиции любого атрибута. Или, проще говоря, в табличном представлении отношения на пересечении любой строки и любого столбца мы видим только одно значение.
Допустим, у нас есть предприятие по доставке пиццы. Мы собрали все факты о заказах и у нас получилась следующая таблица:
Атрибут Order содержит несколько повторяющихся значений, наверняка, домен данного атрибута должен состоять из множества товаров из меню пиццерии (но никак не из множества списков товаров), а количество товара в заказе вообще относится к другому атрибуту. Также, в информации о заказчике (CustomerData) следовало бы выделить в отдельный атрибут номер телефона, причем у мистера Cheng Tsui их два.
После данных замечаний мы бы могли переделать таблицу под следующий вид:
Конечно же, следовало бы еще разделить наши Product1, Product2, Product3 на товар (beer, pizza и т.д.) и название товара (Papperoni , Veggie, SA и т.д.), а объем бутылки (0,5), который я вообще удалил, тоже определить в отдельный атрибут. Но основная проблема в этой таблице – это наличие переменного количества столбцов под продукт. И если с телефонами это не так критично (мы не будет хранить более двух номеров одного клиента), то с продуктами в одном заказе дела обстоят иначе. Конечно же, такие повторяющиеся атрибуты (отличаются только названием, но не доменом) не вписываются и в реляционную модель; от повторения кортежей (строк) нас избавит наличие атрибута OrderNo (ведь один клиент в один день может сделать идентичный заказ и ему его доставит, допустим, тот же курьер), который выступает явным претендентом на первичный ключ.
В общем, возвращаемся к тому, что таблицу нужно изменить, да и вообще, наверное, пора задуматься о том, что было бы неплохо ее разбить на несколько таблиц. Но пока что мы её модифицируем в следующий вид:
Здесь мы ввели дополнительный атрибут OrderItem, и теперь наш атрибут OrderNo не может уникально идентифицировать строку, похоже, наш первичный ключ будет составным (OrderNo, OrderItem). Пора бы перейти ко второй нормальной форме.
Стоп! А как же атомарность значений?
Атомарные данные – это данные, разделенные на наименьшие значения, дальнейшее деление которых невозможно или нецелесообразно. Например, атрибут Customer можно разбить на Фамилию и Имя, из Customer Address выделить улицу, дом, квартиру и так далее.
По этому поводу среди специалистов существует спор, стоит ли данное понятие включать в нормализацию и вообще уделять ему внимание. Конечно же, атомарность упрощает контроль над правильностью данных в таблице (определение более четкого домена, например, номерами домов должны быть только целые положительные числа), но, с другой стороны, это не должно быть панацеей. Допустим, наша пиццерия находится в небольшом городе, мы не планируем собирать статистику заказов по улицам (например, для принятия решения об открытии нового отделения на улице с наибольшим количеством продаж), а единственным пользователем данной информации (поле Customer Address) будет курьер и ему вполне приемлемо видеть адрес целиком. При необходимости, мы всегда сможем написать и такое выражение для выборки:
SELECT * FROM Orders
WHERE [Customer Address] LIKE '%Shevchenko%'
Вторая нормальная форма (2НФ)
Если у Вас несоставной первичный ключ, переходите к третьей нормальной форме.
Вторая нормальная форма начинает избавлять нас от избыточности данных (дублирования) в той части, что в таблице не должно быть неключевых столбцов, которые функционально не зависят от всего первичного ключа.
В нашем случае целый ряд атрибутов не зависит от части ключа – столбца OrderItem: Date, Customer, Customer Address, телефоны, Courier. Пора таблицу разбить на несколько (Customers, OrderInfo, Orders):
Третья нормальная форма (3НФ)
Мы уже пришли к первой и второй нормальным формам и пора задуматься о третьей, которая связана с транзитивными зависимостями. Данная зависимость возникает тогда, когда неключевой атрибут зависит от первичного ключа не напрямую, непосредственно, а транзитивно, т.е. через другой неключевой атрибут. Такого быть не должно. Наверняка, в базе данных нашей пиццерии есть таблица о сотрудниках: уже знакомые нам курьеры, а также телефонные операторы, повара, директор и другие. Пусть данная таблица содержит информацию о должностях и окладах:
Первичный ключ – на поле Employee Name. Поле Salary зависит от поля Employee Name (PK) транзитивно (через поле Position). Проще говоря, оклад зависит от должности (напрямую), а не от имени (конечно же, при условии, что по существующей бизнес-логике оклад действительно определен на каждую должность, а не на отдельного сотрудника, т.е. не может быть двух курьеров с разными окладами). Следует разделить таблицы.
Нормальная форма Бойса-Кодда (BCNF)
Данная нормальная форма расширяет 3НФ, естественно, подразумевает предварительное приведение к 3НФ и не должно быть других потенциальных первичных ключей, иными словами – не должно быть зависимости атрибутов первичного ключа от других неключевых атрибутов.
Давайте вернемся к таблице OrderInfo. У нас есть составной первичный ключ по полям OrderNo, OrderItem, но мы могли бы сделать ключ и по полям OrderNo, ProductName. Нужно вынести информацию о продукте (поля Product, ProductName) в отдельную таблицу, добавить поле ProductId, которое будет ссылаться (FK) на таблицу с информацией о продуктах.
Существует еще 4НФ, 5НФ и даже 6НФ, но они почти не имеют практического применения и в данной статье рассматриваться не будут.
Пора сделать некие выводы и поговорить о значимости нормализации. Во-первых, мы избавляемся от избыточности данных, а значит – экономим память. Во-вторых, мы решаем проблемы обновления данных, исключаем связанные с этим возможные возникновения аномалий. В-третьих, упрощаем контроль целостности данных. В-четвертых, база данных более понятно описывает реальный мир и готова к дальнейшему расширению.
Факторизація цілих чисел
Автор: Редакция ITVDN
Введение
Факторизация целых чисел позволяет раскладывать на множители (факторинг) большие числа (Int64) и проверять простоту целых чисел [1,2].
Приведем пример больших (14 ... 18-ти значных) простых чисел, которые можно использовать для тестирования или оценки.
biggest 18-digit primes
999999999999999989
999999999999999967
999999999999999877
biggest 17-digit primes
99999999999999997
99999999999999977
99999999999999961
biggest 16-digit primes
9999999999999937
9999999999999917
9999999999999887
biggest 15-digit primes
999999999999989
999999999999947
999999999999883
biggest 14-digit primes
99999999999973
99999999999971
99999999999959
Кодовый модуль демонстрирует практическое использование алгоритма, написанного в C# (4.0).
using System;
using System.Collections.Generic;
namespace Infosoft.MathShared
{
///
Integers: Properties and Operations
public static partial class Integers
{
#region Prime Numbers <100
private static readonly int[] Primes =
new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23,
29, 31, 37, 41, 43, 47, 53, 59,
61, 67, 71, 73, 79, 83, 89, 97 };
#endregion
// starting number for iterative factorization
private const int _startNum = 101;
#region IsPrime : primality Check
///
/// Check if the number is Prime
///
/// Int64
/// bool
public static bool IsPrime(Int64 Num){
int j;
bool ret;
Int64 _upMargin = (Int64)Math.Sqrt(Num) + 1;;
// Check if number is in Prime Array
for (int i = 0; i < Primes.Length; i++){
if (Num == Primes[i]) { return true; }
}
// Check divisibility w/Prime Array
for (int i = 0; i < Primes.Length; i++) {
if (Num % Primes[i] == 0) return false;
}
// Main iteration for Primality check
_upMargin = (Int64)Math.Sqrt(Num) + 1;
j = _startNum;
ret = true;
while (j <= _upMargin)
{
if (Num % j == 0) { ret = false; break; }
else { j = j + 2; }
}
return ret;
}
///
/// Check if number-string is Prime
///
/// string
/// bool
public static bool IsPrime(string StringNum) {
return IsPrime(Int64.Parse(StringNum));
}
#endregion
#region Fast Factorization
///
/// Factorize string converted to long integers
///
/// string
/// Int64[]
public static Int64[] FactorizeFast(string StringNum) {
return FactorizeFast(Int64.Parse(StringNum));
}
///
/// Factorize long integers: speed optimized
///
/// Int64
/// Int64[]
public static Int64[] FactorizeFast(Int64 Num)
{
#region vars
// list of Factors
List _arrFactors = new List();
// temp variable
Int64 _num = Num;
#endregion
#region Check if the number is Prime(<100)
for (int k = 0; k < Primes.Length; k++)
{
if (_num == Primes[k])
{
_arrFactors.Add(Primes[k]);
return _arrFactors.ToArray();
}
}
#endregion
#region Try to factorize using Primes Array
for (int k = 0; k < Primes.Length; k++)
{
int m = Primes[k];
if (_num < m) break;
while (_num % m == 0)
{
_arrFactors.Add(m);
_num = (Int64)_num / m;
}
}
if (_num < _startNum)
{
_arrFactors.Sort();
return _arrFactors.ToArray();
}
#endregion
#region Main Factorization Algorithm
Int64 _upMargin = (Int64)Math.Sqrt(_num) + 1;
Int64 i = _startNum;
while (i <= _upMargin)
{
if (_num % i == 0)
{
_arrFactors.Add(i);
_num = _num / i;
_upMargin = (Int64)Math.Sqrt(_num) + 1;
i = _startNum;
}
else { i = i + 2; }
}
_arrFactors.Add(_num);
_arrFactors.Sort();
return _arrFactors.ToArray();
#endregion
}
#endregion
}
}
Точки обзора
Тест на проверку простоты 18-ти значного числа (999999999999999989), т.е. процедура, которая определяет, являются ли целые числа простыми, это лучший способ проверки факторинга программного обеспечения. Если вычисления занимают слишком много времени (например, когда используется мобильная платформа с низким уровнем обработки большого количества численных данных), возьмите меньшее число, но тоже 18-ти значное: 324632623645234523.
Чтобы получить не такую тривиальную запись, как i = i + 2, или i + = 2, необходимо исходный код увеличить в два раза.
i ++; i ++;
Даный фрагмент кода был использован для сравнения производительности трех методов возрастания целых чисел:
using System;
using System.Diagnostics;
namespace IncrementEfficiencyTest
{
class Program
{
private const Int64 _max = 1000000000; // 1 billion
private const int _cycles = 5;
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
Console.Write("{0} on {1}", "i++;i++:", String.Concat(_cycles, " cycles with ", _max, " max: "));
sw.Restart();
for (int count = 0; count < _cycles; count++)
{
Int64 i = 0;
while (i < _max) { i++; i++; }
}
sw.Stop();
Console.WriteLine("{0} elapsed.", sw.Elapsed);
Console.Write("{0} on {1}", "i=i+2", String.Concat(_cycles, " cycles with ", _max, " max: "));
sw.Restart();
for (int count = 0; count < _cycles; count++)
{
Int64 i = 0;
while (i < _max) { i = i + 2; }
}
sw.Stop();
Console.WriteLine("{0} elapsed.", sw.Elapsed);
Console.Write("{0} on {1}", "i+=2", String.Concat(_cycles, " cycles with ", _max, " max: "));
sw.Restart();
for (int count = 0; count < _cycles; count++)
{
Int64 i = 0;
while (i < _max) { i += 2; }
}
sw.Stop();
Console.WriteLine("{0} elapsed.", sw.Elapsed);
Console.ReadKey();
}
}
Чтобы минимизировать потенциальные побочные эффекты теста, следует работать в нескольких циклах (5 циклов) с последующей апроксимацией нескольких результатов тестирования и не нужно реализовывать вызовы функций , потому что оценка синхронизации может искажаться. Основываясь на статистических данных, самый быстрый способ увеличения числа Int64 в 2 раза можно достичь через составленное уравнение: i = i + 2 (5,589 сек для всей процедуры тестирования), вместе с i + = 2 (5,625 сек) и удвоением и ++; i ++; "leading from behind" с оценкой производительности в 11,907 сек. Соответствующая поправка была сделана в факторизации первичных чисел (теперь выводится i = i + 2).
Параллельный алгоритм для факторинг-теста
При использовании параллельных алгоритмов факторизации можно значительно увеличить производительность теста.
Параллельне алгоритмы факторизации
region GetFirstFactorParallel(Int64 Num) algorithm
internal static Int64 GetFirstFactorParallel(Int64 Num)
{
// use concurrent stack to store non-trivial factor if found
ConcurrentStack _stack = new ConcurrentStack();
// object to specify degrees of parallelism
ParallelOptions _po = new ParallelOptions();
try
{
// return value initially set to 1
Int64 _ret = 1;
// step 1: try to factor on base 2, return if OK
if (Num % 2 == 0) return 2;
// step 2: try to factor on base 3, return if OK
if (Num % 3 == 0) return 3;
#region parallel algo to find first non - trivial factor if exists
// set upper limit
Int64 _upMargin = (Int64)Math.Sqrt(Num) + 1;
// number of CPU cores
int _countCPU = System.Environment.ProcessorCount;
// max degree of parallelism set equal to _cpuCount
_po.MaxDegreeOfParallelism = _countCPU;
Parallel.For(0, 2, _po, (i, _plState) = >
{
// starting number for inner loops (5 and 7)
int _seed = 5 + 2 * i;
// inner loops running in parallel;
// notice that because input Num was already tested for factors 2 and 3,
// then increment of 6 is used to speed up the processing,
// thus in dual core CPU it looks like:
// 5, 11, 17, 23, 29, etc. in first thread
// 7, 13, 19, 25, 31, etc, in second thread
for (Int64 j = _seed; j < _upMargin; j += 6)
{
// exit loop if stack contains value
if (_stack.Count != 0) { break; }
// check divisibility
if (Num % j == 0)
{
// push non-trivial factor to ConcurrentStack and exit loop
if (_stack.Count == 0) { _stack.Push(j); }
break;
}
}
});
#endregion
// return the value in ConcurrentStack if exists, or 1
return (_stack.TryPop(out _ret)) ? _ret : 1;
}
catch { throw; }
finally { _po = null; _stack = null; }
}
#endregion
Источник: http://www.codeproject.com/Tips/155308/Fast-Prime-Factoring-Algorithm
Хто такий Type Script?
Автор: Віталій Толмачев
Введение
Сегодня уже никого не удивишь выходом очередной новой технологии. Уж у нее точно будет та самая кнопка «Сделать все красиво за меня» и уж точно она будет работать как следует. Пользователи уже сравнительно спокойно относятся к выходу новых фреймворков и их освоению. Более того, даже с некоторой осторожностью. Где гарантия, что новенький всеумеющий фреймворк в обычный вторник через год не перестанут поддерживать, так как он не нашел своей широкой реализации и нужного комьюнити?
Если объективно оценивать ситуацию, то Java Script победил. На сегодняшний день это самый кроссплатформенный язык. Его можно спокойно разместить как внутри страницы
<script type="application/javascript">
alert('Hello, World!');
script>
Так и внутри тега
<a href="delete.php" onclick="return confirm('Вы уверены?');">
Удалить
a>Более
Более того, можно вынести в отдельный файл
<head>
<script type="application/javascript" src="http://Путь_к_файлу_со_скриптом">
script>
head>
Он отлично себя чувствует как на стороне клиента (браузер), так и на стороне сервера. И все равно, какую платформу использует клиент. Что уже говорить о браузерных операционных системах. В IndraDesktop WebOS программный код на 75 % состоит из JavaScript, IntOS — на 70 %, eyeOS — 5 %, но в eyeOS JavaScript участвует в визуализации на клиенте, что очень важно для отлаженной работы между клиентом и сервером.
Все Вы слышали о языке Java Script, а кто-то из Ваших друзей может внятно объяснить, что за ЯП такой Type Script? Кто создатель языка, какие особенности языка? Все очень просто. Человек, имея опыт создания Turbo Pascal, Delphi и даже С#, решил создать что-то еще лучше. Имя ему Андерс Хейлсберг. TypeScript представлен миру в 2012 году компанией Microsoft и был призван расширить возможности JavaScript. Код компилятора TypeScript распространяется лицензией Apache и на данный момент разработка данного языка ведётся в открытом репозитории GitHub.
Имея опыт разработки в строго типизированных языках, многим программистам поведение под кодом JS не всегда является очевидным. А что, если дать языку JS поддержку полноценных классов, статическую типизацию, поддержку подключения модулей? Станет ли код очевидным, облегчит ли это рефакторинг, поиск ошибок еще на этапе разработки? Наверно, с такими мыслями проснулся однажды Хейлсберг. Все это ему удалось реализовать в TypeScript. Видимо, ни для кого уже не секрет, что на выходе из компилятора TypeScript мы получим JS код. Но идея была настолько популярна и востребована, что ИТ сообщество моментом подхватило такую инициативу. Доказательством этого может послужить наличие дополнений для TS в Vim, Emacs и даже в Visual Studio. Более того, вместе с выходом спецификации TS файлы, которые бы помогли понимать статическую типизацию, уже были среди JS-библиотек, среди которых оказался даже jQuery.
Как же быть? TS неявно типизирован и в то же время поддерживает статическую типизацию. Если тип возвращаемого значения не указан, компилятор выберет type inference для вывода типа. Например, если в функцию сложения двух чисел мы передадим 2 типа numbers , то очевидно что возвращаемое значение будет также number.
function add(left: number, right: number): number {
return left + right;
}
Но как раз прописывание возвращаемого значения позволяет компилятору проверить правильность. В случае, если тип не может быть выведен из-за отсутствия объявления типа, тогда по умолчанию будет динамический тип any.
Так же используя компилятор для TypeScript, Вам будет доступна опция создания отдельного файла декларации (тайпинга). Он будет иметь расширение .d.ts. В данном файле останутся только сигнатуры методов. Это напоминает заголовочный файл header в С/С++
declare module arithmetics {
add(left: number, right: number): number;
subtract(left: number, right: number): number;
multiply(left: number, right: number): number;
divide(left: number, right: number): number;
}
Такие файлы уже написаны за нас как для библиотек JS (таких как jQuery, AngularJS), так и для Node.js, забрать их можно на GITHUB
Резюмируя все вышесказанное, можно сделать вывод, что язык TypeScript будет интересен, понятен и очевиден разработчикам, которые знакомы с объектно-ориентированными подходами, привыкшие к четкому пониманию, какой тип будет ожидаемым на определённом этапе выполнения инструкций. Тем, кто привык рефакторить свой код перед публикацией, а не собирать отзывы от клиента. У этого языка уж точно есть будущее!
Рекомендації щодо планування роботи MS Outlook
Автор: Олександр Марченко
Введение
В прошлой статье мы начали знакомиться с особенностями планирования задач и встреч, используя раздел «Календарь». В этой статье мы определим основные 5 правил, которые позволят более эффективно управлять собственным временем.
Правило 1.
Разделяйте задачи на несколько категорий:
«Жесткие» задачи – выполнение которых назначено на заранее известное время и дату, и у вас нет возможности их перенести во времени и пространстве. Зачастую, такие встречи подразумевают вашу договоренность о точном времени с кем-либо, будь то ваш руководитель, клиент, партнер и т.д.
«Динамические» задачи – не имеющие четких временных ограничений, к примеру, «Забрать костюм из химчистки: сегодня». У вас есть возможность сделать это по пути на работу, во время обеденного перерыва, возвращаясь в офис после встречи с партнером, вовсе после работы по пути домой или даже воспользовавшись курьерской службой. Главное, что это нужно сделать сегодня.
«Плавающие» задачи – не имеющие четкого срока выполнения, т.е. то что нужно сделать с некоторыми затратами по времени. К примеру: «Заказать новую книгу на Amazon» - вам нужно 30 минут чтобы выбрать книгу и оформить заказ, вы можете сделать это в любое свободное время, и у вас нет четких дедлайнов.
Правило 2.
Поскольку встречи бывают разовые (как, скажем, собеседование с кандидатом), а могут быть регулярными, для управления повторяющимися событиями можно пользоваться автоматическими повторами:
Встречи, в которых настроено повторение, будут отображаться в календаре с круговыми стрелками в правом нижнем углу.
Правило 3.
Оставляйте не менее 30-40% времени в вашем резерве. У вас всегда будет потребность корректировать планы в зависимости от обстоятельств. Всегда помните, что «мы планируем что-то одно, а жизнь вносит свои коррективы».
Правило 4.
Для работы вне офиса стоит синхронизировать свой календарь со своим смартфоном, если у вас на работе не приветствуется концепция BYOD, распечатайте свой план на неделю и поместите в ежедневник. Так у вас будет шпаргалка, по которой вы сможете вести свои дела без промедлений и опозданий.
Правило 5.
Используйте четко сформулированные ключевые категории и определения для каждого проекта или направления.
Правильный вариант.
Неправильный вариант.
Соблюдая эти простые правила, вы сможете упростить процесс планирования и сделать его более прозрачным для себя и своих коллег. В следующей статье мы детально рассмотрим процесс создания задачи или события в календаре и приглашения других участников.
Властивість CSS3 box-shadow
Автор: Валерія Прокопенко
Введение
С приходом CSS3 в мир веб-разработки множества модных новинок, отображать потрясающий анимационный эффект стало доступным с помощью нескольких строчек кода. Сегодня мы рассмотрим одно из свойств CSS3 box-shadow и с его помощью научимся создавать такой элемент управления, как кнопка. Особенностью такого подхода является то, что компоненты на странице выглядят объемными и привлекательными, чем обращают на себя внимание пользователя.
Для начала создадим 3 слоя, которые и будут выступать в роли наших кнопок и опишем для них стили:
<!DOCTYPE html>
<html>
<head>
<title>Box-Shadowtitle>
<style type="text/css">
body {
background: url(http://palma-ceramic.ru/images/newcatalog/1945.jpg);
}
.button {
width: 80px;
height: 80px;
margin: 30px;
display: inline-block;
cursor: pointer;
background: green;
}
.left {
border-radius: 50%;
}
.center {
border-radius: 20%;
}
.right {
border-radius: 50%;
}
style>
head>
<body>
<div class="button left">div>
<div class="button center">div>
<div class="button right">div>
body>
html>
В результате получим три зеленые кнопочки на фоне, который мы применили к телу нашего документа.
Теперь можно начать работу с box-shadow, но для начала познакомимся с его возможностями. Итак, данное свойство добавляет тень к нужному элементу, причем указав его параметры через запятую, можно применить несколько теней к одному компоненту и при их наложении первая в списке будет выше, а вторая ниже. Значение inset выводит тень внутрь элемента, но этот параметр не является обязательным.
Вооружившись знаниями о данном свойстве, можно приступить к созданию наших кнопок. Для начала изменим фон элементов на такой же, как у тела нашего документа. Теперь указываем параметры для box-shadow: первый отвечает за смешение по горизонтали, второй – по вертикали, третий - за радиус размытия, четвертый определяет цвет. Также используем значение inset, с помощью которого делаем внутреннюю верхнюю тень белой, а внутреннюю нижнюю - черной, при этом устанавливаем для них прозрачность, чтобы они не выглядели грубо.
<!DOCTYPE html>
<html>
<head>
<title>Box-Shadowtitle>
<style type="text/css">
body {
background: url(http://palma-ceramic.ru/images/newcatalog/1945.jpg);
}
.button {
display: inline-block;
cursor: pointer;
margin: 30px;
width: 80px;
height: 80px;
background: url(http://palma-ceramic.ru/images/newcatalog/1945.jpg);
box-shadow: 0 4px 22px rgba(0,0,0, 0.25), inset 0 3px 0 rgba(255,255,255, 0.5), 0 3px 0 rgba(0,0,0, 0.1), inset 0 0 22px rgba(0,0,0, 0.1);
}
.left {
border-radius: 50%;
}
.center {
border-radius: 20%;
}
.right {
border-radius: 50%;
}
style>
head>
<body>
<div class="button left">div>
<div class="button center">div>
<div class="button right">div>
body>
html>
В результате мы получили объемные формы, теперь сымитируем эффект нажатия при наведении на кнопку, для этого используем псевдокласс :hover и в нем опишем внутренние тени элементов, причем верхняя должна быть черной, а нижняя – белой, и не забываем установить прозрачность для данных элементов.
<!DOCTYPE html>
<html>
<head>
<title>Box-Shadowtitle>
<style type="text/css">
body {
background: url(http://palma-ceramic.ru/images/newcatalog/1945.jpg);
}
.button {
display: inline-block;
cursor: pointer;
margin: 30px;
width: 80px;
height: 80px;
background: url(http://palma-ceramic.ru/images/newcatalog/1945.jpg);
box-shadow: 0 4px 22px rgba(0,0,0, 0.25), inset 0 3px 0 rgba(255,255,255, 0.5), 0 3px 0 rgba(0,0,0, 0.1), inset 0 0 22px rgba(0,0,0, 0.1);
}
.left {
border-radius: 50%;
}
.center {
border-radius: 20%;
}
.right {
border-radius: 50%;
}
.button:hover {
box-shadow: inset 0 0 22px rgba(0,0,0,0.2), 0 3px 0 rgba(255,255,255,0.4),inset 0 3px 0 rgba(0,0,0,0.1), inset 0 0 22px rgba(0,0,0,0.1);
}
style>
head>
<body>
<div class="button left">div>
<div class="button center">div>
<div class="button right">div>
body>
html>
Следующее, что мы сделаем – это добавим иконки для наших кнопок, для этого мы используем псевдокласс :after и, чтобы усилить эффект вдавленности элемента при наведении, мы будем смещать картинки на 3% от начально положения.
<!DOCTYPE html>
<html>
<head>
<title>Box-Shadowtitle>
<style type="text/css">
body {
background: url(http://palma-ceramic.ru/images/newcatalog/1945.jpg);
}
.button {
display: inline-block;
cursor: pointer;
margin: 30px;
width: 80px;
height: 80px;
background: url(http://palma-ceramic.ru/images/newcatalog/1945.jpg);
box-shadow: 0 4px 22px rgba(0,0,0, 0.25), inset 0 3px 0 rgba(255,255,255, 0.5), 0 3px 0 rgba(0,0,0, 0.1), inset 0 0 22px rgba(0,0,0, 0.1);
-moz-box-shadow: 0 4px 22px rgba(0,0,0, 0.25), inset 0 3px 0 rgba(255,255,255, 0.5), 0 3px 0 rgba(0,0,0, 0.1), inset 0 0 22px rgba(0,0,0, 0.1);
-webkit-box-shadow: 0 4px 22px rgba(0,0,0, 0.25), inset 0 3px 0 rgba(255,255,255, 0.5), 0 3px 0 rgba(0,0,0, 0.1), inset 0 0 22px rgba(0,0,0, 0.1);
}
.left {
border-radius: 50%;
}
.center {
border-radius: 20%;
}
.right {
border-radius: 50%;
}
.button:hover {
box-shadow: inset 0 0 22px rgba(0,0,0,0.2), 0 3px 0 rgba(255,255,255,0.4),inset 0 3px 0 rgba(0,0,0,0.1), inset 0 0 22px rgba(0,0,0,0.1);
-moz-box-shadow: inset 0 0 22px rgba(0,0,0,0.2), 0 3px 0 rgba(255,255,255,0.4),inset 0 3px 0 rgba(0,0,0,0.1), inset 0 0 22px rgba(0,0,0,0.1);
-webkit-box-shadow: inset 0 0 22px rgba(0,0,0,0.2), 0 3px 0 rgba(255,255,255,0.4),inset 0 3px 0 rgba(0,0,0,0.1), inset 0 0 22px rgba(0,0,0,0.1);
}
.button::after {
content: '';
width: 80px;
height: 80px;
display: block;
opacity: 0.7;
}
.left::after {
background: url(http://www.defaulticon.com/sites/default/files/styles/icon-front-page-32x32-preview/public/field/image/MD-previous.png?itok=Myj2aYPA);
background-repeat: no-repeat;
background-position: 50%;
}
.center::after {
background: url(http://www.defaulticon.com/sites/default/files/styles/icon-front-page-32x32-preview/public/field/image/MD-play.png?itok=iQrN1tL3);
background-repeat: no-repeat;
background-position: 50%;
}
.right::after {
background: url(http://www.defaulticon.com/sites/default/files/styles/icon-front-page-32x32-preview/public/field/image/MD-next.png?itok=LBqF9Nod);
background-repeat: no-repeat;
background-position: 50%;
}
.button:hover::after {
background-position: center 53%;
}
style>
head>
<body>
<div class="button left">div>
<div class="button center">div>
<div class="button right">div>
body>
html>
Как видим, CSS3 делает жизнь разработчика намного проще, предоставляя множество интересных и простых в использовании плюшек.
WebForms чи MVC?
Автор: Редакция ITVDN
Введение
Когда в 2008 году компания Microsoft придумала ASP.NET MVC, у многих возник вопрос: «Зачем нужна ещё одна технология ASP.NET?».
Многие считают, что ASP.NET MVC не обязательно использовать, заменив на Web Forms ASP.NET. Однако, это неправда. Оба имеют свои плюсы и минусы. В статье мы рассмотрим преимущества этих двух технологий – и каждый сможет определиться, какая из них ему ближе. Мы также объясним понятия ASP.NET, ASP.NET Web Forms, MVC, ASP.NET MVC.
Опытным разработчикам в ASP.NET MVC данная статья поможет переосмыслить свои концепции.
Web-технологии
Когда речь идёт о web-технологиях, на ум приходит классический ASP, PHP, JSP, ROR, ASP.NET Web Forms, ASP.NET MVC и другое. Классический ASP - web-технология, созданная корпорацией Microsoft. У классического ASP было два недостатка: слишком большой, неудобный исходный код и ненадёжность. К примеру, у Вас есть текстовые поля и кнопка. Нажав на кнопку, можно проверить данные, хранящиеся на сервере. Успешная проверка означает, что данные хранятся в базе, а в обратном случае выведется определённое сообщение об ошибке. В чём проблема такого сценария? Вам нужно совершить много действий.
Приложение ASP.NET
ASP.NET – приложение Microsoft, его структура построена на всеязыковой среде выполнения для построения динамических веб-сайтов – для создания можно использовать такие языки: C#, VB.NET и другие. ASP.NET поддерживает две модели: Web Forms и ASP.NET MVC.
ASP.NET Web Forms
Корпорация Microsoft первой вывела ASP.NET Web Forms из ASP, таким образом они решили множество проблем путём создания высокого уровня абстрагирования. Web Forms включает в себя postback (постит данные на заданную страницу) и ViewState. И самое интересное в том, что для ASP.NET Web Forms не требуется написания вручную ни единой строчки кода.
ASP.NET 4.0
В ASP.NET 4.0 придумали, как преодолеть некоторые трудности:
появилась возможность отключать и контролировать размер ViewState;
с URL routing можно предоставить собственный URL вместо физического пути;
в ASP.NET 4.0 мы имеем лучший контроль над ID элементов и, таким образом, интеграция с платформой JavaScript стала проще.
Шаблон MVC
MVC – архитектурный шаблон. Многие используют его с Java-технологией. MVC – не новое понятие, созданное Microsoft. Однако, в MVC ASP.NET нужно разобраться. До этого стоит уточнить для себя некоторые определения – в том числе, что такое MVC.
Архитектурный шаблон – то, что решает наш вопрос на суб-системном уровне или на коротком уровне модуля. Речь идет о проблеме, связанной с архитектурой проекта. Это говорит о том, как можно разделить системы, а в частности - почему. Создаются библиотеки классов, компоненты, веб-сервисы, чтобы решить данный вопрос.
MVC – архитектурный шаблон, позволяющий уловить тонкую связь между input-логикой, бизнес-логикой и UI-логикой.
Платформа ASP.NET MVC
ASP.NET MVC – еще одна платформа web-приложений от Microsoft. В ней устранены недостатки, имеющие место в предыдущих, подобного типа платформах. Эта платформа построена на всеязыковой среде выполнения (CLR) и полностью основана на MVC-архитектуре.
Источник: http://www.codeproject.com/Articles/528117/WebForms-vs-MVC#Visual_in_Web
Як розпочати навчання веб-розробці
Автор: Редакция ITVDN
Введение
В этой статье мы рассмотрим некоторые инструменты, книги и ресурсы о том, как начать обучение веб-разработке. Эта статья направлена на тех, кто уже работал с HTML, CSS и JavaScript.
Зачем учиться веб-разработке?
Одно из главных преимуществ обучения веб-разработке – Вы получите навыки работы с большим количеством клиентов, проектов, а также научитесь контролировать собственный рабочий процесс.
С чего начать?
Ниже мы рассмотрим четыре языка программирования, которые стоит рассматривать прежде всего.
HTML5
HTML5 – последняя спецификация HTML. Он идет рука об руку с CSS3, новейшим образцом CSS. Новая спецификация HTML позволяет создавать приложения для браузера и мобильного устройства.
CSS3
С помощью CSS3 Вы сможете сделать разметку более стильной и профессиональной. Если Вы чувствуете себя достаточно опытным в CSS3, Вам стоит прочитать SVG книги.
LESS
LESS – это надстройка CSS, она расширяет язык CSS, добавляет в него динамику. Он вводит переменные, операции, function-like элементы. Возможность писать таблицы стилей упростит и улучшит написание кода.
Less работает в браузере, в Node и Rhino.
SASS
Таблицы стилей становятся больше и сложнее. В работе с ними может помочь препроцессор. Sass позволяет использовать функции, не существующие в CSS, например, переменные, возможность наследования и многое другое.
Составители для LESS и SASS
LESS и SASS - надстройки, поэтому Вам понадобится компилятор для преобразования результата.
CodeKit
CodeKit – одно из лучших приложений для разработчиков и дизайнеров, работающих на Mac. CodeKit следит за всем, что Вы создаете. Приложение может исправлять ошибки и составлять код самостоятельно.
Prepros
Prepros – GUI-компилятор, предназначенный для предварительной обработки таких языков: Compass, LESS, Sass, Jade, Stylus, Slim, Markdown, CoffeeScript и Haml. Prepros также может обновить браузер, когда Вы меняете свой код в редакторе. С Prepros можно работать и тем, у кого система Windows.
Текстовые редакторы для веб-разработчиков
Sublime Text
Sublime Text – текстовый редактор для кода разметки. В нем легкий пользовательский интерфейс, он удобен в эксплуатации.
Atom
Этот современный текстовый редактор начал пользоваться успехом совсем недавно, и этот проект пока не идеален. Он был создан веб-сервисом GitHub. Atom состоит из 50 модулей вокруг небольшого ядра с открытым кодом. Его цель - глубоко расширяемая система, стирающая различие между пользователем и разработчиком.
Обучение веб-разработке с помощью книг
Book Apart управляют люди, знающие веб лучше, чем 99% пользователей. Содержание этих книг всегда наивысшего качества, их легко читать, и они обеспечивают понимание процесса создания веб-сайтов.
HTML5 для веб-дизайнеров
Спецификация HTML5 состоит из 900 страниц, достаточно трудных для понимания. HTML5 для веб-дизайнеров - 85 интересных страниц. Когда Вы закончите ее читать, Вы не будете задавать себе вопрос, что такое HTML5, как он работает, или что нужно делать, чтобы стать лучшим веб-разработчиком. Эта небольшая книга рассказывает про все в легкой и сжатой форме.
CSS3 для веб-разработчиков
Если Вы не знаете, с чего начинать обучение CSS3, купите книгу Дэна Седерхольма (Dan Cederholm) (соучредитель Dribbble). Она содержит информацию о расширенных функциях, селекторах, а также о CSS3-анимации.
Sass для веб-дизайнеров
Sass может помочь создать интерактивные элементы. Дэн Седерхольм (Dan Cederholm) выпустил книгу, рассказывающую о Sass — процессоре предварительной обработки CSS. Это поможет нам взглянуть на CSS с другой стороны.
Адаптивный веб-дизайн
Чем больше предприятий создают страницы в интернете, тем больше спрос на разработчиков, способных написать код на современных языках программирования. Автор книги по адаптивному веб-дизайну - Итан Маркотт (Ethan Marcotte).
Источник: http://codecondo.com/web-designers-want-become-web-developers/